From 5d1286092eac1545f819babbee27244504a212f0 Mon Sep 17 00:00:00 2001
From: Jakub <53441451+kuba6000@users.noreply.github.com>
Date: Tue, 23 Aug 2022 00:17:48 +0200
Subject: Add Config to override mob drops + some fixes (#8)
* Add overrides
* GTNHCoreMod custom drops integration
* Update buildscript
* Bump
* EEC blacklist
* NEI info
* Loops optimization
* Warn when 0% loots are detected
* Detect looting drops
* No
* Super rare drops
* Keep the same naming
* Crash
* Fix meta
* maybe
* Run at least twice
* Fix stupid TF Lich boss
* Comments
* Fix EEC blacklist
---
src/main/java/kubatech/CommonProxy.java | 1 +
src/main/java/kubatech/Config.java | 93 --------
.../java/kubatech/api/ConstructableItemStack.java | 97 ++++++++
src/main/java/kubatech/api/LoaderReference.java | 1 +
src/main/java/kubatech/api/mobhandler/MobDrop.java | 99 ++++++++
.../kubatech/api/network/LoadConfigPacket.java | 21 +-
src/main/java/kubatech/api/utils/GSONUtils.java | 33 ++-
src/main/java/kubatech/commands/CommandConfig.java | 2 +-
src/main/java/kubatech/config/Config.java | 94 ++++++++
src/main/java/kubatech/config/OverridesConfig.java | 212 +++++++++++++++++
.../java/kubatech/loaders/MobRecipeLoader.java | 258 ++++++++++++++++-----
src/main/java/kubatech/nei/Mob_Handler.java | 31 ++-
src/main/resources/assets/kubatech/lang/en_US.lang | 2 +
13 files changed, 776 insertions(+), 168 deletions(-)
delete mode 100644 src/main/java/kubatech/Config.java
create mode 100644 src/main/java/kubatech/api/ConstructableItemStack.java
create mode 100644 src/main/java/kubatech/api/mobhandler/MobDrop.java
create mode 100644 src/main/java/kubatech/config/Config.java
create mode 100644 src/main/java/kubatech/config/OverridesConfig.java
(limited to 'src')
diff --git a/src/main/java/kubatech/CommonProxy.java b/src/main/java/kubatech/CommonProxy.java
index 5f1ec40cad..db752f9fa0 100644
--- a/src/main/java/kubatech/CommonProxy.java
+++ b/src/main/java/kubatech/CommonProxy.java
@@ -24,6 +24,7 @@ import cpw.mods.fml.common.event.*;
import kubatech.commands.CommandConfig;
import kubatech.commands.CommandHandler;
import kubatech.commands.CommandHelp;
+import kubatech.config.Config;
import kubatech.loaders.RecipeLoader;
public class CommonProxy {
diff --git a/src/main/java/kubatech/Config.java b/src/main/java/kubatech/Config.java
deleted file mode 100644
index feb8f96dae..0000000000
--- a/src/main/java/kubatech/Config.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * KubaTech - Gregtech Addon
- * Copyright (C) 2022 kuba6000
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see .
- *
- */
-
-package kubatech;
-
-import java.io.File;
-import net.minecraftforge.common.config.Configuration;
-
-public class Config {
-
- private static class Categories {
- public static final String mobHandler = "MobHandler";
- }
-
- public static boolean mobHandlerEnabled = true;
- public static boolean includeEmptyMobs = true;
- public static String[] mobBlacklist;
- public static File configFile;
- public static File configDirectory;
-
- public static void init(File configFile) {
- configDirectory = new File(configFile, Tags.MODID);
- Config.configFile = new File(configDirectory, Tags.MODID + ".cfg");
- }
-
- public static File getConfigFile(String file) {
- return new File(configDirectory, file);
- }
-
- public static void synchronizeConfiguration() {
- Configuration configuration = new Configuration(configFile);
- configuration.load();
-
- mobHandlerEnabled = configuration
- .get(
- Categories.mobHandler,
- "Enabled",
- true,
- "Enable \"Mob Drops\" NEI page and Extreme Extermination Chamber")
- .getBoolean();
- includeEmptyMobs = configuration
- .get(Categories.mobHandler, "IncludeEmptyMobs", true, "Include mobs that have no drops in NEI")
- .getBoolean();
- mobBlacklist = configuration
- .get(
- Categories.mobHandler,
- "MobBlacklist",
- new String[] {
- "Giant",
- "Thaumcraft.TravelingTrunk",
- "chisel.snowman",
- "OpenBlocks.Luggage",
- "OpenBlocks.MiniMe",
- "SpecialMobs.SpecialCreeper",
- "SpecialMobs.SpecialZombie",
- "SpecialMobs.SpecialPigZombie",
- "SpecialMobs.SpecialSlime",
- "SpecialMobs.SpecialSkeleton",
- "SpecialMobs.SpecialEnderman",
- "SpecialMobs.SpecialCaveSpider",
- "SpecialMobs.SpecialGhast",
- "SpecialMobs.SpecialWitch",
- "SpecialMobs.SpecialSpider",
- "TwilightForest.HydraHead",
- "TwilightForest.RovingCube",
- "TwilightForest.Harbinger Cube",
- "TwilightForest.Adherent",
- "SpecialMobs.SpecialSilverfish",
- },
- "These mobs will be skipped when generating recipe map")
- .getStringList();
-
- if (configuration.hasChanged()) {
- configuration.save();
- }
- }
-}
diff --git a/src/main/java/kubatech/api/ConstructableItemStack.java b/src/main/java/kubatech/api/ConstructableItemStack.java
new file mode 100644
index 0000000000..668d21d803
--- /dev/null
+++ b/src/main/java/kubatech/api/ConstructableItemStack.java
@@ -0,0 +1,97 @@
+package kubatech.api;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.nio.charset.StandardCharsets;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.CompressedStreamTools;
+import net.minecraft.nbt.NBTSizeTracker;
+import net.minecraft.nbt.NBTTagCompound;
+
+public class ConstructableItemStack {
+ public final GameRegistry.UniqueIdentifier itemIdentifier;
+ public final int meta;
+ public final int size;
+ public final NBTTagCompound tagCompound;
+
+ private ConstructableItemStack(
+ GameRegistry.UniqueIdentifier itemIdentifier, int meta, int size, NBTTagCompound tagCompound) {
+ this.itemIdentifier = itemIdentifier;
+ this.meta = meta;
+ this.size = size;
+ this.tagCompound = tagCompound;
+ }
+
+ public ConstructableItemStack(ItemStack stack) {
+ itemIdentifier = GameRegistry.findUniqueIdentifierFor(stack.getItem());
+ meta = stack.getItemDamage();
+ size = stack.stackSize;
+ tagCompound = stack.stackTagCompound;
+ }
+
+ public ItemStack construct() {
+ if (itemIdentifier == null) return null;
+ Item it = GameRegistry.findItem(itemIdentifier.modId, itemIdentifier.name);
+ if (it == null) return null;
+ ItemStack stack = new ItemStack(it, size, meta);
+ stack.stackTagCompound = tagCompound;
+ return stack;
+ }
+
+ public boolean isSame(ConstructableItemStack stack, boolean ignoreSize) {
+ if (!stack.itemIdentifier.modId.equals(itemIdentifier.modId)) return false;
+ if (!stack.itemIdentifier.name.equals(itemIdentifier.name)) return false;
+ return ignoreSize || stack.size == size;
+ }
+
+ private static final ByteBuf BufHelper = Unpooled.buffer();
+
+ public void writeToByteBuf(ByteBuf byteBuf) {
+ BufHelper.clear();
+ byte[] bytes = itemIdentifier.modId.getBytes(StandardCharsets.UTF_8);
+ BufHelper.writeInt(bytes.length);
+ BufHelper.writeBytes(bytes);
+ bytes = itemIdentifier.name.getBytes(StandardCharsets.UTF_8);
+ BufHelper.writeInt(bytes.length);
+ BufHelper.writeBytes(bytes);
+ BufHelper.writeInt(meta);
+ BufHelper.writeInt(size);
+ BufHelper.writeBoolean(tagCompound != null);
+ if (tagCompound != null) {
+ try {
+ bytes = CompressedStreamTools.compress(tagCompound);
+ } catch (Exception ignored) {
+ bytes = new byte[0];
+ }
+ BufHelper.writeInt(bytes.length);
+ BufHelper.writeBytes(bytes);
+ }
+ byteBuf.writeInt(BufHelper.readableBytes());
+ byteBuf.writeBytes(BufHelper);
+ }
+
+ public static ConstructableItemStack readFromByteBuf(ByteBuf byteBuf) {
+ int size = byteBuf.readInt();
+ byte[] bytes = new byte[byteBuf.readInt()];
+ byteBuf.readBytes(bytes);
+ String modid = new String(bytes, StandardCharsets.UTF_8);
+ bytes = new byte[byteBuf.readInt()];
+ byteBuf.readBytes(bytes);
+ String name = new String(bytes, StandardCharsets.UTF_8);
+ int meta = byteBuf.readInt();
+ int stacksize = byteBuf.readInt();
+ NBTTagCompound nbtTagCompound = null;
+ if (byteBuf.readBoolean()) {
+ bytes = new byte[byteBuf.readInt()];
+ byteBuf.readBytes(bytes);
+ try {
+ nbtTagCompound = CompressedStreamTools.func_152457_a(bytes, new NBTSizeTracker(2097152L));
+ } catch (Exception ignored) {
+ }
+ }
+ return new ConstructableItemStack(
+ new GameRegistry.UniqueIdentifier(modid + ":" + name), meta, stacksize, nbtTagCompound);
+ }
+}
diff --git a/src/main/java/kubatech/api/LoaderReference.java b/src/main/java/kubatech/api/LoaderReference.java
index 418fe4a7ab..b41db59904 100644
--- a/src/main/java/kubatech/api/LoaderReference.java
+++ b/src/main/java/kubatech/api/LoaderReference.java
@@ -10,4 +10,5 @@ public class LoaderReference {
public static final boolean Thaumcraft = Loader.isModLoaded("Thaumcraft");
public static final boolean MineTweaker = Loader.isModLoaded("MineTweaker3");
public static final boolean Bartworks = Loader.isModLoaded("bartworks");
+ public static final boolean GTNHCoreMod = Loader.isModLoaded("dreamcraft");
}
diff --git a/src/main/java/kubatech/api/mobhandler/MobDrop.java b/src/main/java/kubatech/api/mobhandler/MobDrop.java
new file mode 100644
index 0000000000..76942b3148
--- /dev/null
+++ b/src/main/java/kubatech/api/mobhandler/MobDrop.java
@@ -0,0 +1,99 @@
+package kubatech.api.mobhandler;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.util.HashMap;
+import kubatech.api.ConstructableItemStack;
+import kubatech.api.utils.GSONUtils;
+import net.minecraft.item.ItemStack;
+
+public class MobDrop {
+ public enum DropType {
+ Normal,
+ Rare,
+ Additional,
+ Infernal;
+ private static final DropType[] values = values();
+
+ public static DropType get(int ordinal) {
+ return values[ordinal];
+ }
+ }
+
+ @GSONUtils.SkipGSON
+ public ItemStack stack;
+
+ public ConstructableItemStack reconstructableStack;
+ public DropType type;
+ public int chance;
+ public Integer enchantable;
+ public HashMap damages;
+ public boolean lootable = false;
+ public boolean playerOnly = false;
+
+ private MobDrop() {}
+
+ public MobDrop(
+ ItemStack stack,
+ DropType type,
+ int chance,
+ Integer enchantable,
+ HashMap damages,
+ boolean lootable,
+ boolean playerOnly) {
+ this.stack = stack;
+ this.reconstructableStack = new ConstructableItemStack(stack);
+ this.type = type;
+ this.chance = chance;
+ this.enchantable = enchantable;
+ this.damages = damages;
+ this.lootable = lootable;
+ this.playerOnly = playerOnly;
+ }
+
+ public void reconstructStack() {
+ this.stack = reconstructableStack.construct();
+ }
+
+ private static final ByteBuf BufHelper = Unpooled.buffer();
+
+ public void writeToByteBuf(ByteBuf byteBuf) {
+ BufHelper.clear();
+ reconstructableStack.writeToByteBuf(BufHelper);
+ BufHelper.writeInt(type.ordinal());
+ BufHelper.writeInt(chance);
+ BufHelper.writeBoolean(enchantable != null);
+ if (enchantable != null) BufHelper.writeInt(enchantable);
+ BufHelper.writeBoolean(damages != null);
+ if (damages != null) {
+ BufHelper.writeInt(damages.size());
+ damages.forEach((k, v) -> {
+ BufHelper.writeInt(k);
+ BufHelper.writeInt(v);
+ });
+ }
+ BufHelper.writeBoolean(lootable);
+ BufHelper.writeBoolean(playerOnly);
+ byteBuf.writeInt(BufHelper.readableBytes());
+ byteBuf.writeBytes(BufHelper);
+ }
+
+ public static MobDrop readFromByteBuf(ByteBuf byteBuf) {
+ MobDrop mobDrop = new MobDrop();
+ int size = byteBuf.readInt();
+ mobDrop.reconstructableStack = ConstructableItemStack.readFromByteBuf(byteBuf);
+ mobDrop.type = DropType.get(byteBuf.readInt());
+ mobDrop.chance = byteBuf.readInt();
+ if (byteBuf.readBoolean()) mobDrop.enchantable = byteBuf.readInt();
+ else mobDrop.enchantable = null;
+ if (byteBuf.readBoolean()) {
+ mobDrop.damages = new HashMap<>();
+ int damagessize = byteBuf.readInt();
+ for (int i = 0; i < damagessize; i++) mobDrop.damages.put(byteBuf.readInt(), byteBuf.readInt());
+ } else mobDrop.damages = null;
+ mobDrop.lootable = byteBuf.readBoolean();
+ mobDrop.playerOnly = byteBuf.readBoolean();
+ mobDrop.reconstructStack();
+ return mobDrop;
+ }
+}
diff --git a/src/main/java/kubatech/api/network/LoadConfigPacket.java b/src/main/java/kubatech/api/network/LoadConfigPacket.java
index f38293642e..2199eb2db9 100644
--- a/src/main/java/kubatech/api/network/LoadConfigPacket.java
+++ b/src/main/java/kubatech/api/network/LoadConfigPacket.java
@@ -24,8 +24,10 @@ import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
import java.util.HashSet;
-import kubatech.Config;
+import kubatech.config.Config;
+import kubatech.config.OverridesConfig;
import kubatech.kubatech;
import kubatech.loaders.MobRecipeLoader;
@@ -34,6 +36,7 @@ public class LoadConfigPacket implements IMessage {
public static final LoadConfigPacket instance = new LoadConfigPacket();
public final HashSet mobsToLoad = new HashSet<>();
+ public final HashMap mobsOverrides = new HashMap<>();
@Override
public void fromBytes(ByteBuf buf) {
@@ -46,6 +49,13 @@ public class LoadConfigPacket implements IMessage {
buf.readBytes(sbytes);
mobsToLoad.add(new String(sbytes, StandardCharsets.UTF_8));
}
+ int overridessize = buf.readInt();
+ for (int i = 0; i < overridessize; i++) {
+ byte[] sbytes = new byte[buf.readInt()];
+ buf.readBytes(sbytes);
+ mobsOverrides.put(
+ new String(sbytes, StandardCharsets.UTF_8), OverridesConfig.MobOverride.readFromByteBuf(buf));
+ }
}
}
@@ -60,6 +70,13 @@ public class LoadConfigPacket implements IMessage {
buf.writeInt(sbytes.length);
buf.writeBytes(sbytes);
});
+ buf.writeInt(mobsOverrides.size());
+ mobsOverrides.forEach((k, v) -> {
+ byte[] sbytes = k.getBytes(StandardCharsets.UTF_8);
+ buf.writeInt(sbytes.length);
+ buf.writeBytes(sbytes);
+ v.writeToByteBuf(buf);
+ });
}
}
@@ -67,7 +84,7 @@ public class LoadConfigPacket implements IMessage {
@Override
public IMessage onMessage(LoadConfigPacket message, MessageContext ctx) {
kubatech.info("Received Mob Handler config, parsing");
- MobRecipeLoader.processMobRecipeMap(message.mobsToLoad);
+ MobRecipeLoader.processMobRecipeMap(message.mobsToLoad, message.mobsOverrides);
return null;
}
}
diff --git a/src/main/java/kubatech/api/utils/GSONUtils.java b/src/main/java/kubatech/api/utils/GSONUtils.java
index 1c0e7ec3f4..90f777000c 100644
--- a/src/main/java/kubatech/api/utils/GSONUtils.java
+++ b/src/main/java/kubatech/api/utils/GSONUtils.java
@@ -1,12 +1,16 @@
package kubatech.api.utils;
import com.google.gson.*;
+import java.io.File;
import java.io.IOException;
+import java.io.Reader;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Type;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTSizeTracker;
import net.minecraft.nbt.NBTTagCompound;
@@ -66,5 +70,32 @@ public class GSONUtils {
.addSerializationExclusionStrategy(GSONStrategy)
.addDeserializationExclusionStrategy(GSONStrategy)
.registerTypeAdapter(NBTTagCompound.class, NBTTagCompoundDeserializer)
- .registerTypeAdapter(NBTTagCompound.class, NBTTagCompoundSerializer);
+ .registerTypeAdapter(NBTTagCompound.class, NBTTagCompoundSerializer)
+ .serializeNulls();
+ public static final GsonBuilder GSON_BUILDER_PRETTY = new GsonBuilder()
+ .addSerializationExclusionStrategy(GSONStrategy)
+ .addDeserializationExclusionStrategy(GSONStrategy)
+ .registerTypeAdapter(NBTTagCompound.class, NBTTagCompoundDeserializer)
+ .registerTypeAdapter(NBTTagCompound.class, NBTTagCompoundSerializer)
+ .serializeNulls()
+ .setPrettyPrinting();
+
+ public static T readFile(Gson gson, File file, Class tClass) {
+ if (!file.exists()) return null;
+ if (!file.isFile()) return null;
+ T t = null;
+ Reader reader = null;
+ try {
+ reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8);
+ t = gson.fromJson(reader, tClass);
+ } catch (Exception ignored) {
+ } finally {
+ if (reader != null)
+ try {
+ reader.close();
+ } catch (Exception ignored) {
+ }
+ }
+ return t;
+ }
}
diff --git a/src/main/java/kubatech/commands/CommandConfig.java b/src/main/java/kubatech/commands/CommandConfig.java
index a1c3659165..0c33c3dedf 100644
--- a/src/main/java/kubatech/commands/CommandConfig.java
+++ b/src/main/java/kubatech/commands/CommandConfig.java
@@ -21,8 +21,8 @@ package kubatech.commands;
import static kubatech.commands.CommandConfig.Translations.*;
-import kubatech.Config;
import kubatech.api.network.LoadConfigPacket;
+import kubatech.config.Config;
import kubatech.kubatech;
import kubatech.loaders.MobRecipeLoader;
import net.minecraft.command.CommandBase;
diff --git a/src/main/java/kubatech/config/Config.java b/src/main/java/kubatech/config/Config.java
new file mode 100644
index 0000000000..72044ae899
--- /dev/null
+++ b/src/main/java/kubatech/config/Config.java
@@ -0,0 +1,94 @@
+/*
+ * KubaTech - Gregtech Addon
+ * Copyright (C) 2022 kuba6000
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see .
+ *
+ */
+
+package kubatech.config;
+
+import java.io.File;
+import kubatech.Tags;
+import net.minecraftforge.common.config.Configuration;
+
+public class Config {
+
+ private static class Categories {
+ public static final String mobHandler = "MobHandler";
+ }
+
+ public static boolean mobHandlerEnabled = true;
+ public static boolean includeEmptyMobs = true;
+ public static String[] mobBlacklist;
+ public static File configFile;
+ public static File configDirectory;
+
+ public static void init(File configFile) {
+ configDirectory = new File(configFile, Tags.MODID);
+ Config.configFile = new File(configDirectory, Tags.MODID + ".cfg");
+ }
+
+ public static File getConfigFile(String file) {
+ return new File(configDirectory, file);
+ }
+
+ public static void synchronizeConfiguration() {
+ Configuration configuration = new Configuration(configFile);
+ configuration.load();
+
+ mobHandlerEnabled = configuration
+ .get(
+ Categories.mobHandler,
+ "Enabled",
+ true,
+ "Enable \"Mob Drops\" NEI page and Extreme Extermination Chamber")
+ .getBoolean();
+ includeEmptyMobs = configuration
+ .get(Categories.mobHandler, "IncludeEmptyMobs", true, "Include mobs that have no drops in NEI")
+ .getBoolean();
+ mobBlacklist = configuration
+ .get(
+ Categories.mobHandler,
+ "MobBlacklist",
+ new String[] {
+ "Giant",
+ "Thaumcraft.TravelingTrunk",
+ "chisel.snowman",
+ "OpenBlocks.Luggage",
+ "OpenBlocks.MiniMe",
+ "SpecialMobs.SpecialCreeper",
+ "SpecialMobs.SpecialZombie",
+ "SpecialMobs.SpecialPigZombie",
+ "SpecialMobs.SpecialSlime",
+ "SpecialMobs.SpecialSkeleton",
+ "SpecialMobs.SpecialEnderman",
+ "SpecialMobs.SpecialCaveSpider",
+ "SpecialMobs.SpecialGhast",
+ "SpecialMobs.SpecialWitch",
+ "SpecialMobs.SpecialSpider",
+ "TwilightForest.HydraHead",
+ "TwilightForest.RovingCube",
+ "TwilightForest.Harbinger Cube",
+ "TwilightForest.Adherent",
+ "SpecialMobs.SpecialSilverfish",
+ },
+ "These mobs will be skipped when generating recipe map")
+ .getStringList();
+
+ if (configuration.hasChanged()) {
+ configuration.save();
+ }
+ }
+}
diff --git a/src/main/java/kubatech/config/OverridesConfig.java b/src/main/java/kubatech/config/OverridesConfig.java
new file mode 100644
index 0000000000..9c1ca6170c
--- /dev/null
+++ b/src/main/java/kubatech/config/OverridesConfig.java
@@ -0,0 +1,212 @@
+package kubatech.config;
+
+import com.dreammaster.main.MainRegistry;
+import com.dreammaster.modcustomdrops.CustomDrops;
+import com.google.common.io.Files;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import cpw.mods.fml.common.registry.GameRegistry;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import java.io.File;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import kubatech.Tags;
+import kubatech.api.ConstructableItemStack;
+import kubatech.api.LoaderReference;
+import kubatech.api.mobhandler.MobDrop;
+import kubatech.api.utils.GSONUtils;
+import kubatech.api.utils.ReflectionHelper;
+import net.minecraft.entity.EntityList;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.JsonToNBT;
+import net.minecraft.nbt.NBTTagCompound;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+public class OverridesConfig {
+
+ private static final Logger LOG = LogManager.getLogger(Tags.MODID + "[Config-Overrides]");
+
+ public static class MobDropSimplified {
+ @GSONUtils.SkipGSON
+ ItemStack stack;
+
+ ConstructableItemStack reconstructableStack;
+ MobDrop.DropType type;
+
+ private MobDropSimplified() {}
+
+ public MobDropSimplified(ItemStack stack, MobDrop.DropType type) {
+ reconstructableStack = new ConstructableItemStack(stack);
+ this.type = type;
+ }
+
+ public void reconstructStack() {
+ stack = reconstructableStack.construct();
+ }
+
+ public boolean isMatching(MobDrop drop) {
+ return reconstructableStack.isSame(drop.reconstructableStack, true);
+ }
+
+ private static final ByteBuf BufHelper = Unpooled.buffer();
+
+ public void writeToByteBuf(ByteBuf byteBuf) {
+ BufHelper.clear();
+ reconstructableStack.writeToByteBuf(BufHelper);
+ BufHelper.writeInt(type.ordinal());
+ byteBuf.writeInt(BufHelper.readableBytes());
+ byteBuf.writeBytes(BufHelper);
+ }
+
+ public static MobDropSimplified readFromByteBuf(ByteBuf byteBuf) {
+ MobDropSimplified mobDropSimplified = new MobDropSimplified();
+ int size = byteBuf.readInt();
+ mobDropSimplified.reconstructableStack = ConstructableItemStack.readFromByteBuf(byteBuf);
+ mobDropSimplified.type = MobDrop.DropType.get(byteBuf.readInt());
+ mobDropSimplified.reconstructStack();
+ return mobDropSimplified;
+ }
+ }
+
+ public static class MobOverride {
+ public boolean removeAll = false;
+ public List additions = new ArrayList<>();
+ public List removals = new ArrayList<>();
+
+ private static final ByteBuf BufHelper = Unpooled.buffer();
+
+ public void writeToByteBuf(ByteBuf byteBuf) {
+ BufHelper.clear();
+ BufHelper.writeBoolean(removeAll);
+ BufHelper.writeInt(additions.size());
+ additions.forEach(drop -> drop.writeToByteBuf(BufHelper));
+ BufHelper.writeInt(removals.size());
+ removals.forEach(drop -> drop.writeToByteBuf(BufHelper));
+ byteBuf.writeInt(BufHelper.readableBytes());
+ byteBuf.writeBytes(BufHelper);
+ }
+
+ public static MobOverride readFromByteBuf(ByteBuf byteBuf) {
+ int size = byteBuf.readInt();
+ MobOverride mobOverride = new MobOverride();
+ mobOverride.removeAll = byteBuf.readBoolean();
+ int additionssize = byteBuf.readInt();
+ for (int i = 0; i < additionssize; i++) mobOverride.additions.add(MobDrop.readFromByteBuf(byteBuf));
+ int removalssize = byteBuf.readInt();
+ for (int i = 0; i < removalssize; i++) mobOverride.removals.add(MobDropSimplified.readFromByteBuf(byteBuf));
+ return mobOverride;
+ }
+ }
+
+ public static Map overrides = new HashMap<>();
+ private static File overrideFile = null;
+
+ private static final Gson gson = GSONUtils.GSON_BUILDER_PRETTY.create();
+
+ @SuppressWarnings("UnstableApiUsage")
+ public static void LoadConfig() {
+ LOG.info("Loading Config");
+ if (overrideFile == null) overrideFile = Config.getConfigFile("MobOverrides.cfg");
+ if (!overrideFile.exists()) writeExampleFile();
+ Reader reader = null;
+ try {
+ reader = Files.newReader(overrideFile, StandardCharsets.UTF_8);
+ overrides = gson.fromJson(reader, new TypeToken