From 311ab89f93558233a40079f7cb16605b141b5346 Mon Sep 17 00:00:00 2001 From: Johann Bernhardt Date: Sun, 12 Dec 2021 19:38:06 +0100 Subject: Move sources and resources --- .../java/gtPlusPlus/preloader/asm/AsmConfig.java | 211 +++ .../preloader/asm/ClassesToTransform.java | 74 + .../preloader/asm/Preloader_DummyContainer.java | 95 + .../preloader/asm/Preloader_FMLLoadingPlugin.java | 84 + .../preloader/asm/Preloader_SetupClass.java | 23 + .../preloader/asm/helpers/MethodHelper_CC.java | 28 + .../preloader/asm/helpers/MethodHelper_GT.java | 25 + .../ClassTransformer_CC_GuiContainerManager.java | 121 ++ ...ClassTransformer_COFH_OreDictionaryArbiter.java | 185 ++ .../ClassTransformer_Forge_ChunkLoading.java | 684 +++++++ ...ansformer_Forge_EntityLivingBase_SetHealth.java | 130 ++ .../ClassTransformer_GC_EntityAutoRocket.java | 527 ++++++ .../ClassTransformer_GC_FluidUtil.java | 242 +++ .../ClassTransformer_GC_FuelLoader.java | 622 +++++++ .../ClassTransformer_GT_Achievements.java | 1896 ++++++++++++++++++++ .../ClassTransformer_GT_Achievements_CrashFix.java | 218 +++ .../ClassTransformer_GT_BaseMetaTileEntity.java | 158 ++ ...ransformer_GT_BlockMachines_MetaPipeEntity.java | 286 +++ .../ClassTransformer_GT_BlockMachines_NBT.java | 193 ++ .../ClassTransformer_GT_CharcoalPit.java | 184 ++ .../transformers/ClassTransformer_GT_Client.java | 410 +++++ .../ClassTransformer_GT_EnergyHatchPatch.java | 317 ++++ .../ClassTransformer_GT_ItemMachines_Tooltip.java | 139 ++ .../ClassTransformer_GT_MetaGenerated_Tool.java | 116 ++ .../ClassTransformer_GT_Packet_TileEntity.java | 319 ++++ .../transformers/ClassTransformer_GT_Utility.java | 283 +++ .../ClassTransformer_IC2_GetHarvestTool.java | 214 +++ .../transformers/ClassTransformer_IC2_Hazmat.java | 147 ++ .../ClassTransformer_LWJGL_Keyboard.java | 278 +++ ...assTransformer_Railcraft_FluidCartHandling.java | 117 ++ .../ClassTransformer_Railcraft_FluidHelper.java | 695 +++++++ .../ClassTransformer_Railcraft_InvTools.java | 235 +++ .../ClassTransformer_TC_ItemWispEssence.java | 278 +++ .../ClassTransformer_TT_ThaumicRestorer.java | 611 +++++++ .../transformers/ClassTransformer_TiConFluids.java | 164 ++ .../transformers/Preloader_ClassTransformer.java | 79 + .../transformers/Preloader_ClassTransformer2.java | 16 + .../Preloader_Transformer_Handler.java | 286 +++ 38 files changed, 10690 insertions(+) create mode 100644 src/main/java/gtPlusPlus/preloader/asm/AsmConfig.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/ClassesToTransform.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/Preloader_DummyContainer.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/Preloader_FMLLoadingPlugin.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/Preloader_SetupClass.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_CC.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_GT.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_CC_GuiContainerManager.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_COFH_OreDictionaryArbiter.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_ChunkLoading.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_EntityLivingBase_SetHealth.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_EntityAutoRocket.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FluidUtil.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FuelLoader.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements_CrashFix.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BaseMetaTileEntity.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_MetaPipeEntity.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_NBT.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Client.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_EnergyHatchPatch.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_ItemMachines_Tooltip.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_MetaGenerated_Tool.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Packet_TileEntity.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Utility.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_GetHarvestTool.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_Hazmat.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidCartHandling.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidHelper.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_InvTools.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ItemWispEssence.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TT_ThaumicRestorer.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TiConFluids.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer2.java create mode 100644 src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java (limited to 'src/main/java/gtPlusPlus/preloader/asm') diff --git a/src/main/java/gtPlusPlus/preloader/asm/AsmConfig.java b/src/main/java/gtPlusPlus/preloader/asm/AsmConfig.java new file mode 100644 index 0000000000..a5981b15d9 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/AsmConfig.java @@ -0,0 +1,211 @@ +package gtPlusPlus.preloader.asm; + +import cpw.mods.fml.common.FMLLog; +import gtPlusPlus.preloader.Preloader_Logger; + +import java.io.File; +import java.util.ArrayList; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; +import org.apache.logging.log4j.Level; + +public class AsmConfig { + + public static boolean loaded; + public static Configuration config; + + public static boolean enableOreDictPatch; + public static boolean enableTiConFluidLighting; + public static boolean enableGtTooltipFix; + public static boolean enableGtNbtFix; + public static boolean enableGtCharcoalPitFix; + public static boolean enableChunkDebugging; + public static boolean enableCofhPatch; + public static boolean enableGcFuelChanges; + public static boolean enableRcFlowFix; + public static int maxRailcraftTankProcessVolume; + public static int maxRailcraftFluidLoaderFlow; + public static int maxRailcraftFluidUnloaderFlow; + public static boolean enableRcItemDupeFix; + public static boolean enableTcAspectSafety; + public static boolean enabledLwjglKeybindingFix; + public static boolean enabledFixEntitySetHealth; + public static boolean enableThaumicTinkererRepairFix; + + public static boolean disableAllLogging; + public static boolean debugMode; + + public AsmConfig(File file) { + if (!loaded) { + config = new Configuration(file); + syncConfig(true); + } + + } + + public static void syncConfig(boolean load) { + ArrayList propOrder = new ArrayList(); + ArrayList propOrderDebug = new ArrayList(); + + try { + if (!config.isChild && load) { + config.load(); + } + + Property prop; + + //Debug + prop = config.get("debug", "disableAllLogging", false); + prop.comment = "Disables ALL logging from GT++."; + prop.setLanguageKey("gtpp.disableAllLogging").setRequiresMcRestart(false); + disableAllLogging = prop.getBoolean(false); + propOrderDebug.add(prop.getName()); + + prop = config.get("debug", "debugMode", false); + prop.comment = "Enables all sorts of debug logging. (Don't use unless told to, breaks other things.)"; + prop.setLanguageKey("gtpp.debugMode").setRequiresMcRestart(false); + debugMode = prop.getBoolean(false); + propOrderDebug.add(prop.getName()); + + prop = config.get("debug", "enabledFixEntitySetHealth", false); + prop.comment = "Enable/Disable entity setHealth() fix."; + prop.setLanguageKey("gtpp.enabledFixEntitySetHealth").setRequiresMcRestart(true); + enabledFixEntitySetHealth = prop.getBoolean(false); + propOrderDebug.add(prop.getName()); + + prop = config.get("debug", "enableChunkDebugging", false); + prop.comment = "Enable/Disable Chunk Debugging Features, Must Be enabled on Client and Server."; + prop.setLanguageKey("gtpp.enableChunkDebugging").setRequiresMcRestart(true); + enableChunkDebugging = prop.getBoolean(false); + propOrderDebug.add(prop.getName()); + + prop = config.get("debug", "enableGtNbtFix", true); + prop.comment = "Enable/Disable GT NBT Persistency Fix"; + prop.setLanguageKey("gtpp.enableGtNbtFix").setRequiresMcRestart(true); + enableGtNbtFix = prop.getBoolean(true); + propOrderDebug.add(prop.getName()); + + prop = config.get("debug", "enableCofhPatch", false); + prop.comment = "Enable/Disable COFH OreDictionaryArbiter Patch (Useful for Development)"; + prop.setLanguageKey("gtpp.enableCofhPatch").setRequiresMcRestart(true); + enableCofhPatch = prop.getBoolean(false); + propOrderDebug.add(prop.getName()); + + prop = config.get("debug", "enableOreDictPatch", false); + prop.comment = "Enable/Disable Forge OreDictionary Patch (Useful for Development)"; + prop.setLanguageKey("gtpp.enableOreDictPatch").setRequiresMcRestart(true); + enableOreDictPatch = prop.getBoolean(false); + propOrderDebug.add(prop.getName()); + + prop = config.get("debug", "enableThaumicTinkererRepairFix", false); + prop.comment = "Enable/Disable Patch for Thaumic Repairer"; + prop.setLanguageKey("gtpp.enableThaumicTinkererRepairFix").setRequiresMcRestart(true); + enableThaumicTinkererRepairFix = prop.getBoolean(false); + propOrderDebug.add(prop.getName()); + + + + + + + //General Features + prop = config.get("general", "enableTiConFluidLighting", true); + prop.comment = "Enable/Disable Brightness Visuals for Tinkers Fluids, only required on the Client."; + prop.setLanguageKey("gtpp.enableTiConFluidLighting").setRequiresMcRestart(true); + enableTiConFluidLighting = prop.getBoolean(true); + propOrder.add(prop.getName()); + + prop = config.get("general", "enabledLwjglKeybindingFix", true); + prop.comment = "Prevents the game crashing from having invalid keybinds. https://github.com/alkcorp/GTplusplus/issues/544"; + prop.setLanguageKey("gtpp.enabledLwjglKeybindingFix").setRequiresMcRestart(true); + enabledLwjglKeybindingFix = prop.getBoolean(true); + propOrder.add(prop.getName()); + + prop = config.get("general", "enableGtTooltipFix", true); + prop.comment = "Enable/Disable Custom GT Tooltips"; + prop.setLanguageKey("gtpp.enableGtTooltipFix").setRequiresMcRestart(true); + enableGtTooltipFix = prop.getBoolean(true); + propOrder.add(prop.getName()); + + + + prop = config.get("general", "enableGtCharcoalPitFix", true); + prop.comment = "Makes the Charcoal Pile Igniter work better."; + prop.setLanguageKey("gtpp.enableGtCharcoalPitFix").setRequiresMcRestart(true); + enableGtCharcoalPitFix = prop.getBoolean(true); + propOrder.add(prop.getName()); + + prop = config.get("general", "enableGcFuelChanges", true); + prop.comment = "Enable/Disable changes to Galacticraft Rocket Fuels."; + prop.setLanguageKey("gtpp.enableGcFuelChanges").setRequiresMcRestart(true); + //Disabled because Broken + //enableGcFuelChanges = prop.getBoolean(true); + enableGcFuelChanges = false; + propOrder.add(prop.getName()); + + + //Railcraft Tank fix + prop = config.get("general", "enableRcFlowFix", true); + prop.comment = "Allows Custom max IO rates on RC tanks"; + prop.setLanguageKey("gtpp.enableRcFlowFix").setRequiresMcRestart(true); + enableRcFlowFix = prop.getBoolean(true); + propOrder.add(prop.getName()); + + prop = config.get("general", "maxRailcraftTankProcessVolume", 4000); + prop.comment = "Max IO for RC fluid tanks (Not Carts). 'enableRcFlowFix' Must be enabled."; + prop.setLanguageKey("gtpp.maxRailcraftTankProcessVolume").setRequiresMcRestart(true); + maxRailcraftTankProcessVolume = prop.getInt(4000); + propOrder.add(prop.getName()); + + // Railcraft Loader Max flowrate + prop = config.get("general", "maxRailcraftFluidLoaderFlow", 20); + prop.comment = "Max Output rate for RC Fluid Loaders"; + prop.setLanguageKey("gtpp.maxRailcraftFluidLoaderFlow").setRequiresMcRestart(true); + maxRailcraftFluidLoaderFlow = prop.getInt(20); + propOrder.add(prop.getName()); + + // Railcraft Unloader Max flowrate + prop = config.get("general", "maxRailcraftFluidUnloaderFlow", 80); + prop.comment = "Max Output rate for RC Fluid Unloaders"; + prop.setLanguageKey("gtpp.maxRailcraftFluidUnloaderFlow").setRequiresMcRestart(true); + maxRailcraftFluidUnloaderFlow = prop.getInt(80); + propOrder.add(prop.getName()); + + //Railcraft Dupe Fix + prop = config.get("general", "enableRcItemDupeFix", true); + prop.comment = "Fixes possible negative itemstacks"; + prop.setLanguageKey("gtpp.enableRcItemDupeFix").setRequiresMcRestart(true); + enableRcItemDupeFix = prop.getBoolean(true); + propOrder.add(prop.getName()); + + + //TC Aspect Safety + prop = config.get("general", "enableTcAspectSafety", true); + prop.comment = "Fixes small oversights in Thaumcraft 4."; + prop.setLanguageKey("gtpp.enableTcAspectSafety").setRequiresMcRestart(true); + enableTcAspectSafety = prop.getBoolean(true); + propOrder.add(prop.getName()); + + + config.setCategoryPropertyOrder("general", propOrder); + config.setCategoryPropertyOrder("debug", propOrderDebug); + if (config.hasChanged()) { + config.save(); + } + + Preloader_Logger.INFO("Chunk Debugging - Enabled: "+enableChunkDebugging); + Preloader_Logger.INFO("Gt Nbt Fix - Enabled: "+enableGtNbtFix); + Preloader_Logger.INFO("TiCon Fluid Lighting - Enabled: "+enableTiConFluidLighting); + Preloader_Logger.INFO("Gt Tooltip Fix - Enabled: "+enableGtTooltipFix); + Preloader_Logger.INFO("COFH Patch - Enabled: "+enableCofhPatch); + Preloader_Logger.INFO("Gc Fuel Changes Patch - Enabled: "+enableGcFuelChanges); + Preloader_Logger.INFO("Railcraft Fluid Flow Patch - Enabled: "+enableRcFlowFix); + Preloader_Logger.INFO("Thaumcraft Aspect Safety Patch - Enabled: "+enableTcAspectSafety); + Preloader_Logger.INFO("Fix bad usage of EntityLivingBase.setHealth Patch - Enabled: "+enabledFixEntitySetHealth); + + } catch (Exception var3) { + FMLLog.log(Level.ERROR, var3, "GT++ ASM had a problem loading it's config", new Object[0]); + } + + } +} \ No newline at end of file diff --git a/src/main/java/gtPlusPlus/preloader/asm/ClassesToTransform.java b/src/main/java/gtPlusPlus/preloader/asm/ClassesToTransform.java new file mode 100644 index 0000000000..1dcbff439f --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/ClassesToTransform.java @@ -0,0 +1,74 @@ +package gtPlusPlus.preloader.asm; + +public class ClassesToTransform { + + + public static final String LWJGL_KEYBOARD = "org.lwjgl.input.Keyboard"; + + + public static final String MINECRAFT_GAMESETTINGS = "net.minecraft.client.settings.GameSettings"; + public static final String MINECRAFT_GAMESETTINGS_OBF = "bbj"; + + + public static final String FORGE_CHUNK_MANAGER = "net.minecraftforge.common.ForgeChunkManager"; + public static final String FORGE_ORE_DICTIONARY = "net.minecraftforge.oredict.OreDictionary"; + + + public static final String COFH_ORE_DICTIONARY_ARBITER = "cofh.core.util.oredict.OreDictionaryArbiter"; + + + public static final String TINKERS_FLUID_BLOCK = "tconstruct.smeltery.blocks.TConstructFluid"; + + + public static final String RAILCRAFT_FLUID_HELPER = "mods.railcraft.common.fluids.FluidHelper"; + public static final String RAILCRAFT_TILE_FLUID_LOADER = "mods.railcraft.common.blocks.machine.gamma.TileFluidLoader"; + public static final String RAILCRAFT_INVENTORY_TOOLS = "mods.railcraft.common.util.inventory.InvTools"; + + + public static final String GALACTICRAFT_FLUID_UTILS = "micdoodle8.mods.galacticraft.core.util.FluidUtil"; + public static final String GALACTICRAFT_TILE_ENTITY_FUEL_LOADER = "micdoodle8.mods.galacticraft.core.tile.TileEntityFuelLoader"; + public static final String GALACTICRAFT_ENTITY_AUTO_ROCKET = "micdoodle8.mods.galacticraft.api.prefab.entity.EntityAutoRocket"; + + + public static final String GT_UTILITY = "gregtech.api.util.GT_Utility"; + public static final String GT_ACHIEVEMENTS = "gregtech.loaders.misc.GT_Achievements"; + public static final String GT_CLIENT_PROXY = "gregtech.common.GT_Client"; + public static final String GT_PACKET_TILE_ENTITY = "gregtech.api.net.GT_Packet_TileEntity"; + public static final String GT_BASE_META_TILE_ENTITY = "gregtech.api.metatileentity.BaseMetaTileEntity"; + public static final String GT_MTE_CHARCOAL_PIT = "gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_Charcoal_Pit"; + public static final String GT_ITEM_MACHINES = "gregtech.common.blocks.GT_Item_Machines"; + public static final String GT_METAGENERATED_TOOL = "gregtech.api.items.GT_MetaGenerated_Tool"; + public static final String GT_BLOCK_MACHINES = "gregtech.common.blocks.GT_Block_Machines"; + public static final String GT_MTE_HATCH_ENERGY = "gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy"; + public static final String GT_METAPIPE_ITEM = "gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Item"; + public static final String GT_METAPIPE_FLUID = "gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Fluid"; + public static final String GT_METAPIPE_FRAME = "gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Frame"; + + + public static final String GTPP_MTE_HATCH_RTG = "gtPlusPlus.xmod.gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy_RTG"; + + + public static final String THAUMCRAFT_ITEM_WISP_ESSENCE = "thaumcraft.common.items.ItemWispEssence"; + public static final String THAUMCRAFT_CRAFTING_MANAGER = "thaumcraft.common.lib.crafting.ThaumcraftCraftingManager"; + public static final String THAUMCRAFT_TILE_ALCHEMY_FURNACE = "thaumcraft.common.tiles.TileAlchemyFurnace"; + public static final String THAUMICTINKERER_TILE_REPAIRER = "thaumic.tinkerer.common.block.tile.TileRepairer"; + + public static final String IC2_ITEM_ARMOUR_HAZMAT = "ic2.core.item.armor.ItemArmorHazmat"; + public static final String IC2_BLOCK_BASE_TILE_ENTITY = "ic2.core.block.BlockTileEntity"; + public static final String IC2_BLOCK_MACHINE1 = "ic2.core.block.machine.BlockMachine"; + public static final String IC2_BLOCK_MACHINE2 = "ic2.core.block.machine.BlockMachine2"; + public static final String IC2_BLOCK_MACHINE3 = "ic2.core.block.machine.BlockMachine3"; + public static final String IC2_BLOCK_KINETIC_GENERATOR = "ic2.core.block.kineticgenerator.block.BlockKineticGenerator"; + public static final String IC2_BLOCK_HEAT_GENERATOR = "ic2.core.block.heatgenerator.block.BlockHeatGenerator"; + public static final String IC2_BLOCK_GENERATOR = "ic2.core.block.generator.block.BlockGenerator"; + public static final String IC2_BLOCK_REACTOR_ACCESS_HATCH = "ic2.core.block.reactor.block.BlockReactorAccessHatch"; + public static final String IC2_BLOCK_REACTOR_CHAMBER = "ic2.core.block.reactor.block.BlockReactorChamber"; + public static final String IC2_BLOCK_REACTOR_FLUID_PORT = "ic2.core.block.reactor.block.BlockReactorFluidPort"; + public static final String IC2_BLOCK_REACTOR_REDSTONE_PORT = "ic2.core.block.reactor.block.BlockReactorRedstonePort"; + public static final String IC2_BLOCK_REACTOR_VESSEL = "ic2.core.block.reactor.block.BlockReactorVessel"; + public static final String IC2_BLOCK_PERSONAL = "ic2.core.block.personal.BlockPersonal.class"; + public static final String IC2_BLOCK_CHARGEPAD = "ic2.core.block.wiring.BlockChargepad.class"; + public static final String IC2_BLOCK_ELECTRIC = "ic2.core.block.wiring.BlockElectric.class"; + public static final String IC2_BLOCK_LUMINATOR = "ic2.core.block.wiring.BlockLuminator.class"; + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/Preloader_DummyContainer.java b/src/main/java/gtPlusPlus/preloader/asm/Preloader_DummyContainer.java new file mode 100644 index 0000000000..2a0082754a --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/Preloader_DummyContainer.java @@ -0,0 +1,95 @@ +package gtPlusPlus.preloader.asm; + +import java.io.File; +import java.util.Arrays; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import cpw.mods.fml.common.DummyModContainer; +import cpw.mods.fml.common.LoadController; +import cpw.mods.fml.common.ModMetadata; +import cpw.mods.fml.common.event.FMLConstructionEvent; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import gtPlusPlus.preloader.CORE_Preloader; +import gtPlusPlus.preloader.Preloader_Logger; +import net.minecraftforge.common.config.Configuration; + +public class Preloader_DummyContainer extends DummyModContainer { + + public Preloader_DummyContainer() { + super(new ModMetadata()); + ModMetadata meta = getMetadata(); + meta.modId = CORE_Preloader.MODID; + meta.name = CORE_Preloader.NAME; + meta.version = CORE_Preloader.VERSION; + meta.credits = "Roll Credits ..."; + meta.authorList = Arrays.asList("Alkalus"); + meta.description = ""; + meta.url = ""; + meta.updateUrl = ""; + meta.screenshots = new String[0]; + meta.logoFile = ""; + //meta.dependencies = (List) CORE_Preloader.DEPENDENCIES; + Preloader_Logger.INFO("Initializing DummyModContainer"); + + } + + @Override + public boolean registerBus(EventBus bus, LoadController controller) { + bus.register(this); + return true; + } + + @Subscribe + public void modConstruction(FMLConstructionEvent evt){ + Preloader_Logger.INFO("Constructing DummyModContainer"); + + } + + @Subscribe + public void preInit(FMLPreInitializationEvent event) { + Preloader_Logger.INFO("Loading " + CORE_Preloader.MODID + " V" + CORE_Preloader.VERSION); + // Handle GT++ Config + handleConfigFile(event); + } + + @Subscribe + public void init(FMLInitializationEvent evt) { + Preloader_Logger.INFO("Begin resource allocation for " + CORE_Preloader.MODID + " V" + CORE_Preloader.VERSION); + + } + + @Subscribe + public void postInit(FMLPostInitializationEvent evt) { + Preloader_Logger.INFO("Finished loading."); + } + + public static void handleConfigFile(final FMLPreInitializationEvent event) { + final Configuration config = new Configuration(new File(event.getModConfigurationDirectory(), "GTplusplus/GTplusplus.cfg")); + config.load(); + + //BGM Watchdog + CORE_Preloader.enableWatchdogBGM = config.getInt("enableWatchdogBGM", "features", 0, 0, Short.MAX_VALUE, "Set to a value greater than 0 to reduce the ticks taken to delay between BGM tracks. Acceptable Values are 1-32767, where 0 is disabled. Vanilla Uses 12,000 & 24,000. 200 is 10s."); + + // Circuits + CORE_Preloader.enableOldGTcircuits = config.getBoolean("enableOldGTcircuits", "gregtech", false, "Restores circuits and their recipes from Pre-5.09.28 times."); + } + + public static boolean getConfig(){ + final Configuration config = new Configuration( new File(gtPlusPlus.preloader.CORE_Preloader.MC_DIR, "config/GTplusplus/GTplusplus.cfg")); + if (config != null){ + config.load(); + // Circuits + CORE_Preloader.enableOldGTcircuits = config.getBoolean("enableOldGTcircuits", "gregtech", false, "Restores circuits and their recipes from Pre-5.09.28 times."); + CORE_Preloader.enableWatchdogBGM = config.getInt("enableWatchdogBGM", "features", 0, 0, Short.MAX_VALUE, "Set to a value greater than 0 to reduce the ticks taken to delay between BGM tracks. Acceptable Values are 1-32767, where 0 is disabled. Vanilla Uses 12,000 & 24,000. 200 is 10s."); + + Preloader_Logger.INFO("Loaded the configuration file."); + return true; + } + Preloader_Logger.INFO("Failed loading the configuration file."); + return false; + } +} \ No newline at end of file diff --git a/src/main/java/gtPlusPlus/preloader/asm/Preloader_FMLLoadingPlugin.java b/src/main/java/gtPlusPlus/preloader/asm/Preloader_FMLLoadingPlugin.java new file mode 100644 index 0000000000..22568e6de7 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/Preloader_FMLLoadingPlugin.java @@ -0,0 +1,84 @@ +package gtPlusPlus.preloader.asm; + +import java.io.File; +import java.text.NumberFormat; +import java.util.Locale; +import java.util.Map; + +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion; +import cpw.mods.fml.relauncher.IFMLLoadingPlugin.SortingIndex; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.preloader.CORE_Preloader; +import gtPlusPlus.preloader.Preloader_Logger; +import gtPlusPlus.preloader.asm.transformers.Preloader_Transformer_Handler; +import net.minecraft.launchwrapper.Launch; + +@SortingIndex(10097) +@MCVersion(value = "1.7.10") +@IFMLLoadingPlugin.TransformerExclusions("gtPlusPlus.preloader") +@IFMLLoadingPlugin.Name(CORE_Preloader.NAME) +public class Preloader_FMLLoadingPlugin implements IFMLLoadingPlugin { + + //-Dfml.coreMods.load=gtPlusPlus.preloader.asm.Preloader_FMLLoadingPlugin + + static { + Preloader_Logger.INFO("Initializing IFMLLoadingPlugin"); + } + + @Override + public String getAccessTransformerClass() { + return null; + } + + @Override + public String[] getASMTransformerClass() { + //This will return the name of the class + return new String[]{ + Preloader_Transformer_Handler.class.getName() + }; + } + + @Override + public String getModContainerClass() { + //This is the name of our dummy container + return Preloader_DummyContainer.class.getName(); + } + + @Override + public String getSetupClass() { + //return Preloader_SetupClass.class.getName(); + return null; + } + + @Override + public void injectData(Map data) { + boolean isDeObf = (boolean) data.get("runtimeDeobfuscationEnabled"); + File mcDir = (File) data.get("mcLocation"); + //LaunchClassLoader classLoader = (LaunchClassLoader) data.get("classLoader"); + File coremodLocation = (File) data.get("coremodLocation"); + String deobfuscationFileName = (String) data.get("deobfuscationFileName"); + if (mcDir != null && mcDir.exists()) { + CORE_Preloader.setMinecraftDirectory(mcDir); + Preloader_Logger.INFO("Set McDir via Preloader_SetupClass"); + } + Preloader_Logger.INFO("runtimeDeobfuscationEnabled: "+isDeObf); + Preloader_Logger.INFO("deobfuscationFileName: "+deobfuscationFileName); + if (coremodLocation != null && coremodLocation.exists()) { + Preloader_Logger.INFO("coremodLocation: "+coremodLocation.getPath()); + } + else { + Preloader_Logger.INFO("coremodLocation: null"); + Preloader_Logger.ERROR("Unable to determine CoreMod location"); + } + CORE_Preloader.DEV_ENVIRONMENT = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); + CORE_Preloader.DEBUG_MODE = AsmConfig.debugMode; + Preloader_Logger.INFO("Running on "+gtPlusPlus.preloader.CORE_Preloader.JAVA_VERSION+" | Development Environment: "+CORE_Preloader.DEV_ENVIRONMENT); + Locale aDefaultLocale = Locale.getDefault(); + NumberFormat aFormat = NumberFormat.getInstance(); + Locale aDisplayLocale = (Locale) ReflectionUtils.getFieldValue(ReflectionUtils.getField(Locale.class, "defaultDisplayLocale")); + Locale aFormatLocale = (Locale) ReflectionUtils.getFieldValue(ReflectionUtils.getField(Locale.class, "defaultFormatLocale")); + Preloader_Logger.INFO("Locale: "+aDefaultLocale+" | Test: "+aFormat.format(1000000000)+" | Display: "+aDisplayLocale+" | Format: "+aFormatLocale); + } + +} \ No newline at end of file diff --git a/src/main/java/gtPlusPlus/preloader/asm/Preloader_SetupClass.java b/src/main/java/gtPlusPlus/preloader/asm/Preloader_SetupClass.java new file mode 100644 index 0000000000..a6d2b6c863 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/Preloader_SetupClass.java @@ -0,0 +1,23 @@ +package gtPlusPlus.preloader.asm; + +import java.io.File; +import java.util.Map; + +import cpw.mods.fml.relauncher.IFMLCallHook; +import gtPlusPlus.preloader.CORE_Preloader; +import gtPlusPlus.preloader.Preloader_Logger; + +public class Preloader_SetupClass implements IFMLCallHook { + + @Override + public Void call() throws Exception { + Preloader_Logger.INFO("Executing IFMLCallHook"); + return null; + } + + @Override + public void injectData(Map data) { + + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_CC.java b/src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_CC.java new file mode 100644 index 0000000000..664ffe7b2d --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_CC.java @@ -0,0 +1,28 @@ +package gtPlusPlus.preloader.asm.helpers; + +import codechicken.nei.guihook.GuiContainerManager; +import codechicken.nei.guihook.IContainerInputHandler; +import net.minecraft.client.gui.inventory.GuiContainer; + +public class MethodHelper_CC { + + + public void mouseUp2(int mousex, int mousey, int button) { + MethodHelper_CC.mouseUp(mousex, mousey, button); + } + + public static void mouseUp(int mousex, int mousey, int button) { + GuiContainerManager aManager = codechicken.nei.guihook.GuiContainerManager.getManager(); + if (aManager != null) { + GuiContainer aWindow = aManager.window; + for (IContainerInputHandler inputhander : GuiContainerManager.inputHandlers) { + //Preloader_Logger.INFO("Found Handler: "+aWindow.getClass().getName() + " | "+inputhander.getClass().getName()); + } + for (IContainerInputHandler inputhander : GuiContainerManager.inputHandlers) { + //Preloader_Logger.INFO("Trying to handle events for "+aWindow.getClass().getName() + " | "+inputhander.getClass().getName()); + inputhander.onMouseUp(aWindow, mousex, mousey, button); + } + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_GT.java b/src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_GT.java new file mode 100644 index 0000000000..8120df81fa --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/helpers/MethodHelper_GT.java @@ -0,0 +1,25 @@ +package gtPlusPlus.preloader.asm.helpers; + +import java.util.List; + +import gregtech.api.enums.Materials; +import gregtech.api.items.GT_MetaGenerated_Tool; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +public class MethodHelper_GT { + + public static final void getSubItems(GT_MetaGenerated_Tool aTool, Item var1, CreativeTabs aCreativeTab, List aList) { + for (int i = 0; i < 32766; i += 2) { + if (aTool.getToolStats(new ItemStack(aTool, 1, i)) != null) { + ItemStack tStack = new ItemStack(aTool, 1, i); + aTool.isItemStackUsable(tStack); + aList.add(tStack); + aList.add(aTool.getToolWithStats(i,1,Materials.TungstenSteel,Materials.TungstenSteel,null)); + aList.add(aTool.getToolWithStats(i,1,Materials.Neutronium,Materials.Neutronium,null)); + } + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_CC_GuiContainerManager.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_CC_GuiContainerManager.java new file mode 100644 index 0000000000..8791d401c8 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_CC_GuiContainerManager.java @@ -0,0 +1,121 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.*; + +import gtPlusPlus.preloader.Preloader_Logger; + +public class ClassTransformer_CC_GuiContainerManager { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public ClassTransformer_CC_GuiContainerManager(byte[] basicClass) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + localClassVisitor aTempMethodRemover = new localClassVisitor(aTempWriter); + aTempReader.accept(aTempMethodRemover, 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } else { + isValid = false; + } + + Preloader_Logger.LOG("CodeChicken GuiContainerManager Patch", Level.INFO, "Valid patch? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null) { + Preloader_Logger.LOG("CodeChicken GuiContainerManager Patch", Level.INFO, "Attempting Method Injection."); + injectMethod("mouseUp"); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(String aMethodName) { + MethodVisitor mv; + boolean didInject = false; + String aClassName = "codechicken/nei/guihook/GuiContainerManager"; + ClassWriter cw = getWriter(); + if (aMethodName.equals("mouseUp")) { + Preloader_Logger.LOG("CodeChicken GuiContainerManager Patch", Level.INFO, "Injecting " + aMethodName + ", static replacement call to "+aClassName+"."); + mv = cw.visitMethod(ACC_PUBLIC, "mouseUp", "(III)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(12, l0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/helpers/MethodHelper_CC", "mouseUp", "(III)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(13, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "L+aClassName+;", null, l0, l2, 0); + mv.visitLocalVariable("mousex", "I", null, l0, l2, 1); + mv.visitLocalVariable("mousey", "I", null, l0, l2, 2); + mv.visitLocalVariable("button", "I", null, l0, l2, 3); + mv.visitMaxs(3, 4); + mv.visitEnd(); + didInject = true; + } + + Preloader_Logger.LOG("CodeChicken GuiContainerManager Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public final class localClassVisitor extends ClassVisitor { + + boolean obfuscated = false; + + public localClassVisitor(ClassVisitor cv) { + super(ASM5, cv); + } + + public boolean getObfuscatedRemoval() { + return obfuscated; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + + if (name.equals("mouseUp")) { + methodVisitor = null; + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + + if (methodVisitor == null) { + Preloader_Logger.LOG("CodeChicken GuiContainerManager Patch", Level.INFO, "Found method " + name + ", removing."); + Preloader_Logger.LOG("CodeChicken GuiContainerManager Patch", Level.INFO, "Descriptor: "+desc); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_COFH_OreDictionaryArbiter.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_COFH_OreDictionaryArbiter.java new file mode 100644 index 0000000000..6f08dc4ff5 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_COFH_OreDictionaryArbiter.java @@ -0,0 +1,185 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ACC_STATIC; +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ASM5; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.objectweb.asm.Opcodes.RETURN; + +import java.util.ArrayList; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +import com.google.common.base.Strings; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; + +import cofh.core.util.oredict.OreDictionaryArbiter; +import cofh.lib.util.ItemWrapper; +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gnu.trove.map.TMap; +import gnu.trove.map.hash.THashMap; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.preloader.DevHelper; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + +public class ClassTransformer_COFH_OreDictionaryArbiter { + + //The qualified name of the class we plan to transform. + private static final String className = "cofh.core.util.oredict.OreDictionaryArbiter"; + //cofh/core/util/oredict/OreDictionaryArbiter + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public ClassTransformer_COFH_OreDictionaryArbiter(byte[] basicClass) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitor(aTempWriter), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null) { + injectMethod("registerOreDictionaryEntry"); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public void injectMethod(String aMethodName) { + + boolean isObfuscated; + try { + isObfuscated = Class.forName("net.minecraft.item.ItemStack") != null ? false : true; + } catch (ClassNotFoundException e) { + isObfuscated = true; + } + String aItemStack = isObfuscated ? DevHelper.getObfuscated("net/minecraft/item/ItemStack") : "net/minecraft/item/ItemStack"; + MethodVisitor mv; + if (aMethodName.equals("registerOreDictionaryEntry")) { + FMLRelaunchLog.log("[GT++ ASM] COFH OreDictionaryArbiter Patch", Level.INFO, "Injecting "+aMethodName+" into "+className+". ItemStack: "+aItemStack); + mv = getWriter().visitMethod(ACC_PUBLIC + ACC_STATIC, "registerOreDictionaryEntry", "(L"+aItemStack+";Ljava/lang/String;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(61, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_COFH_OreDictionaryArbiter$FixCOFH", "registerOreDictionaryEntry", "(L"+aItemStack+";Ljava/lang/String;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(62, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("arg", "L"+aItemStack+";", null, l0, l2, 0); + mv.visitLocalVariable("arg0", "Ljava/lang/String;", null, l0, l2, 1); + mv.visitMaxs(2, 2); + mv.visitEnd(); + } + FMLRelaunchLog.log("[GT++ ASM] COFH OreDictionaryArbiter Patch", Level.INFO, "Method injection complete."); + + } + + public static final class localClassVisitor extends ClassVisitor { + + public localClassVisitor(ClassVisitor cv) { + super(ASM5, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (name.equals("registerOreDictionaryEntry")) { + FMLRelaunchLog.log("[GT++ ASM] COFH OreDictionaryArbiter Patch", Level.INFO, "Removing method "+name); + return null; + } + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + return methodVisitor; + } + } + + + + + @SuppressWarnings("unchecked") + public static class FixCOFH{ + + private static BiMap oreIDs; + private static TMap> oreStacks; + private static TMap> stackIDs; + private static TMap> stackNames; + + static { + try { + oreIDs = (BiMap) ReflectionUtils.getField(OreDictionaryArbiter.class, "oreIDs").get(null); + oreStacks = (TMap>) ReflectionUtils.getField(OreDictionaryArbiter.class, "oreStacks").get(null); + stackIDs = (TMap>) ReflectionUtils.getField(OreDictionaryArbiter.class, "stackIDs").get(null); + stackNames = (TMap>) ReflectionUtils.getField(OreDictionaryArbiter.class, "stackNames").get(null); + } + catch (Throwable t) { + oreIDs = HashBiMap.create(); + oreStacks = new THashMap>(); + stackIDs = new THashMap>(); + stackNames = new THashMap>(); + } + } + + public static void registerOreDictionaryEntry(ItemStack arg, String arg0) { + try { + if (arg == null) { + return; + } + if (arg.getItem() != null && !Strings.isNullOrEmpty(arg0)) { + int arg1 = OreDictionary.getOreID(arg0); + oreIDs.put(arg0, Integer.valueOf(arg1)); + if (!oreStacks.containsKey(Integer.valueOf(arg1))) { + oreStacks.put(Integer.valueOf(arg1), new ArrayList()); + } + ((ArrayList) oreStacks.get(Integer.valueOf(arg1))).add(arg); + ItemWrapper arg2 = ItemWrapper.fromItemStack(arg); + if (!stackIDs.containsKey(arg2)) { + stackIDs.put(arg2, new ArrayList()); + stackNames.put(arg2, new ArrayList()); + } + ((ArrayList) stackIDs.get(arg2)).add(Integer.valueOf(arg1)); + ((ArrayList) stackNames.get(arg2)).add(arg0); + } + } + catch (Throwable t) { + return; + } + } + } + + + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_ChunkLoading.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_ChunkLoading.java new file mode 100644 index 0000000000..19648ae60c --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_ChunkLoading.java @@ -0,0 +1,684 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import java.io.IOException; +import org.apache.logging.log4j.Level; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gtPlusPlus.preloader.DevHelper; + +public class ClassTransformer_Forge_ChunkLoading { + + //The qualified name of the class we plan to transform. + private static final String className = "net.minecraftforge.common.ForgeChunkManager"; + //net/minecraftforge/common/ForgeChunkManager + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + String aChunkCoordIntPair; + String aItemStack; + String aWorld; + String aEntity; + + private static boolean doesMethodAlreadyExist = false; + + public ClassTransformer_Forge_ChunkLoading(byte[] basicClass, boolean obfuscated) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitor(aTempWriter), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null && !doesMethodAlreadyExist) { + + aChunkCoordIntPair = obfuscated ? DevHelper.getObfuscated("net/minecraft/world/ChunkCoordIntPair") : "net/minecraft/world/ChunkCoordIntPair"; + aWorld = obfuscated ? DevHelper.getObfuscated("net/minecraft/world/World") : "net/minecraft/world/World"; + aEntity = obfuscated ? DevHelper.getObfuscated("net/minecraft/entity/Entity") : "net/minecraft/entity/Entity"; + + injectMethod("forceChunk"); + injectMethod("unforceChunk"); + injectMethod("requestTicket"); + injectMethod("releaseTicket"); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public void injectMethod(String aMethodName) { + MethodVisitor mv; + FMLRelaunchLog.log("[GT++ ASM] Chunkloading Patch", Level.INFO, "Injecting "+aMethodName+" into "+className+"."); + if (aMethodName.equals("forceChunk")) { + + mv = getWriter().visitMethod(ACC_PUBLIC + ACC_STATIC, "forceChunk", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aChunkCoordIntPair+";)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(730, l0); + mv.visitVarInsn(ALOAD, 0); + Label l1 = new Label(); + mv.visitJumpInsn(IFNULL, l1); + mv.visitVarInsn(ALOAD, 1); + Label l2 = new Label(); + mv.visitJumpInsn(IFNONNULL, l2); + mv.visitLabel(l1); + mv.visitLineNumber(732, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + mv.visitLabel(l2); + mv.visitLineNumber(734, l2); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$500", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Lnet/minecraftforge/common/ForgeChunkManager$Type;", false); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager$Type", "ENTITY", "Lnet/minecraftforge/common/ForgeChunkManager$Type;"); + Label l3 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l3); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$600", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)L"+aEntity+";", false); + mv.visitJumpInsn(IFNONNULL, l3); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(736, l4); + mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); + mv.visitInsn(DUP); + mv.visitLdcInsn("Attempted to use an entity ticket to force a chunk, without an entity"); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "", "(Ljava/lang/String;)V", false); + mv.visitInsn(ATHROW); + mv.visitLabel(l3); + mv.visitLineNumber(738, l3); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/common/ForgeChunkManager$Ticket", "isPlayerTicket", "()Z", false); + Label l5 = new Label(); + mv.visitJumpInsn(IFEQ, l5); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "playerTickets", "Lcom/google/common/collect/SetMultimap;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEINTERFACE, "com/google/common/collect/SetMultimap", "containsValue", "(Ljava/lang/Object;)Z", true); + Label l6 = new Label(); + mv.visitJumpInsn(IFNE, l6); + Label l7 = new Label(); + mv.visitJumpInsn(GOTO, l7); + mv.visitLabel(l5); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "tickets", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/common/ForgeChunkManager$Ticket", "world", "L"+aWorld+";"); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, "com/google/common/collect/Multimap"); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$200", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Ljava/lang/String;", false); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEINTERFACE, "com/google/common/collect/Multimap", "containsEntry", "(Ljava/lang/Object;Ljava/lang/Object;)Z", true); + mv.visitJumpInsn(IFNE, l6); + mv.visitLabel(l7); + mv.visitLineNumber(740, l7); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitLdcInsn("The mod %s attempted to force load a chunk with an invalid ticket. This is not permitted."); + mv.visitInsn(ICONST_1); + mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$200", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Ljava/lang/String;", false); + mv.visitInsn(AASTORE); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/FMLLog", "severe", "(Ljava/lang/String;[Ljava/lang/Object;)V", false); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(741, l8); + mv.visitInsn(RETURN); + mv.visitLabel(l6); + mv.visitLineNumber(743, l6); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$700", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Ljava/util/LinkedHashSet;", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/LinkedHashSet", "add", "(Ljava/lang/Object;)Z", false); + mv.visitInsn(POP); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(744, l9); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/ChunkDebugger", "storeLoadChunkToCache", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aChunkCoordIntPair+";)V", false); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(745, l10); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/MinecraftForge", "EVENT_BUS", "Lcpw/mods/fml/common/eventhandler/EventBus;"); + mv.visitTypeInsn(NEW, "net/minecraftforge/common/ForgeChunkManager$ForceChunkEvent"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/common/ForgeChunkManager$ForceChunkEvent", "", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aChunkCoordIntPair+";)V", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "cpw/mods/fml/common/eventhandler/EventBus", "post", "(Lcpw/mods/fml/common/eventhandler/Event;)Z", false); + mv.visitInsn(POP); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(747, l11); + mv.visitMethodInsn(INVOKESTATIC, "com/google/common/collect/ImmutableSetMultimap", "builder", "()Lcom/google/common/collect/ImmutableSetMultimap$Builder;", false); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "forcedChunks", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/common/ForgeChunkManager$Ticket", "world", "L"+aWorld+";"); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, "com/google/common/collect/Multimap"); + mv.visitMethodInsn(INVOKEVIRTUAL, "com/google/common/collect/ImmutableSetMultimap$Builder", "putAll", "(Lcom/google/common/collect/Multimap;)Lcom/google/common/collect/ImmutableSetMultimap$Builder;", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "com/google/common/collect/ImmutableSetMultimap$Builder", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableSetMultimap$Builder;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "com/google/common/collect/ImmutableSetMultimap$Builder", "build", "()Lcom/google/common/collect/ImmutableSetMultimap;", false); + mv.visitVarInsn(ASTORE, 2); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(748, l12); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "forcedChunks", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/common/ForgeChunkManager$Ticket", "world", "L"+aWorld+";"); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true); + mv.visitInsn(POP); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(749, l13); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$800", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)I", false); + Label l14 = new Label(); + mv.visitJumpInsn(IFLE, l14); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$700", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Ljava/util/LinkedHashSet;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/LinkedHashSet", "size", "()I", false); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$800", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)I", false); + mv.visitJumpInsn(IF_ICMPLE, l14); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(751, l15); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$700", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Ljava/util/LinkedHashSet;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/LinkedHashSet", "iterator", "()Ljava/util/Iterator;", false); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, ""+aChunkCoordIntPair+""); + mv.visitVarInsn(ASTORE, 3); + Label l16 = new Label(); + mv.visitLabel(l16); + mv.visitLineNumber(752, l16); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager", "unforceChunk", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aChunkCoordIntPair+";)V", false); + mv.visitLabel(l14); + mv.visitLineNumber(754, l14); + mv.visitFrame(F_APPEND,1, new Object[] {"com/google/common/collect/ImmutableSetMultimap"}, 0, null); + mv.visitInsn(RETURN); + Label l17 = new Label(); + mv.visitLabel(l17); + mv.visitLocalVariable("ticket", "Lnet/minecraftforge/common/ForgeChunkManager$Ticket;", null, l0, l17, 0); + mv.visitLocalVariable("chunk", "L"+aChunkCoordIntPair+";", null, l0, l17, 1); + mv.visitLocalVariable("newMap", "Lcom/google/common/collect/ImmutableSetMultimap;", "Lcom/google/common/collect/ImmutableSetMultimap;", l12, l17, 2); + mv.visitLocalVariable("removed", "L"+aChunkCoordIntPair+";", null, l16, l14, 3); + mv.visitMaxs(5, 4); + mv.visitEnd(); + + } + else if (aMethodName.equals("unforceChunk")) { + + mv = getWriter().visitMethod(ACC_PUBLIC + ACC_STATIC, "unforceChunk", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aChunkCoordIntPair+";)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(781, l0); + mv.visitVarInsn(ALOAD, 0); + Label l1 = new Label(); + mv.visitJumpInsn(IFNULL, l1); + mv.visitVarInsn(ALOAD, 1); + Label l2 = new Label(); + mv.visitJumpInsn(IFNONNULL, l2); + mv.visitLabel(l1); + mv.visitLineNumber(783, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + mv.visitLabel(l2); + mv.visitLineNumber(785, l2); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$700", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Ljava/util/LinkedHashSet;", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/LinkedHashSet", "remove", "(Ljava/lang/Object;)Z", false); + mv.visitInsn(POP); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(786, l3); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/ChunkDebugger", "removeLoadedChunkFromCache", "(L"+aChunkCoordIntPair+";)V", false); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(787, l4); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/MinecraftForge", "EVENT_BUS", "Lcpw/mods/fml/common/eventhandler/EventBus;"); + mv.visitTypeInsn(NEW, "net/minecraftforge/common/ForgeChunkManager$UnforceChunkEvent"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/common/ForgeChunkManager$UnforceChunkEvent", "", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aChunkCoordIntPair+";)V", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "cpw/mods/fml/common/eventhandler/EventBus", "post", "(Lcpw/mods/fml/common/eventhandler/Event;)Z", false); + mv.visitInsn(POP); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(788, l5); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "forcedChunks", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/common/ForgeChunkManager$Ticket", "world", "L"+aWorld+";"); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, "com/google/common/collect/Multimap"); + mv.visitMethodInsn(INVOKESTATIC, "com/google/common/collect/LinkedHashMultimap", "create", "(Lcom/google/common/collect/Multimap;)Lcom/google/common/collect/LinkedHashMultimap;", false); + mv.visitVarInsn(ASTORE, 2); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(789, l6); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "com/google/common/collect/LinkedHashMultimap", "remove", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false); + mv.visitInsn(POP); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(790, l7); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKESTATIC, "com/google/common/collect/ImmutableSetMultimap", "copyOf", "(Lcom/google/common/collect/Multimap;)Lcom/google/common/collect/ImmutableSetMultimap;", false); + mv.visitVarInsn(ASTORE, 3); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(791, l8); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "forcedChunks", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/common/ForgeChunkManager$Ticket", "world", "L"+aWorld+";"); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", true); + mv.visitInsn(POP); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(792, l9); + mv.visitInsn(RETURN); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLocalVariable("ticket", "Lnet/minecraftforge/common/ForgeChunkManager$Ticket;", null, l0, l10, 0); + mv.visitLocalVariable("chunk", "L"+aChunkCoordIntPair+";", null, l0, l10, 1); + mv.visitLocalVariable("copy", "Lcom/google/common/collect/LinkedHashMultimap;", "Lcom/google/common/collect/LinkedHashMultimap;", l6, l10, 2); + mv.visitLocalVariable("newMap", "Lcom/google/common/collect/ImmutableSetMultimap;", "Lcom/google/common/collect/ImmutableSetMultimap;", l8, l10, 3); + mv.visitMaxs(5, 4); + mv.visitEnd(); + + } + + else if (aMethodName.equals("requestTicket")) { + + mv = getWriter().visitMethod(ACC_PUBLIC + ACC_STATIC, "requestTicket", "(Ljava/lang/Object;L"+aWorld+";Lnet/minecraftforge/common/ForgeChunkManager$Type;)Lnet/minecraftforge/common/ForgeChunkManager$Ticket;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(656, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager", "getContainer", "(Ljava/lang/Object;)Lcpw/mods/fml/common/ModContainer;", false); + mv.visitVarInsn(ASTORE, 3); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(657, l1); + mv.visitVarInsn(ALOAD, 3); + Label l2 = new Label(); + mv.visitJumpInsn(IFNONNULL, l2); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(659, l3); + mv.visitFieldInsn(GETSTATIC, "org/apache/logging/log4j/Level", "ERROR", "Lorg/apache/logging/log4j/Level;"); + mv.visitLdcInsn("Failed to locate the container for mod instance %s (%s : %x)"); + mv.visitInsn(ICONST_3); + mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(AASTORE); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_1); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", false); + mv.visitInsn(AASTORE); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_2); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "identityHashCode", "(Ljava/lang/Object;)I", false); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); + mv.visitInsn(AASTORE); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/FMLLog", "log", "(Lorg/apache/logging/log4j/Level;Ljava/lang/String;[Ljava/lang/Object;)V", false); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(660, l4); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + mv.visitLabel(l2); + mv.visitLineNumber(662, l2); + mv.visitFrame(F_APPEND,1, new Object[] {"cpw/mods/fml/common/ModContainer"}, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEINTERFACE, "cpw/mods/fml/common/ModContainer", "getModId", "()Ljava/lang/String;", true); + mv.visitVarInsn(ASTORE, 4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(663, l5); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManag