aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorkuba6000 <kuba.123123.6000@gmail.com>2022-08-18 00:12:14 +0200
committerkuba6000 <kuba.123123.6000@gmail.com>2022-08-18 00:12:14 +0200
commit01d91c0acd0e8b494578d63683088e6f1d67509f (patch)
tree6c861a4dd1adb10908bea3db416f7c589611c2cd /src
parentfdc6e8700d3404cf4aa2e073fd1201d8e8c5de60 (diff)
downloadGT5-Unofficial-01d91c0acd0e8b494578d63683088e6f1d67509f.tar.gz
GT5-Unofficial-01d91c0acd0e8b494578d63683088e6f1d67509f.tar.bz2
GT5-Unofficial-01d91c0acd0e8b494578d63683088e6f1d67509f.zip
Cache Mob Handler map
Diffstat (limited to 'src')
-rw-r--r--src/main/java/kubatech/CommonProxy.java2
-rw-r--r--src/main/java/kubatech/Config.java8
-rw-r--r--src/main/java/kubatech/api/utils/GSONUtils.java70
-rw-r--r--src/main/java/kubatech/api/utils/ModUtils.java29
-rw-r--r--src/main/java/kubatech/loaders/MobRecipeLoader.java84
5 files changed, 187 insertions, 6 deletions
diff --git a/src/main/java/kubatech/CommonProxy.java b/src/main/java/kubatech/CommonProxy.java
index e1285a7b84..5f1ec40cad 100644
--- a/src/main/java/kubatech/CommonProxy.java
+++ b/src/main/java/kubatech/CommonProxy.java
@@ -31,7 +31,7 @@ public class CommonProxy {
public void preInit(FMLPreInitializationEvent event) {
kubatech.info("Initializing ! Version: " + Tags.VERSION);
- Config.init(event.getSuggestedConfigurationFile());
+ Config.init(event.getModConfigurationDirectory());
Config.synchronizeConfiguration();
RecipeLoader.addRecipes();
FMLCommonHandler.instance().bus().register(new FMLEventHandler());
diff --git a/src/main/java/kubatech/Config.java b/src/main/java/kubatech/Config.java
index f258a9e088..feb8f96dae 100644
--- a/src/main/java/kubatech/Config.java
+++ b/src/main/java/kubatech/Config.java
@@ -32,9 +32,15 @@ public class Config {
public static boolean includeEmptyMobs = true;
public static String[] mobBlacklist;
public static File configFile;
+ public static File configDirectory;
public static void init(File configFile) {
- Config.configFile = 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() {
diff --git a/src/main/java/kubatech/api/utils/GSONUtils.java b/src/main/java/kubatech/api/utils/GSONUtils.java
new file mode 100644
index 0000000000..1c0e7ec3f4
--- /dev/null
+++ b/src/main/java/kubatech/api/utils/GSONUtils.java
@@ -0,0 +1,70 @@
+package kubatech.api.utils;
+
+import com.google.gson.*;
+import java.io.IOException;
+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 net.minecraft.nbt.CompressedStreamTools;
+import net.minecraft.nbt.NBTSizeTracker;
+import net.minecraft.nbt.NBTTagCompound;
+
+public class GSONUtils {
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface SkipGSON {}
+
+ private static final ExclusionStrategy GSONStrategy = new ExclusionStrategy() {
+ @Override
+ public boolean shouldSkipField(FieldAttributes f) {
+ return f.getAnnotation(SkipGSON.class) != null;
+ }
+
+ @Override
+ public boolean shouldSkipClass(Class<?> clazz) {
+ return false;
+ }
+ };
+
+ private static final JsonSerializer<NBTTagCompound> NBTTagCompoundSerializer =
+ new JsonSerializer<NBTTagCompound>() {
+
+ @Override
+ public JsonElement serialize(NBTTagCompound src, Type typeOfSrc, JsonSerializationContext context) {
+ try {
+ JsonArray array = new JsonArray();
+ for (byte b : CompressedStreamTools.compress(src)) {
+ array.add(new JsonPrimitive(b));
+ }
+ return array;
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+
+ private static final JsonDeserializer<NBTTagCompound> NBTTagCompoundDeserializer =
+ new JsonDeserializer<NBTTagCompound>() {
+ @Override
+ public NBTTagCompound deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ throws JsonParseException {
+ try {
+ if (!(json instanceof JsonArray)) return null;
+ byte[] bytes = new byte[((JsonArray) json).size()];
+ for (int i = 0; i < bytes.length; i++)
+ bytes[i] = ((JsonArray) json).get(i).getAsByte();
+ return CompressedStreamTools.func_152457_a(bytes, new NBTSizeTracker(2097152L));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+
+ public static final GsonBuilder GSON_BUILDER = new GsonBuilder()
+ .addSerializationExclusionStrategy(GSONStrategy)
+ .addDeserializationExclusionStrategy(GSONStrategy)
+ .registerTypeAdapter(NBTTagCompound.class, NBTTagCompoundDeserializer)
+ .registerTypeAdapter(NBTTagCompound.class, NBTTagCompoundSerializer);
+}
diff --git a/src/main/java/kubatech/api/utils/ModUtils.java b/src/main/java/kubatech/api/utils/ModUtils.java
index 0f598dcfa8..447796ddbf 100644
--- a/src/main/java/kubatech/api/utils/ModUtils.java
+++ b/src/main/java/kubatech/api/utils/ModUtils.java
@@ -20,9 +20,11 @@
package kubatech.api.utils;
import cpw.mods.fml.common.Loader;
-import java.util.AbstractMap;
-import java.util.HashMap;
-import java.util.Map;
+import cpw.mods.fml.common.ModContainer;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.*;
+import javax.xml.bind.DatatypeConverter;
import net.minecraft.launchwrapper.Launch;
public class ModUtils {
@@ -47,4 +49,25 @@ public class ModUtils {
.orElse(emptyEntry)
.getValue();
}
+
+ private static String modListVersion = null;
+
+ public static String getModListVersion() {
+ if (modListVersion != null) return modListVersion;
+ ArrayList<ModContainer> modlist = (ArrayList<ModContainer>)
+ ((ArrayList<ModContainer>) Loader.instance().getActiveModList()).clone();
+ String sortedList = modlist.stream()
+ .filter(m -> m.getMod() != null)
+ .sorted(Comparator.comparing(ModContainer::getModId))
+ .collect(String::new, (a, b) -> a += b.getModId() + b.getVersion(), (a, b) -> a += ", " + b);
+ try {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+ modListVersion = DatatypeConverter.printHexBinary(md.digest(sortedList.getBytes(StandardCharsets.UTF_8)))
+ .toUpperCase();
+ return modListVersion;
+ } catch (Exception e) {
+ modListVersion = sortedList;
+ return sortedList;
+ }
+ }
}
diff --git a/src/main/java/kubatech/loaders/MobRecipeLoader.java b/src/main/java/kubatech/loaders/MobRecipeLoader.java
index 3c087961d9..b7c5e9781d 100644
--- a/src/main/java/kubatech/loaders/MobRecipeLoader.java
+++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java
@@ -26,20 +26,28 @@ import static kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_E
import atomicstryker.infernalmobs.common.InfernalMobsCore;
import atomicstryker.infernalmobs.common.MobModifier;
import atomicstryker.infernalmobs.common.mods.api.ModifierLoader;
+import com.google.common.io.Files;
+import com.google.gson.Gson;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.util.GT_Utility;
import gregtech.common.GT_DummyWorld;
+import java.io.File;
+import java.io.Reader;
+import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
import kubatech.Config;
import kubatech.Tags;
import kubatech.api.LoaderReference;
+import kubatech.api.utils.GSONUtils;
import kubatech.api.utils.InfernalHelper;
+import kubatech.api.utils.ModUtils;
import kubatech.common.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber;
import kubatech.nei.Mob_Handler;
import kubatech.network.LoadConfigPacket;
@@ -259,7 +267,10 @@ public class MobRecipeLoader {
Infernal
}
+ @GSONUtils.SkipGSON
public ItemStack stack;
+
+ public NBTTagCompound reconstructableStack;
public DropType type;
public int chance;
public Integer enchantable;
@@ -268,11 +279,16 @@ public class MobRecipeLoader {
public MobDrop(
ItemStack stack, DropType type, int chance, Integer enchantable, HashMap<Integer, Integer> damages) {
this.stack = stack;
+ this.reconstructableStack = stack.writeToNBT(new NBTTagCompound());
this.type = type;
this.chance = chance;
this.enchantable = enchantable;
this.damages = damages;
}
+
+ public void reconstructStack() {
+ this.stack = ItemStack.loadItemStackFromNBT(this.reconstructableStack);
+ }
}
public static class fakeRand extends Random {
@@ -539,7 +555,12 @@ public class MobRecipeLoader {
public static final HashMap<String, GeneralMappedMob> GeneralMobList = new HashMap<>();
- @SuppressWarnings("unchecked")
+ private static class MobRecipeLoaderCacheStructure {
+ String version;
+ Map<String, ArrayList<MobDrop>> moblist;
+ }
+
+ @SuppressWarnings({"unchecked", "UnstableApiUsage"})
public static void generateMobRecipeMap() {
if (alreadyGenerated) return;
@@ -562,6 +583,46 @@ public class MobRecipeLoader {
fakeRand frand = new fakeRand();
f.rand = frand;
+ File cache = Config.getConfigFile("MobRecipeLoader.cache");
+ Gson gson = GSONUtils.GSON_BUILDER.create();
+
+ if (cache.exists()) {
+ LOG.info("Parsing Cached map");
+ Reader reader = null;
+ try {
+ reader = Files.newReader(cache, StandardCharsets.UTF_8);
+ MobRecipeLoaderCacheStructure s = gson.fromJson(reader, MobRecipeLoaderCacheStructure.class);
+ if (s.version.equals(ModUtils.getModListVersion())) {
+ for (Map.Entry<String, ArrayList<MobDrop>> entry : s.moblist.entrySet()) {
+ try {
+ EntityLiving e =
+ (EntityLiving) ((Class<?>) EntityList.stringToClassMapping.get(entry.getKey()))
+ .getConstructor(new Class[] {World.class})
+ .newInstance(new Object[] {f});
+ ArrayList<MobDrop> drops = entry.getValue();
+ drops.forEach(MobDrop::reconstructStack);
+ GeneralMobList.put(entry.getKey(), new GeneralMappedMob(e, new MobRecipe(e, drops), drops));
+ } catch (Exception ignored) {
+ }
+ }
+ LOG.info("Parsed cached map, skipping generation");
+ return;
+ } else {
+ LOG.info("Cached map version mismatch, generating a new one");
+ }
+ } catch (Exception ignored) {
+ LOG.info("There was an exception while parsing cached map, generating a new one");
+ } finally {
+ if (reader != null)
+ try {
+ reader.close();
+ } catch (Exception ignored) {
+ }
+ }
+ } else {
+ LOG.info("Cached map doesn't exist, generating a new one");
+ }
+
isInGenerationProcess = true;
LOG.info("Generating Recipe Map for Mob Handler and EEC");
@@ -878,6 +939,27 @@ public class MobRecipeLoader {
LOG.info("Recipe map generated ! It took " + time + "ms");
isInGenerationProcess = false;
+
+ LOG.info("Saving generated map to file");
+ MobRecipeLoaderCacheStructure s = new MobRecipeLoaderCacheStructure();
+ s.version = ModUtils.getModListVersion();
+ s.moblist = new HashMap<>();
+ GeneralMobList.forEach((k, v) -> s.moblist.put(k, v.drops));
+ Writer writer = null;
+ try {
+ writer = Files.newWriter(cache, StandardCharsets.UTF_8);
+ gson.toJson(s, writer);
+ writer.flush();
+ writer.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (writer != null)
+ try {
+ writer.close();
+ } catch (Exception ignored) {
+ }
+ }
}
public static void processMobRecipeMap() {