diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/kubatech/CommonProxy.java | 2 | ||||
-rw-r--r-- | src/main/java/kubatech/Config.java | 8 | ||||
-rw-r--r-- | src/main/java/kubatech/api/utils/GSONUtils.java | 70 | ||||
-rw-r--r-- | src/main/java/kubatech/api/utils/ModUtils.java | 33 | ||||
-rw-r--r-- | src/main/java/kubatech/loaders/MobRecipeLoader.java | 88 |
5 files changed, 194 insertions, 7 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..53f0086e25 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,29 @@ 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( + StringBuilder::new, + (a, b) -> a.append(b.getModId()).append(b.getVersion()), + (a, b) -> a.append(", ").append(b)) + .toString(); + 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 21c18897f4..d3b02083e9 100644 --- a/src/main/java/kubatech/loaders/MobRecipeLoader.java +++ b/src/main/java/kubatech/loaders/MobRecipeLoader.java @@ -26,14 +26,20 @@ import static kubatech.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeE 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; @@ -41,8 +47,10 @@ import kubatech.Tags; import kubatech.api.LoaderReference; import kubatech.api.network.LoadConfigPacket; import kubatech.api.utils.InfernalHelper; +import kubatech.api.utils.GSONUtils; +import kubatech.api.utils.InfernalHelper; +import kubatech.api.utils.ModUtils; import kubatech.nei.Mob_Handler; -import kubatech.tileentity.gregtech.multiblock.GT_MetaTileEntity_ExtremeExterminationChamber; import minetweaker.MineTweakerAPI; import minetweaker.api.entity.IEntityDefinition; import minetweaker.api.item.IItemStack; @@ -264,7 +272,10 @@ public class MobRecipeLoader { Infernal } + @GSONUtils.SkipGSON public ItemStack stack; + + public NBTTagCompound reconstructableStack; public DropType type; public int chance; public Integer enchantable; @@ -273,11 +284,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 { @@ -544,7 +560,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; @@ -568,6 +589,48 @@ 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, drops.size() != 0 ? new MobRecipe(e, drops) : null, 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"); @@ -884,6 +947,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() { |