diff options
Diffstat (limited to 'src/main/java/gtPlusPlus/preloader/asm')
38 files changed, 10690 insertions, 0 deletions
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<String> propOrder = new ArrayList<String>(); + ArrayList<String> propOrderDebug = new ArrayList<String>(); + + 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<ArtifactVersion>) 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..b52f4eb67e --- /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<String, Object> 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 = ReflectionUtils.getFieldValue(ReflectionUtils.getField(Locale.class, "defaultDisplayLocale")); + Locale aFormatLocale = 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<String, Object> 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<String, Integer> oreIDs; + private static TMap<Integer, ArrayList<ItemStack>> oreStacks; + private static TMap<ItemWrapper, ArrayList<Integer>> stackIDs; + private static TMap<ItemWrapper, ArrayList<String>> stackNames; + + static { + try { + oreIDs = (BiMap<String, Integer>) ReflectionUtils.getField(OreDictionaryArbiter.class, "oreIDs").get(null); + oreStacks = (TMap<Integer, ArrayList<ItemStack>>) ReflectionUtils.getField(OreDictionaryArbiter.class, "oreStacks").get(null); + stackIDs = (TMap<ItemWrapper, ArrayList<Integer>>) ReflectionUtils.getField(OreDictionaryArbiter.class, "stackIDs").get(null); + stackNames = (TMap<ItemWrapper, ArrayList<String>>) ReflectionUtils.getField(OreDictionaryArbiter.class, "stackNames").get(null); + } + catch (Throwable t) { + oreIDs = HashBiMap.create(); + oreStacks = new THashMap<Integer, ArrayList<ItemStack>>(); + stackIDs = new THashMap<ItemWrapper, ArrayList<Integer>>(); + stackNames = new THashMap<ItemWrapper, ArrayList<String>>(); + } + } + + 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<ItemStack>()); + } + ((ArrayList<ItemStack>) oreStacks.get(Integer.valueOf(arg1))).add(arg); + ItemWrapper arg2 = ItemWrapper.fromItemStack(arg); + if (!stackIDs.containsKey(arg2)) { + stackIDs.put(arg2, new ArrayList<Integer>()); + stackNames.put(arg2, new ArrayList<String>()); + } + ((ArrayList<Integer>) stackIDs.get(arg2)).add(Integer.valueOf(arg1)); + ((ArrayList<String>) 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", "<init>", "(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", "<init>", "(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<L"+aChunkCoordIntPair+";Lnet/minecraftforge/common/ForgeChunkManager$Ticket;>;", 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", "<init>", "(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<L"+aChunkCoordIntPair+";Lnet/minecraftforge/common/ForgeChunkManager$Ticket;>;", l6, l10, 2); + mv.visitLocalVariable("newMap", "Lcom/google/common/collect/ImmutableSetMultimap;", "Lcom/google/common/collect/ImmutableSetMultimap<L"+aChunkCoordIntPair+";Lnet/minecraftforge/common/ForgeChunkManager$Ticket;>;", 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/ForgeChunkManager", "callbacks", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "containsKey", "(Ljava/lang/Object;)Z", true); + Label l6 = new Label(); + mv.visitJumpInsn(IFNE, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(665, l7); + mv.visitLdcInsn("The mod %s has attempted to request a ticket without a listener in place"); + mv.visitInsn(ICONST_1); + mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ALOAD, 4); + 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(666, l8); + mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); + mv.visitInsn(DUP); + mv.visitLdcInsn("Invalid ticket request"); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false); + mv.visitInsn(ATHROW); + mv.visitLabel(l6); + mv.visitLineNumber(669, l6); + mv.visitFrame(F_APPEND,1, new Object[] {"java/lang/String"}, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager", "getMaxTicketLengthFor", "(Ljava/lang/String;)I", false); + mv.visitVarInsn(ISTORE, 5); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(671, l9); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "tickets", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 1); + 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, 4); + mv.visitMethodInsn(INVOKEINTERFACE, "com/google/common/collect/Multimap", "get", "(Ljava/lang/Object;)Ljava/util/Collection;", true); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "size", "()I", true); + mv.visitVarInsn(ILOAD, 5); + Label l10 = new Label(); + mv.visitJumpInsn(IF_ICMPLT, l10); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(673, l11); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "warnedMods", "Ljava/util/Set;"); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "contains", "(Ljava/lang/Object;)Z", true); + Label l12 = new Label(); + mv.visitJumpInsn(IFNE, l12); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(675, l13); + mv.visitLdcInsn("The mod %s has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum : %d"); + mv.visitInsn(ICONST_2); + mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ALOAD, 4); + mv.visitInsn(AASTORE); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_1); + mv.visitVarInsn(ILOAD, 5); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); + mv.visitInsn(AASTORE); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/FMLLog", "info", "(Ljava/lang/String;[Ljava/lang/Object;)V", false); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(676, l14); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "warnedMods", "Ljava/util/Set;"); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Set", "add", "(Ljava/lang/Object;)Z", true); + mv.visitInsn(POP); + mv.visitLabel(l12); + mv.visitLineNumber(678, l12); + mv.visitFrame(F_APPEND,1, new Object[] {INTEGER}, 0, null); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + mv.visitLabel(l10); + mv.visitLineNumber(680, l10); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitTypeInsn(NEW, "net/minecraftforge/common/ForgeChunkManager$Ticket"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/common/ForgeChunkManager$Ticket", "<init>", "(Ljava/lang/String;Lnet/minecraftforge/common/ForgeChunkManager$Type;L"+aWorld+";)V", false); + mv.visitVarInsn(ASTORE, 6); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(681, l15); + mv.visitVarInsn(ALOAD, 6); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/ChunkDebugger", "storeTicketToCache", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aWorld+";)V", false); + Label l16 = new Label(); + mv.visitLabel(l16); + mv.visitLineNumber(682, l16); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "tickets", "Ljava/util/Map;"); + mv.visitVarInsn(ALOAD, 1); + 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, 4); + mv.visitVarInsn(ALOAD, 6); + mv.visitMethodInsn(INVOKEINTERFACE, "com/google/common/collect/Multimap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Z", true); + mv.visitInsn(POP); + Label l17 = new Label(); + mv.visitLabel(l17); + mv.visitLineNumber(683, l17); + mv.visitVarInsn(ALOAD, 6); + mv.visitInsn(ARETURN); + Label l18 = new Label(); + mv.visitLabel(l18); + mv.visitLocalVariable("mod", "Ljava/lang/Object;", null, l0, l18, 0); + mv.visitLocalVariable("world", "L"+aWorld+";", null, l0, l18, 1); + mv.visitLocalVariable("type", "Lnet/minecraftforge/common/ForgeChunkManager$Type;", null, l0, l18, 2); + mv.visitLocalVariable("container", "Lcpw/mods/fml/common/ModContainer;", null, l1, l18, 3); + mv.visitLocalVariable("modId", "Ljava/lang/String;", null, l5, l18, 4); + mv.visitLocalVariable("allowedCount", "I", null, l9, l18, 5); + mv.visitLocalVariable("ticket", "Lnet/minecraftforge/common/ForgeChunkManager$Ticket;", null, l15, l18, 6); + mv.visitMaxs(6, 7); + mv.visitEnd(); + + } + + + else if (aMethodName.equals("releaseTicket")) { + + mv = getWriter().visitMethod(ACC_PUBLIC + ACC_STATIC, "releaseTicket", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(693, l0); + mv.visitVarInsn(ALOAD, 0); + Label l1 = new Label(); + mv.visitJumpInsn(IFNONNULL, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(695, l2); + mv.visitInsn(RETURN); + mv.visitLabel(l1); + mv.visitLineNumber(697, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/common/ForgeChunkManager$Ticket", "isPlayerTicket", "()Z", false); + Label l3 = new Label(); + mv.visitJumpInsn(IFEQ, l3); + 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 l4 = new Label(); + mv.visitJumpInsn(IFNE, l4); + Label l5 = new Label(); + mv.visitJumpInsn(GOTO, l5); + mv.visitLabel(l3); + 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, l4); + mv.visitLabel(l5); + mv.visitLineNumber(699, l5); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + mv.visitLabel(l4); + mv.visitLineNumber(701, l4); + 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); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(703, l7); + 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(INVOKESTATIC, "com/google/common/collect/ImmutableSet", "copyOf", "(Ljava/util/Collection;)Lcom/google/common/collect/ImmutableSet;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "com/google/common/collect/ImmutableSet", "iterator", "()Ljava/util/Iterator;", false); + mv.visitVarInsn(ASTORE, 2); + Label l8 = new Label(); + mv.visitJumpInsn(GOTO, l8); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitFrame(F_FULL, 3, new Object[] {"net/minecraftforge/common/ForgeChunkManager$Ticket", TOP, "java/util/Iterator"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, ""+aChunkCoordIntPair+""); + mv.visitVarInsn(ASTORE, 1); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(705, l10); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager", "unforceChunk", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;L"+aChunkCoordIntPair+";)V", false); + mv.visitLabel(l8); + mv.visitLineNumber(703, l8); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true); + mv.visitJumpInsn(IFNE, l9); + mv.visitLabel(l6); + mv.visitLineNumber(708, l6); + mv.visitFrame(F_FULL, 1, new Object[] {"net/minecraftforge/common/ForgeChunkManager$Ticket"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/ChunkDebugger", "removeTicketFromCache", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)V", false); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(709, l11); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/common/ForgeChunkManager$Ticket", "isPlayerTicket", "()Z", false); + Label l12 = new Label(); + mv.visitJumpInsn(IFEQ, l12); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(711, l13); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/ForgeChunkManager", "playerTickets", "Lcom/google/common/collect/SetMultimap;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/common/ForgeChunkManager$Ticket", "access$100", "(Lnet/minecraftforge/common/ForgeChunkManager$Ticket;)Ljava/lang/String;", false); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEINTERFACE, "com/google/common/collect/SetMultimap", "remove", "(Ljava/lang/Object;Ljava/lang/Object;)Z", true); + mv.visitInsn(POP); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(712, l14); + 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.visitLdcInsn("Forge"); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEINTERFACE, "com/google/common/collect/Multimap", "remove", "(Ljava/lang/Object;Ljava/lang/Object;)Z", true); + mv.visitInsn(POP); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(713, l15); + Label l16 = new Label(); + mv.visitJumpInsn(GOTO, l16); + mv.visitLabel(l12); + mv.visitLineNumber(716, l12); + 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", "remove", "(Ljava/lang/Object;Ljava/lang/Object;)Z", true); + mv.visitInsn(POP); + mv.visitLabel(l16); + mv.visitLineNumber(718, l16); + mv.visitFrame(F_SAME, 0, null, 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, l10, l8, 1); + mv.visitMaxs(3, 3); + mv.visitEnd(); + + } + + + FMLRelaunchLog.log("[GT++ ASM] Chunkloading 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("forceChunk") || name.equals("unforceChunk") || name.equals("requestTicket") || name.equals("releaseTicket")) { + FMLRelaunchLog.log("[GT++ ASM] Chunkloading Patch", Level.INFO, "Found method "+name+", Patching."); + return null; + } + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_EntityLivingBase_SetHealth.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_EntityLivingBase_SetHealth.java new file mode 100644 index 0000000000..d56b9de059 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_EntityLivingBase_SetHealth.java @@ -0,0 +1,130 @@ +package gtPlusPlus.preloader.asm.transformers; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.DamageSource; + +public class ClassTransformer_Forge_EntityLivingBase_SetHealth { + + private boolean isValid = false; + private ClassReader mReader = null; + private ClassWriter mWriter = null; + private boolean didPatch = false; + + public ClassTransformer_Forge_EntityLivingBase_SetHealth(String aClassName, byte[] basicClass) { + if (basicClass == null) { + return; + } + + ClassReader reader = new ClassReader(basicClass); + ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS); + ClassVisitor visitor = writer; + SetHealthVisitor aVisitor = new SetHealthVisitor(visitor); + visitor = aVisitor; + reader.accept(visitor, 0); + if (reader != null && writer != null) { + isValid = true; + } + else { + isValid = false; + } + mReader = reader; + mWriter = writer; + didPatch = aVisitor.didPatchInternal; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return mReader; + } + + public ClassWriter getWriter() { + return mWriter; + } + + + public static class SetHealthVisitor extends ClassVisitor { + private String clsName = null; + private boolean didPatchInternal = false; + private static final String callbackOwner = org.objectweb.asm.Type.getInternalName(SetHealthVisitor.class); + + private SetHealthVisitor(ClassVisitor cv) { + super(Opcodes.ASM5, cv); + } + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + super.visit( + version, access, name, signature, superName, interfaces + ); + this.clsName = name; + } + + @Override + public MethodVisitor visitMethod( + int mAccess, final String mName, final String mDesc, String mSignature, String[] mExceptions) { + final boolean warn = !(clsName.equals( + "net/minecraft/entity/EntityLivingBase" + )); + + return new MethodVisitor(Opcodes.ASM5, super.visitMethod(mAccess, mName, mDesc, mSignature, mExceptions)) { + @Override + public void visitMethodInsn( + int opcode, String owner, String name, String desc, boolean isIntf + ) { + if (owner.equals( + "net/minecraft/entity/EntityLivingBase" + ) && name.equals("setHealth") && desc.equals("(F)V")) { + if (warn) { + FMLRelaunchLog.warning( + "=============================================================" + ); + FMLRelaunchLog.warning( + "MOD HAS DIRECT REFERENCE Entity.setHealth() THIS IS NOT ALLOWED!" + ); + FMLRelaunchLog.warning( + "Offendor: %s.%s%s", SetHealthVisitor.this.clsName, mName, mDesc + ); + FMLRelaunchLog.warning( + "Use EntityLiving.attackEntityFrom(DamageSource, damageDealt) instead" + ); + FMLRelaunchLog.warning( + "=============================================================" + ); + } + didPatchInternal = true; + //opcode = Opcodes.INVOKESTATIC; // Set it static + //owner = SetHealthVisitor.callbackOwner; + //name = "setHealthGeneric"; // Replace the method name + //desc = "(Lnet/minecraft/entity/EntityLivingBase;F)V"; // Replace the method desc + + } + super.visitMethodInsn(opcode, owner, name, desc, isIntf); + } + }; + } + + + private final static DamageSource mGenericDamageSource = new DamageSource("gtpp.generic"); + + public static void setHealthGeneric(EntityLivingBase aEntity, float aValue) { + aEntity.attackEntityFrom(mGenericDamageSource, aValue); + } + + } + + + public boolean didPatchClass() { + return didPatch; + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_EntityAutoRocket.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_EntityAutoRocket.java new file mode 100644 index 0000000000..1e58cbbe9b --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_EntityAutoRocket.java @@ -0,0 +1,527 @@ +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_GC_EntityAutoRocket { + + //The qualified name of the class we plan to transform. + private static final String className = "micdoodle8.mods.galacticraft.api.prefab.entity.EntityAutoRocket"; + //micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private final boolean isObfuscated; + + public ClassTransformer_GC_EntityAutoRocket(byte[] basicClass, boolean obfuscated) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + isObfuscated = obfuscated; + + 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(); + } + else { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft EntityAutoRocket Patch", Level.INFO, "Failed to Inject new code."); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public void injectMethod() { + + String aEntityPlayer = isObfuscated ? DevHelper.getObfuscated("net/minecraft/entity/player/EntityPlayer") : "net/minecraft/entity/player/EntityPlayer"; + String aEntityPlayerMP = isObfuscated ? DevHelper.getObfuscated("net/minecraft/entity/player/EntityPlayerMP") : "net/minecraft/entity/player/EntityPlayerMP"; + String aWorld = isObfuscated ? DevHelper.getObfuscated("net/minecraft/world/World") : "net/minecraft/world/World"; + String aItemStack = isObfuscated ? DevHelper.getObfuscated("net/minecraft/item/ItemStack") : "net/minecraft/item/ItemStack"; + String aEntity = isObfuscated ? DevHelper.getObfuscated("net/minecraft/entity/Entity") : "net/minecraft/entity/Entity"; + String aWorldClient = isObfuscated ? DevHelper.getObfuscated("net/minecraft/client/multiplayer/WorldClient") : "net/minecraft/client/multiplayer/WorldClient"; + String aDifficultyEnum = isObfuscated ? DevHelper.getObfuscated("net/minecraft/world/EnumDifficulty") : "net/minecraft/world/EnumDifficulty"; + String aWorldInfo = isObfuscated ? DevHelper.getObfuscated("net/minecraft/world/storage/WorldInfo") : "net/minecraft/world/storage/WorldInfo"; + String aItemInWorldManager = isObfuscated ? DevHelper.getObfuscated("net/minecraft/server/management/ItemInWorldManager") : "net/minecraft/server/management/ItemInWorldManager"; + String aWorldType = isObfuscated ? DevHelper.getObfuscated("net/minecraft/world/WorldType") : "net/minecraft/world/WorldType"; + String aGameType = isObfuscated ? DevHelper.getObfuscated("net/minecraft/world/WorldSettings$GameType") : "net/minecraft/world/WorldSettings$GameType"; + + if (isValidTransformer()) { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft EntityAutoRocket Patch", Level.INFO, "Injecting decodePacketdata into "+className+"."); + MethodVisitor mv = getWriter().visitMethod(ACC_PUBLIC, "decodePacketdata", "(Lio/netty/buffer/ByteBuf;)V", null, null); + + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1027, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESPECIAL, "micdoodle8/mods/galacticraft/api/prefab/entity/EntitySpaceshipBase", "decodePacketdata", "(Lio/netty/buffer/ByteBuf;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(1029, l1); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/xmod/galacticraft/util/GalacticUtils", "getValidFuelForTier", "(L"+aEntity+";)Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitVarInsn(ASTORE, 2); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(1030, l2); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitVarInsn(ISTORE, 3); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(1031, l3); + mv.visitVarInsn(ALOAD, 2); + Label l4 = new Label(); + mv.visitJumpInsn(IFNULL, l4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(1032, l5); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/FluidStack;I)V", false); + mv.visitVarInsn(ASTORE, 4); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(1033, l6); + mv.visitVarInsn(ALOAD, 4); + mv.visitJumpInsn(IFNULL, l4); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(1034, l7); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "setFluid", "(Lnet/minecraftforge/fluids/FluidStack;)V", false); + mv.visitLabel(l4); + mv.visitLineNumber(1038, l4); + mv.visitFrame(F_APPEND,2, new Object[] {"net/minecraftforge/fluids/FluidStack", INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readBoolean", "()Z", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "landing", "Z"); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(1039, l8); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "destinationFrequency", "I"); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(1041, l9); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readBoolean", "()Z", false); + Label l10 = new Label(); + mv.visitJumpInsn(IFEQ, l10); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(1043, l11); + mv.visitVarInsn(ALOAD, 0); + mv.visitTypeInsn(NEW, "micdoodle8/mods/galacticraft/api/vector/BlockVec3"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitMethodInsn(INVOKESPECIAL, "micdoodle8/mods/galacticraft/api/vector/BlockVec3", "<init>", "(III)V", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "targetVec", "Lmicdoodle8/mods/galacticraft/api/vector/BlockVec3;"); + mv.visitLabel(l10); + mv.visitLineNumber(1046, l10); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readDouble", "()D", false); + mv.visitLdcInsn(new Double("8000.0")); + mv.visitInsn(DDIV); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "motionX", "D"); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(1047, l12); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readDouble", "()D", false); + mv.visitLdcInsn(new Double("8000.0")); + mv.visitInsn(DDIV); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "motionY", "D"); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(1048, l13); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readDouble", "()D", false); + mv.visitLdcInsn(new Double("8000.0")); + mv.visitInsn(DDIV); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "motionZ", "D"); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(1049, l14); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readDouble", "()D", false); + mv.visitLdcInsn(new Double("8000.0")); + mv.visitInsn(DDIV); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "lastMotionY", "D"); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(1050, l15); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readDouble", "()D", false); + mv.visitLdcInsn(new Double("8000.0")); + mv.visitInsn(DDIV); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "lastLastMotionY", "D"); + Label l16 = new Label(); + mv.visitLabel(l16); + mv.visitLineNumber(1052, l16); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "cargoItems", "[L"+aItemStack+";"); + Label l17 = new Label(); + mv.visitJumpInsn(IFNONNULL, l17); + Label l18 = new Label(); + mv.visitLabel(l18); + mv.visitLineNumber(1054, l18); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "getSizeInventory", "()I", false); + mv.visitTypeInsn(ANEWARRAY, aItemStack); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "cargoItems", "[L"+aItemStack+";"); + mv.visitLabel(l17); + mv.visitLineNumber(1057, l17); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readBoolean", "()Z", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "setWaitForPlayer", "(Z)V", false); + Label l19 = new Label(); + mv.visitLabel(l19); + mv.visitLineNumber(1059, l19); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/network/ByteBufUtils", "readUTF8String", "(Lio/netty/buffer/ByteBuf;)Ljava/lang/String;", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusMessage", "Ljava/lang/String;"); + Label l20 = new Label(); + mv.visitLabel(l20); + mv.visitLineNumber(1060, l20); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusMessage", "Ljava/lang/String;"); + mv.visitLdcInsn(""); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l21 = new Label(); + mv.visitJumpInsn(IFEQ, l21); + mv.visitInsn(ACONST_NULL); + Label l22 = new Label(); + mv.visitJumpInsn(GOTO, l22); + mv.visitLabel(l21); + mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {"micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket"}); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusMessage", "Ljava/lang/String;"); + mv.visitLabel(l22); + mv.visitFrame(F_FULL, 4, new Object[] {"micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "io/netty/buffer/ByteBuf", "net/minecraftforge/fluids/FluidStack", INTEGER}, 2, new Object[] {"micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "java/lang/String"}); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusMessage", "Ljava/lang/String;"); + Label l23 = new Label(); + mv.visitLabel(l23); + mv.visitLineNumber(1061, l23); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusMessageCooldown", "I"); + Label l24 = new Label(); + mv.visitLabel(l24); + mv.visitLineNumber(1062, l24); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "lastStatusMessageCooldown", "I"); + Label l25 = new Label(); + mv.visitLabel(l25); + mv.visitLineNumber(1063, l25); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readBoolean", "()Z", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusValid", "Z"); + Label l26 = new Label(); + mv.visitLabel(l26); + mv.visitLineNumber(1066, l26); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "worldObj", "L"+aWorld+";"); + mv.visitFieldInsn(GETFIELD, aWorld, "isRemote", "Z"); + Label l27 = new Label(); + mv.visitJumpInsn(IFEQ, l27); + Label l28 = new Label(); + mv.visitLabel(l28); + mv.visitLineNumber(1068, l28); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "io/netty/buffer/ByteBuf", "readInt", "()I", false); + mv.visitVarInsn(ISTORE, 4); + Label l29 = new Label(); + mv.visitLabel(l29); + mv.visitLineNumber(1069, l29); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "riddenByEntity", "L"+aEntity+";"); + Label l30 = new Label(); + mv.visitJumpInsn(IFNONNULL, l30); + Label l31 = new Label(); + mv.visitLabel(l31); + mv.visitLineNumber(1071, l31); + mv.visitVarInsn(ILOAD, 4); + mv.visitInsn(ICONST_M1); + mv.visitJumpInsn(IF_ICMPLE, l27); + Label l32 = new Label(); + mv.visitLabel(l32); + mv.visitLineNumber(1073, l32); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/client/FMLClientHandler", "instance", "()Lcpw/mods/fml/client/FMLClientHandler;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "cpw/mods/fml/client/FMLClientHandler", "getWorldClient", "()L"+aWorldClient+";", false); + mv.visitVarInsn(ILOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aWorldClient+"", "getEntityByID", "(I)L"+aEntity+";", false); + mv.visitVarInsn(ASTORE, 5); + Label l33 = new Label(); + mv.visitLabel(l33); + mv.visitLineNumber(1074, l33); + mv.visitVarInsn(ALOAD, 5); + mv.visitJumpInsn(IFNULL, l27); + Label l34 = new Label(); + mv.visitLabel(l34); + mv.visitLineNumber(1076, l34); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETFIELD, ""+aEntity+"", "dimension", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "dimension", "I"); + Label l35 = new Label(); + mv.visitJumpInsn(IF_ICMPEQ, l35); + Label l36 = new Label(); + mv.visitLabel(l36); + mv.visitLineNumber(1078, l36); + mv.visitVarInsn(ALOAD, 5); + mv.visitTypeInsn(INSTANCEOF, ""+aEntityPlayer+""); + mv.visitJumpInsn(IFEQ, l27); + Label l37 = new Label(); + mv.visitLabel(l37); + mv.visitLineNumber(1080, l37); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "dimension", "I"); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETFIELD, ""+aEntity+"", "worldObj", "L"+aWorld+";"); + mv.visitFieldInsn(GETFIELD, aWorld, "difficultySetting", "L"+aDifficultyEnum+";"); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aDifficultyEnum+"", "getDifficultyId", "()I", false); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETFIELD, ""+aEntity+"", "worldObj", "L"+aWorld+";"); + mv.visitMethodInsn(INVOKEVIRTUAL, aWorld, "getWorldInfo", "()L"+aWorldInfo+";", false); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aWorldInfo+"", "getTerrainType", "()L"+aWorldType+";", false); + mv.visitMethodInsn(INVOKEVIRTUAL, aWorldType, "getWorldTypeName", "()Ljava/lang/String;", false); + mv.visitVarInsn(ALOAD, 5); + mv.visitTypeInsn(CHECKCAST, ""+aEntityPlayerMP+""); + mv.visitFieldInsn(GETFIELD, ""+aEntityPlayerMP+"", "theItemInWorldManager", "L"+aItemInWorldManager+";"); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItemInWorldManager+"", "getGameType", "()L"+aGameType+";", false); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aGameType+"", "getID", "()I", false); + mv.visitMethodInsn(INVOKESTATIC, "micdoodle8/mods/galacticraft/core/util/WorldUtil", "forceRespawnClient", "(IILjava/lang/String;I)L"+aEntityPlayer+";", false); + mv.visitVarInsn(ASTORE, 5); + Label l38 = new Label(); + mv.visitLabel(l38); + mv.visitLineNumber(1081, l38); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aEntity+"", "mountEntity", "(L"+aEntity+";)V", false); + Label l39 = new Label(); + mv.visitLabel(l39); + mv.visitLineNumber(1083, l39); + mv.visitJumpInsn(GOTO, l27); + mv.visitLabel(l35); + mv.visitLineNumber(1085, l35); + mv.visitFrame(F_APPEND,2, new Object[] {INTEGER, ""+aEntity+""}, 0, null); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aEntity+"", "mountEntity", "(L"+aEntity+";)V", false); + Label l40 = new Label(); + mv.visitLabel(l40); + mv.visitLineNumber(1088, l40); + mv.visitJumpInsn(GOTO, l27); + mv.visitLabel(l30); + mv.visitLineNumber(1089, l30); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "riddenByEntity", "L"+aEntity+";"); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aEntity+"", "getEntityId", "()I", false); + mv.visitVarInsn(ILOAD, 4); + mv.visitJumpInsn(IF_ICMPEQ, l27); + Label l41 = new Label(); + mv.visitLabel(l41); + mv.visitLineNumber(1091, l41); + mv.visitVarInsn(ILOAD, 4); + mv.visitInsn(ICONST_M1); + Label l42 = new Label(); + mv.visitJumpInsn(IF_ICMPNE, l42); + Label l43 = new Label(); + mv.visitLabel(l43); + mv.visitLineNumber(1093, l43); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "riddenByEntity", "L"+aEntity+";"); + mv.visitInsn(ACONST_NULL); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aEntity+"", "mountEntity", "(L"+aEntity+";)V", false); + Label l44 = new Label(); + mv.visitLabel(l44); + mv.visitLineNumber(1094, l44); + mv.visitJumpInsn(GOTO, l27); + mv.visitLabel(l42); + mv.visitLineNumber(1097, l42); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/client/FMLClientHandler", "instance", "()Lcpw/mods/fml/client/FMLClientHandler;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "cpw/mods/fml/client/FMLClientHandler", "getWorldClient", "()L"+aWorldClient+";", false); + mv.visitVarInsn(ILOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aWorldClient+"", "getEntityByID", "(I)L"+aEntity+";", false); + mv.visitVarInsn(ASTORE, 5); + Label l45 = new Label(); + mv.visitLabel(l45); + mv.visitLineNumber(1098, l45); + mv.visitVarInsn(ALOAD, 5); + mv.visitJumpInsn(IFNULL, l27); + Label l46 = new Label(); + mv.visitLabel(l46); + mv.visitLineNumber(1100, l46); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETFIELD, ""+aEntity+"", "dimension", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "dimension", "I"); + Label l47 = new Label(); + mv.visitJumpInsn(IF_ICMPEQ, l47); + Label l48 = new Label(); + mv.visitLabel(l48); + mv.visitLineNumber(1102, l48); + mv.visitVarInsn(ALOAD, 5); + mv.visitTypeInsn(INSTANCEOF, ""+aEntityPlayer+""); + mv.visitJumpInsn(IFEQ, l27); + Label l49 = new Label(); + mv.visitLabel(l49); + mv.visitLineNumber(1104, l49); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "dimension", "I"); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETFIELD, ""+aEntity+"", "worldObj", "L"+aWorld+";"); + mv.visitFieldInsn(GETFIELD, aWorld, "difficultySetting", "L"+aDifficultyEnum+";"); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aDifficultyEnum+"", "getDifficultyId", "()I", false); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETFIELD, ""+aEntity+"", "worldObj", "L"+aWorld+";"); + mv.visitMethodInsn(INVOKEVIRTUAL, aWorld, "getWorldInfo", "()L"+aWorldInfo+";", false); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aWorldInfo+"", "getTerrainType", "()L"+aWorldType+";", false); + mv.visitMethodInsn(INVOKEVIRTUAL, aWorldType, "getWorldTypeName", "()Ljava/lang/String;", false); + mv.visitVarInsn(ALOAD, 5); + mv.visitTypeInsn(CHECKCAST, ""+aEntityPlayerMP+""); + mv.visitFieldInsn(GETFIELD, ""+aEntityPlayerMP+"", "theItemInWorldManager", "L"+aItemInWorldManager+";"); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItemInWorldManager+"", "getGameType", "()L"+aGameType+";", false); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aGameType+"", "getID", "()I", false); + mv.visitMethodInsn(INVOKESTATIC, "micdoodle8/mods/galacticraft/core/util/WorldUtil", "forceRespawnClient", "(IILjava/lang/String;I)L"+aEntityPlayer+";", false); + mv.visitVarInsn(ASTORE, 5); + Label l50 = new Label(); + mv.visitLabel(l50); + mv.visitLineNumber(1105, l50); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aEntity+"", "mountEntity", "(L"+aEntity+";)V", false); + Label l51 = new Label(); + mv.visitLabel(l51); + mv.visitLineNumber(1107, l51); + mv.visitJumpInsn(GOTO, l27); + mv.visitLabel(l47); + mv.visitLineNumber(1109, l47); + mv.visitFrame(F_APPEND,1, new Object[] {""+aEntity+""}, 0, null); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aEntity+"", "mountEntity", "(L"+aEntity+";)V", false); + mv.visitLabel(l27); + mv.visitLineNumber(1114, l27); + mv.visitFrame(F_CHOP,2, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/network/ByteBufUtils", "readUTF8String", "(Lio/netty/buffer/ByteBuf;)Ljava/lang/String;", false); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusColour", "Ljava/lang/String;"); + Label l52 = new Label(); + mv.visitLabel(l52); + mv.visitLineNumber(1115, l52); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusColour", "Ljava/lang/String;"); + mv.visitLdcInsn(""); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l53 = new Label(); + mv.visitJumpInsn(IFEQ, l53); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ACONST_NULL); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket", "statusColour", "Ljava/lang/String;"); + mv.visitLabel(l53); + mv.visitLineNumber(1116, l53); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + Label l54 = new Label(); + mv.visitLabel(l54); + mv.visitLocalVariable("this", "Lmicdoodle8/mods/galacticraft/api/prefab/entity/EntityAutoRocket;", null, l0, l54, 0); + mv.visitLocalVariable("buffer", "Lio/netty/buffer/ByteBuf;", null, l0, l54, 1); + mv.visitLocalVariable("g", "Lnet/minecraftforge/fluids/FluidStack;", null, l2, l54, 2); + mv.visitLocalVariable("aBufferData", "I", null, l3, l54, 3); + mv.visitLocalVariable("s", "Lnet/minecraftforge/fluids/FluidStack;", null, l6, l4, 4); + mv.visitLocalVariable("shouldBeMountedId", "I", null, l29, l27, 4); + mv.visitLocalVariable("e", "L"+aEntity+";", null, l33, l40, 5); + mv.visitLocalVariable("e", "L"+aEntity+";", null, l45, l27, 5); + mv.visitMaxs(6, 6); + mv.visitEnd(); + + } + } + + public static final class localClassVisitor extends ClassVisitor { + + public localClassVisitor(ClassVisitor cv) { + super(ASM5, cv); + FMLRelaunchLog.log("[GT++ ASM] Galacticraft EntityAutoRocket Patch", Level.INFO, "Inspecting Class "+className); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (name.equals("decodePacketdata")) { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft EntityAutoRocket Patch", Level.INFO, "Removing method "+name); + return null; + } + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FluidUtil.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FluidUtil.java new file mode 100644 index 0000000000..13681e7e3a --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FluidUtil.java @@ -0,0 +1,242 @@ +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; + + +public class ClassTransformer_GC_FluidUtil { + + //The qualified name of the class we plan to transform. + private static final String className = "micdoodle8.mods.galacticraft.core.util.FluidUtil"; + //"micdoodle8/mods/galacticraft/core/util/FluidUtil + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public ClassTransformer_GC_FluidUtil(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) { + injectMethod("testFuel"); + injectMethod("fillWithGCFuel"); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public void injectMethod(String aMethodName) { + MethodVisitor mv; + if (aMethodName.equals("testFuel")) { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft FluidUtils Patch", Level.INFO, "Injecting "+aMethodName+" into "+className+"."); + mv = getWriter().visitMethod(ACC_PUBLIC + ACC_STATIC, "testFuel", "(Ljava/lang/String;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(37, l0); + mv.visitFieldInsn(GETSTATIC, "gtPlusPlus/core/item/chemistry/RocketFuels", "mValidRocketFuelNames", "Ljava/util/HashSet;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashSet", "iterator", "()Ljava/util/Iterator;", false); + mv.visitVarInsn(ASTORE, 2); + Label l1 = new Label(); + mv.visitJumpInsn(GOTO, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitFrame(F_FULL, 3, new Object[] {"java/lang/String", TOP, "java/util/Iterator"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, "java/lang/String"); + mv.visitVarInsn(ASTORE, 1); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(38, l3); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + mv.visitJumpInsn(IFEQ, l1); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(39, l4); + mv.visitInsn(ICONST_1); + mv.visitInsn(IRETURN); + mv.visitLabel(l1); + mv.visitLineNumber(37, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true); + mv.visitJumpInsn(IFNE, l2); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(42, l5); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLocalVariable("name", "Ljava/lang/String;", null, l0, l6, 0); + mv.visitLocalVariable("aFuelname", "Ljava/lang/String;", null, l3, l1, 1); + mv.visitMaxs(2, 3); + mv.visitEnd(); + } + else if (aMethodName.equals("fillWithGCFuel")) { + mv = getWriter().visitMethod(ACC_PUBLIC + ACC_STATIC, "fillWithGCFuel", "(Lnet/minecraftforge/fluids/FluidTank;Lnet/minecraftforge/fluids/FluidStack;Z)I", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(46, l0); + mv.visitVarInsn(ALOAD, 1); + Label l1 = new Label(); + mv.visitJumpInsn(IFNULL, l1); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/fluids/FluidRegistry", "getFluidName", "(Lnet/minecraftforge/fluids/FluidStack;)Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKESTATIC, "micdoodle8/mods/galacticraft/core/util/FluidUtil", "testFuel", "(Ljava/lang/String;)Z", false); + mv.visitJumpInsn(IFEQ, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(47, l2); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitVarInsn(ASTORE, 3); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(48, l3); + mv.visitVarInsn(ALOAD, 3); + Label l4 = new Label(); + mv.visitJumpInsn(IFNONNULL, l4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(49, l5); + mv.visitFieldInsn(GETSTATIC, "gtPlusPlus/core/item/chemistry/RocketFuels", "mValidRocketFuels", "Ljava/util/HashMap;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashMap", "values", "()Ljava/util/Collection;", false); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "iterator", "()Ljava/util/Iterator;", true); + mv.visitVarInsn(ASTORE, 5); + Label l6 = new Label(); + mv.visitJumpInsn(GOTO, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitFrame(F_FULL, 6, new Object[] {"net/minecraftforge/fluids/FluidTank", "net/minecraftforge/fluids/FluidStack", INTEGER, "net/minecraftforge/fluids/FluidStack", TOP, "java/util/Iterator"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, "net/minecraftforge/fluids/Fluid"); + mv.visitVarInsn(ASTORE, 4); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(50, l8); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidStack", "getFluid", "()Lnet/minecraftforge/fluids/Fluid;", false); + mv.visitVarInsn(ALOAD, 4); + mv.visitJumpInsn(IF_ACMPNE, l6); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(51, l9); + mv.visitVarInsn(ALOAD, 0); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/Fluid;I)V", false); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "fill", "(Lnet/minecraftforge/fluids/FluidStack;Z)I", false); + mv.visitInsn(IRETURN); + mv.visitLabel(l6); + mv.visitLineNumber(49, l6); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true); + mv.visitJumpInsn(IFNE, l7); + mv.visitLabel(l4); + mv.visitLineNumber(55, l4); + mv.visitFrame(F_FULL, 4, new Object[] {"net/minecraftforge/fluids/FluidTank", "net/minecraftforge/fluids/FluidStack", INTEGER, "net/minecraftforge/fluids/FluidStack"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 3); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getCapacity", "()I", false); + mv.visitJumpInsn(IF_ICMPGE, l1); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(56, l10); + mv.visitVarInsn(ALOAD, 0); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/FluidStack;I)V", false); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "fill", "(Lnet/minecraftforge/fluids/FluidStack;Z)I", false); + mv.visitInsn(IRETURN); + mv.visitLabel(l1); + mv.visitLineNumber(59, l1); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLocalVariable("tank", "Lnet/minecraftforge/fluids/FluidTank;", null, l0, l11, 0); + mv.visitLocalVariable("liquid", "Lnet/minecraftforge/fluids/FluidStack;", null, l0, l11, 1); + mv.visitLocalVariable("doFill", "Z", null, l0, l11, 2); + mv.visitLocalVariable("liquidInTank", "Lnet/minecraftforge/fluids/FluidStack;", null, l3, l1, 3); + mv.visitLocalVariable("aFuelType", "Lnet/minecraftforge/fluids/Fluid;", null, l8, l6, 4); + mv.visitMaxs(5, 6); + mv.visitEnd(); + } + FMLRelaunchLog.log("[GT++ ASM] Galacticraft FluidUtils 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("testFuel")) { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft FluidUtils Patch", Level.INFO, "Removing method "+name); + return null; + } + if (name.equals("fillWithGCFuel")) { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft FluidUtils Patch", Level.INFO, "Removing method "+name); + return null; + } + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FuelLoader.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FuelLoader.java new file mode 100644 index 0000000000..5ef5b75505 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GC_FuelLoader.java @@ -0,0 +1,622 @@ +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_GC_FuelLoader { + + //The qualified name of the class we plan to transform. + private static final String className = "micdoodle8.mods.galacticraft.core.tile.TileEntityFuelLoader"; + //micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private final boolean isObfuscated; + + public ClassTransformer_GC_FuelLoader(byte[] basicClass, boolean obfuscated) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + isObfuscated = obfuscated; + + 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(); + } + else { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft Fuel_Loader Patch", Level.INFO, "Failed to Inject new code."); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public void injectMethod() { + String aWorld = isObfuscated ? DevHelper.getObfuscated("net/minecraft/world/World") : "net/minecraft/world/World"; + String aItemStack = isObfuscated ? DevHelper.getObfuscated("net/minecraft/item/ItemStack") : "net/minecraft/item/ItemStack"; + String aTileEntity = isObfuscated ? DevHelper.getObfuscated("net/minecraft/tileentity/TileEntity") : "net/minecraft/tileentity/TileEntity"; + + if (isValidTransformer()) { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft Fuel_Loader Patch", Level.INFO, "Injecting updateEntity into "+className+"."); + MethodVisitor mv = getWriter().visitMethod(ACC_PUBLIC, "updateEntity", "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(60, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "micdoodle8/mods/galacticraft/core/energy/tile/TileBaseElectricBlockWithInventory", "updateEntity", "()V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(61, l1); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "worldObj", "L"+aWorld+";"); + mv.visitFieldInsn(GETFIELD, ""+aWorld+"", "isRemote", "Z"); + Label l2 = new Label(); + mv.visitJumpInsn(IFNE, l2); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(62, l3); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ICONST_0); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "loadedFuelLastTick", "Z"); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(63, l4); + mv.visitInsn(ACONST_NULL); + mv.visitVarInsn(ASTORE, 1); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(66, l5); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "containingItems", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_1); + mv.visitInsn(AALOAD); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(67, l7); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "containingItems", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_1); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/fluids/FluidContainerRegistry", "getFluidForFilledItem", "(L"+aItemStack+";)Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitVarInsn(ASTORE, 1); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(68, l8); + mv.visitVarInsn(ALOAD, 1); + mv.visitJumpInsn(IFNULL, l6); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(69, l9); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "net/minecraftforge/fluids/FluidRegistry", "getFluidName", "(Lnet/minecraftforge/fluids/FluidStack;)Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKESTATIC, "micdoodle8/mods/galacticraft/core/util/FluidUtil", "testFuel", "(Ljava/lang/String;)Z", false); + mv.visitVarInsn(ISTORE, 4); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(70, l10); + mv.visitVarInsn(ILOAD, 4); + mv.visitJumpInsn(IFEQ, l6); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + Label l11 = new Label(); + mv.visitJumpInsn(IFNULL, l11); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(71, l12); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitInsn(IADD); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getCapacity", "()I", false); + mv.visitJumpInsn(IF_ICMPGT, l6); + mv.visitLabel(l11); + mv.visitLineNumber(73, l11); + mv.visitFrame(F_FULL, 5, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, TOP, INTEGER}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitVarInsn(ASTORE, 5); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(74, l13); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 6); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(75, l14); + mv.visitVarInsn(ALOAD, 5); + Label l15 = new Label(); + mv.visitJumpInsn(IFNONNULL, l15); + Label l16 = new Label(); + mv.visitLabel(l16); + mv.visitLineNumber(76, l16); + mv.visitFieldInsn(GETSTATIC, "gtPlusPlus/core/item/chemistry/RocketFuels", "mValidRocketFuels", "Ljava/util/HashMap;"); + Label l17 = new Label(); + mv.visitLabel(l17); + mv.visitLineNumber(77, l17); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashMap", "values", "()Ljava/util/Collection;", false); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "iterator", "()Ljava/util/Iterator;", true); + mv.visitVarInsn(ASTORE, 8); + Label l18 = new Label(); + mv.visitJumpInsn(GOTO, l18); + Label l19 = new Label(); + mv.visitLabel(l19); + mv.visitFrame(F_FULL, 9, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, TOP, INTEGER, "net/minecraftforge/fluids/FluidStack", INTEGER, TOP, "java/util/Iterator"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 8); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, "net/minecraftforge/fluids/Fluid"); + mv.visitVarInsn(ASTORE, 7); + Label l20 = new Label(); + mv.visitLabel(l20); + mv.visitLineNumber(78, l20); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidStack", "getFluid", "()Lnet/minecraftforge/fluids/Fluid;", false); + mv.visitVarInsn(ALOAD, 7); + mv.visitJumpInsn(IF_ACMPNE, l18); + Label l21 = new Label(); + mv.visitLabel(l21); + mv.visitLineNumber(79, l21); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 7); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/Fluid;I)V", false); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "fill", "(Lnet/minecraftforge/fluids/FluidStack;Z)I", false); + Label l22 = new Label(); + mv.visitJumpInsn(IFLE, l22); + mv.visitInsn(ICONST_1); + Label l23 = new Label(); + mv.visitJumpInsn(GOTO, l23); + mv.visitLabel(l22); + mv.visitFrame(F_FULL, 9, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, TOP, INTEGER, "net/minecraftforge/fluids/FluidStack", INTEGER, "net/minecraftforge/fluids/Fluid", "java/util/Iterator"}, 0, new Object[] {}); + mv.visitInsn(ICONST_0); + mv.visitLabel(l23); + mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {INTEGER}); + mv.visitVarInsn(ISTORE, 6); + mv.visitLabel(l18); + mv.visitLineNumber(76, l18); + mv.visitFrame(F_FULL, 9, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, TOP, INTEGER, "net/minecraftforge/fluids/FluidStack", INTEGER, TOP, "java/util/Iterator"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 8); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true); + mv.visitJumpInsn(IFNE, l19); + Label l24 = new Label(); + mv.visitLabel(l24); + mv.visitLineNumber(82, l24); + Label l25 = new Label(); + mv.visitJumpInsn(GOTO, l25); + mv.visitLabel(l15); + mv.visitLineNumber(84, l15); + mv.visitFrame(F_FULL, 7, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, TOP, INTEGER, "net/minecraftforge/fluids/FluidStack", INTEGER}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getCapacity", "()I", false); + mv.visitJumpInsn(IF_ICMPGE, l25); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidStack", "isFluidEqual", "(Lnet/minecraftforge/fluids/FluidStack;)Z", false); + mv.visitJumpInsn(IFEQ, l25); + Label l26 = new Label(); + mv.visitLabel(l26); + mv.visitLineNumber(85, l26); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/FluidStack;I)V", false); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "fill", "(Lnet/minecraftforge/fluids/FluidStack;Z)I", false); + Label l27 = new Label(); + mv.visitJumpInsn(IFLE, l27); + mv.visitInsn(ICONST_1); + Label l28 = new Label(); + mv.visitJumpInsn(GOTO, l28); + mv.visitLabel(l27); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(ICONST_0); + mv.visitLabel(l28); + mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {INTEGER}); + mv.visitVarInsn(ISTORE, 6); + mv.visitLabel(l25); + mv.visitLineNumber(88, l25); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ILOAD, 6); + mv.visitJumpInsn(IFEQ, l6); + Label l29 = new Label(); + mv.visitLabel(l29); + mv.visitLineNumber(89, l29); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "containingItems", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_1); + mv.visitInsn(AALOAD); + mv.visitInsn(DUP); + mv.visitFieldInsn(GETFIELD, ""+aItemStack+"", "stackSize", "I"); + mv.visitInsn(ICONST_1); + mv.visitInsn(ISUB); + mv.visitFieldInsn(PUTFIELD, ""+aItemStack+"", "stackSize", "I"); + Label l30 = new Label(); + mv.visitLabel(l30); + mv.visitLineNumber(90, l30); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "containingItems", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_1); + mv.visitInsn(AALOAD); + mv.visitFieldInsn(GETFIELD, ""+aItemStack+"", "stackSize", "I"); + mv.visitJumpInsn(IFNE, l6); + Label l31 = new Label(); + mv.visitLabel(l31); + mv.visitLineNumber(91, l31); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "containingItems", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_1); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(AASTORE); + mv.visitLabel(l6); + mv.visitLineNumber(97, l6); + mv.visitFrame(F_FULL, 2, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "ticks", "I"); + mv.visitIntInsn(BIPUSH, 100); + mv.visitInsn(IREM); + Label l32 = new Label(); + mv.visitJumpInsn(IFNE, l32); + Label l33 = new Label(); + mv.visitLabel(l33); + mv.visitLineNumber(98, l33); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ACONST_NULL); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "attachedFuelable", "Lmicdoodle8/mods/galacticraft/api/entity/IFuelable;"); + Label l34 = new Label(); + mv.visitLabel(l34); + mv.visitLineNumber(99, l34); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "VALID_DIRECTIONS", "[Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ASTORE, 4); + Label l35 = new Label(); + mv.visitLabel(l35); + mv.visitLineNumber(100, l35); + mv.visitVarInsn(ALOAD, 4); + mv.visitInsn(ARRAYLENGTH); + mv.visitVarInsn(ISTORE, 3); + Label l36 = new Label(); + mv.visitLabel(l36); + mv.visitLineNumber(102, l36); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 2); + Label l37 = new Label(); + mv.visitLabel(l37); + Label l38 = new Label(); + mv.visitJumpInsn(GOTO, l38); + Label l39 = new Label(); + mv.visitLabel(l39); + mv.visitLineNumber(103, l39); + mv.visitFrame(F_APPEND,3, new Object[] {INTEGER, INTEGER, "[Lnet/minecraftforge/common/util/ForgeDirection;"}, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ILOAD, 2); + mv.visitInsn(AALOAD); + mv.visitVarInsn(ASTORE, 5); + Label l40 = new Label(); + mv.visitLabel(l40); + mv.visitLineNumber(104, l40); + mv.visitTypeInsn(NEW, "micdoodle8/mods/galacticraft/api/vector/BlockVec3"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "micdoodle8/mods/galacticraft/api/vector/BlockVec3", "<init>", "(L"+aTileEntity+";)V", false); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "worldObj", "L"+aWorld+";"); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKEVIRTUAL, "micdoodle8/mods/galacticraft/api/vector/BlockVec3", "getTileEntityOnSide", "(L"+aWorld+";Lnet/minecraftforge/common/util/ForgeDirection;)L"+aTileEntity+";", false); + mv.visitVarInsn(ASTORE, 6); + Label l41 = new Label(); + mv.visitLabel(l41); + mv.visitLineNumber(105, l41); + mv.visitVarInsn(ALOAD, 6); + mv.visitTypeInsn(INSTANCEOF, "micdoodle8/mods/galacticraft/core/tile/TileEntityMulti"); + Label l42 = new Label(); + mv.visitJumpInsn(IFEQ, l42); + Label l43 = new Label(); + mv.visitLabel(l43); + mv.visitLineNumber(106, l43); + mv.visitVarInsn(ALOAD, 6); + mv.visitTypeInsn(CHECKCAST, "micdoodle8/mods/galacticraft/core/tile/TileEntityMulti"); + mv.visitMethodInsn(INVOKEVIRTUAL, "micdoodle8/mods/galacticraft/core/tile/TileEntityMulti", "getMainBlockTile", "()L"+aTileEntity+";", false); + mv.visitVarInsn(ASTORE, 7); + Label l44 = new Label(); + mv.visitLabel(l44); + mv.visitLineNumber(107, l44); + mv.visitVarInsn(ALOAD, 7); + mv.visitTypeInsn(INSTANCEOF, "micdoodle8/mods/galacticraft/api/entity/IFuelable"); + Label l45 = new Label(); + mv.visitJumpInsn(IFEQ, l45); + Label l46 = new Label(); + mv.visitLabel(l46); + mv.visitLineNumber(108, l46); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 7); + mv.visitTypeInsn(CHECKCAST, "micdoodle8/mods/galacticraft/api/entity/IFuelable"); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "attachedFuelable", "Lmicdoodle8/mods/galacticraft/api/entity/IFuelable;"); + Label l47 = new Label(); + mv.visitLabel(l47); + mv.visitLineNumber(109, l47); + mv.visitJumpInsn(GOTO, l32); + mv.visitLabel(l42); + mv.visitLineNumber(111, l42); + mv.visitFrame(F_APPEND,2, new Object[] {"net/minecraftforge/common/util/ForgeDirection", ""+aTileEntity+""}, 0, null); + mv.visitVarInsn(ALOAD, 6); + mv.visitTypeInsn(INSTANCEOF, "micdoodle8/mods/galacticraft/api/entity/IFuelable"); + mv.visitJumpInsn(IFEQ, l45); + Label l48 = new Label(); + mv.visitLabel(l48); + mv.visitLineNumber(112, l48); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 6); + mv.visitTypeInsn(CHECKCAST, "micdoodle8/mods/galacticraft/api/entity/IFuelable"); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "attachedFuelable", "Lmicdoodle8/mods/galacticraft/api/entity/IFuelable;"); + Label l49 = new Label(); + mv.visitLabel(l49); + mv.visitLineNumber(113, l49); + mv.visitJumpInsn(GOTO, l32); + mv.visitLabel(l45); + mv.visitLineNumber(102, l45); + mv.visitFrame(F_CHOP,2, null, 0, null); + mv.visitIincInsn(2, 1); + mv.visitLabel(l38); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitJumpInsn(IF_ICMPLT, l39); + mv.visitLabel(l32); + mv.visitLineNumber(117, l32); + mv.visitFrame(F_CHOP,3, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitJumpInsn(IFNULL, l2); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitJumpInsn(IFNULL, l2); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitJumpInsn(IFLE, l2); + Label l50 = new Label(); + mv.visitLabel(l50); + mv.visitLineNumber(118, l50); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitVarInsn(ASTORE, 4); + Label l51 = new Label(); + mv.visitLabel(l51); + mv.visitLineNumber(119, l51); + mv.visitVarInsn(ALOAD, 4); + Label l52 = new Label(); + mv.visitJumpInsn(IFNONNULL, l52); + Label l53 = new Label(); + mv.visitLabel(l53); + mv.visitLineNumber(120, l53); + mv.visitFieldInsn(GETSTATIC, "gtPlusPlus/core/item/chemistry/RocketFuels", "mValidRocketFuels", "Ljava/util/HashMap;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/HashMap", "values", "()Ljava/util/Collection;", false); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Collection", "iterator", "()Ljava/util/Iterator;", true); + mv.visitVarInsn(ASTORE, 6); + Label l54 = new Label(); + mv.visitJumpInsn(GOTO, l54); + Label l55 = new Label(); + mv.visitLabel(l55); + mv.visitFrame(F_FULL, 7, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, TOP, "net/minecraftforge/fluids/FluidStack", TOP, "java/util/Iterator"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 6); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); + mv.visitTypeInsn(CHECKCAST, "net/minecraftforge/fluids/Fluid"); + mv.visitVarInsn(ASTORE, 5); + Label l56 = new Label(); + mv.visitLabel(l56); + mv.visitLineNumber(121, l56); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getFluid", "()Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidStack", "getFluid", "()Lnet/minecraftforge/fluids/Fluid;", false); + mv.visitVarInsn(ALOAD, 5); + mv.visitJumpInsn(IF_ACMPNE, l54); + Label l57 = new Label(); + mv.visitLabel(l57); + mv.visitLineNumber(122, l57); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 5); + mv.visitInsn(ICONST_2); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/Fluid;I)V", false); + mv.visitVarInsn(ASTORE, 1); + mv.visitLabel(l54); + mv.visitLineNumber(120, l54); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 6); + mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true); + mv.visitJumpInsn(IFNE, l55); + mv.visitLabel(l52); + mv.visitLineNumber(126, l52); + mv.visitFrame(F_FULL, 5, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, TOP, "net/minecraftforge/fluids/FluidStack"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "getCapacity", "()I", false); + Label l58 = new Label(); + mv.visitJumpInsn(IF_ICMPGE, l58); + Label l59 = new Label(); + mv.visitLabel(l59); + mv.visitLineNumber(127, l59); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 4); + mv.visitInsn(ICONST_2); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/FluidStack;I)V", false); + mv.visitVarInsn(ASTORE, 1); + mv.visitLabel(l58); + mv.visitLineNumber(130, l58); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitJumpInsn(IFNULL, l2); + Label l60 = new Label(); + mv.visitLabel(l60); + mv.visitLineNumber(131, l60); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "attachedFuelable", "Lmicdoodle8/mods/galacticraft/api/entity/IFuelable;"); + mv.visitJumpInsn(IFNULL, l2); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "hasEnoughEnergyToRun", "Z"); + mv.visitJumpInsn(IFEQ, l2); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "disabled", "Z"); + mv.visitJumpInsn(IFNE, l2); + Label l61 = new Label(); + mv.visitLabel(l61); + mv.visitLineNumber(132, l61); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "attachedFuelable", "Lmicdoodle8/mods/galacticraft/api/entity/IFuelable;"); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/xmod/galacticraft/util/GalacticUtils", "getRocketTier", "(Ljava/lang/Object;)I", false); + mv.visitVarInsn(ISTORE, 5); + Label l62 = new Label(); + mv.visitLabel(l62); + mv.visitLineNumber(133, l62); + mv.visitVarInsn(ILOAD, 5); + mv.visitJumpInsn(IFLE, l2); + Label l63 = new Label(); + mv.visitLabel(l63); + mv.visitLineNumber(134, l63); + mv.visitVarInsn(ILOAD, 5); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/xmod/galacticraft/util/GalacticUtils", "isFuelValidForTier", "(ILnet/minecraftforge/fluids/FluidStack;)Z", false); + mv.visitJumpInsn(IFEQ, l2); + Label l64 = new Label(); + mv.visitLabel(l64); + mv.visitLineNumber(135, l64); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "attachedFuelable", "Lmicdoodle8/mods/galacticraft/api/entity/IFuelable;"); + mv.visitVarInsn(ALOAD, 1); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEINTERFACE, "micdoodle8/mods/galacticraft/api/entity/IFuelable", "addFuel", "(Lnet/minecraftforge/fluids/FluidStack;Z)I", true); + mv.visitVarInsn(ISTORE, 3); + Label l65 = new Label(); + mv.visitLabel(l65); + mv.visitLineNumber(136, l65); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 3); + Label l66 = new Label(); + mv.visitJumpInsn(IFLE, l66); + mv.visitInsn(ICONST_1); + Label l67 = new Label(); + mv.visitJumpInsn(GOTO, l67); + mv.visitLabel(l66); + mv.visitFrame(F_FULL, 6, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, INTEGER, "net/minecraftforge/fluids/FluidStack", INTEGER}, 1, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader"}); + mv.visitInsn(ICONST_0); + mv.visitLabel(l67); + mv.visitFrame(F_FULL, 6, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "net/minecraftforge/fluids/FluidStack", TOP, INTEGER, "net/minecraftforge/fluids/FluidStack", INTEGER}, 2, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", INTEGER}); + mv.visitFieldInsn(PUTFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "loadedFuelLastTick", "Z"); + Label l68 = new Label(); + mv.visitLabel(l68); + mv.visitLineNumber(137, l68); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader", "fuelTank", "Lnet/minecraftforge/fluids/FluidTank;"); + mv.visitVarInsn(ILOAD, 3); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraftforge/fluids/FluidTank", "drain", "(IZ)Lnet/minecraftforge/fluids/FluidStack;", false); + mv.visitInsn(POP); + mv.visitLabel(l2); + mv.visitLineNumber(144, l2); + mv.visitFrame(F_FULL, 1, new Object[] {"micdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader"}, 0, new Object[] {}); + mv.visitInsn(RETURN); + Label l69 = new Label(); + mv.visitLabel(l69); + mv.visitLocalVariable("this", "Lmicdoodle8/mods/galacticraft/core/tile/TileEntityFuelLoader;", null, l0, l69, 0); + mv.visitLocalVariable("liquid", "Lnet/minecraftforge/fluids/FluidStack;", null, l5, l2, 1); + mv.visitLocalVariable("amount", "I", null, l37, l32, 2); + mv.visitLocalVariable("filled", "I", null, l36, l32, 3); + mv.visitLocalVariable("filled", "I", null, l65, l2, 3); + mv.visitLocalVariable("isFuel", "Z", null, l10, l6, 4); + mv.visitLocalVariable("liquidInTank", "Lnet/minecraftforge/fluids/FluidStack;", null, l13, l6, 5); + mv.visitLocalVariable("didFill", "Z", null, l14, l6, 6); + mv.visitLocalVariable("aFuelType", "Lnet/minecraftforge/fluids/Fluid;", null, l20, l18, 7); + mv.visitLocalVariable("var8", "[Lnet/minecraftforge/common/util/ForgeDirection;", null, l35, l32, 4); + mv.visitLocalVariable("dir", "Lnet/minecraftforge/common/util/ForgeDirection;", null, l40, l45, 5); + mv.visitLocalVariable("pad", "L"+aTileEntity+";", null, l41, l45, 6); + mv.visitLocalVariable("mainTile", "L"+aTileEntity+";", null, l44, l42, 7); + mv.visitLocalVariable("liquidInTank", "Lnet/minecraftforge/fluids/FluidStack;", null, l51, l2, 4); + mv.visitLocalVariable("aFuelType", "Lnet/minecraftforge/fluids/Fluid;", null, l56, l54, 5); + mv.visitLocalVariable("aTier", "I", null, l62, l2, 5); + mv.visitMaxs(5, 9); + mv.visitEnd(); + } + } + + public static final class localClassVisitor extends ClassVisitor { + + public localClassVisitor(ClassVisitor cv) { + super(ASM5, cv); + FMLRelaunchLog.log("[GT++ ASM] Galacticraft Fuel_Loader Patch", Level.INFO, "Inspecting Class "+className); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (name.equals("updateEntity")) { + FMLRelaunchLog.log("[GT++ ASM] Galacticraft Fuel_Loader Patch", Level.INFO, "Removing method "+name); + return null; + } + + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements.java new file mode 100644 index 0000000000..2b9729a8a3 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements.java @@ -0,0 +1,1896 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.AnnotationVisitor; +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.common.FMLCommonHandler; +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import net.minecraftforge.common.MinecraftForge; + +public class ClassTransformer_GT_Achievements { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private static boolean mDidRemoveAssLineRecipeAdder = false; + + public ClassTransformer_GT_Achievements(byte[] basicClass) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + + aTempReader.accept(new MethodAdaptor(aTempWriter), 0); + + if (mDidRemoveAssLineRecipeAdder) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Patching GT .09"); + injectMethod(aTempWriter); + patchOnItemPickup09(aTempWriter); + } + else { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Patching GT .08"); + patchOnItemPickup08(aTempWriter); + } + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Valid? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Injecting " + "registerAssAchievement" + "."); + + /** + * Inject new, safer code + */ + + + /*mv = cw.visitMethod(ACC_PUBLIC, "registerAssAchievement", "(Lgregtech/api/util/GT_Recipe;)Lnet/minecraft/stats/Achievement;", null, null); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(291, l3); + mv.visitVarInsn(ALOAD, 1); + Label l4 = new Label(); + mv.visitJumpInsn(IFNONNULL, l4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(292, l5); + mv.visitLdcInsn("Someone tried to register an achievement for an invalid recipe. Please report this to Alkalus."); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/api/objects/Logger", "INFO", "(Ljava/lang/String;)V", false); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(293, l6); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + mv.visitLabel(l4); + mv.visitLineNumber(295, l4); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/util/GT_Recipe", "getOutput", "(I)Lnet/minecraft/item/ItemStack;", false); + Label l7 = new Label(); + mv.visitJumpInsn(IFNONNULL, l7); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(296, l8); + mv.visitLdcInsn("Someone tried to register an achievement for a recipe with null output. Please report this to Alkalus."); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/api/objects/Logger", "INFO", "(Ljava/lang/String;)V", false); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(297, l9); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + mv.visitLabel(l7); + mv.visitLineNumber(299, l7); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/util/GT_Recipe", "getOutput", "(I)Lnet/minecraft/item/ItemStack;", false); + mv.visitVarInsn(ASTORE, 3); + mv.visitLabel(l0); + mv.visitLineNumber(301, l0); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitVarInsn(ASTORE, 2); + mv.visitLabel(l1); + mv.visitLineNumber(302, l1); + Label l10 = new Label(); + mv.visitJumpInsn(GOTO, l10); + mv.visitLabel(l2); + mv.visitLineNumber(303, l2); + mv.visitFrame(F_FULL, 4, new Object[] {"gregtech/loaders/misc/GT_Achievements", "gregtech/api/util/GT_Recipe", TOP, "net/minecraft/item/ItemStack"}, 1, new Object[] {"java/lang/Throwable"}); + mv.visitVarInsn(ASTORE, 4); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(304, l11); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/ItemUtils", "getUnlocalizedItemName", "(Lnet/minecraft/item/ItemStack;)Ljava/lang/String;", false); + mv.visitVarInsn(ASTORE, 2); + mv.visitLabel(l10); + mv.visitLineNumber(306, l10); + mv.visitFrame(F_FULL, 4, new Object[] {"gregtech/loaders/misc/GT_Achievements", "gregtech/api/util/GT_Recipe", "java/lang/String", "net/minecraft/item/ItemStack"}, 0, new Object[] {}); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/loaders/misc/GT_Achievements", "achievementList", "Ljava/util/concurrent/ConcurrentHashMap;"); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", false); + Label l12 = new Label(); + mv.visitJumpInsn(IFNONNULL, l12); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(307, l13); + mv.visitFieldInsn(GETSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + mv.visitInsn(ICONST_1); + mv.visitInsn(IADD); + mv.visitFieldInsn(PUTSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(308, l14); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitIntInsn(BIPUSH, 11); + mv.visitFieldInsn(GETSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + mv.visitInsn(ICONST_5); + mv.visitInsn(IREM); + mv.visitInsn(IADD); + mv.visitInsn(INEG); + mv.visitFieldInsn(GETSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + mv.visitInsn(ICONST_5); + mv.visitInsn(IDIV); + mv.visitIntInsn(BIPUSH, 8); + mv.visitInsn(ISUB); + mv.visitVarInsn(ALOAD, 1); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/util/GT_Recipe", "getOutput", "(I)Lnet/minecraft/item/ItemStack;", false); + mv.visitFieldInsn(GETSTATIC, "net/minecraft/stats/AchievementList", "openInventory", "Lnet/minecraft/stats/Achievement;"); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "registerAchievement", "(Ljava/lang/String;IILnet/minecraft/item/ItemStack;Lnet/minecraft/stats/Achievement;Z)Lnet/minecraft/stats/Achievement;", false); + mv.visitInsn(ARETURN); + mv.visitLabel(l12); + mv.visitLineNumber(310, l12); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLocalVariable("this", "Lgregtech/loaders/misc/GT_Achievements;", null, l3, l15, 0); + mv.visitLocalVariable("recipe", "Lgregtech/api/util/GT_Recipe;", null, l3, l15, 1); + mv.visitLocalVariable("aSafeUnlocalName", "Ljava/lang/String;", null, l1, l2, 2); + mv.visitLocalVariable("aSafeUnlocalName", "Ljava/lang/String;", null, l10, l15, 2); + mv.visitLocalVariable("aStack", "Lnet/minecraft/item/ItemStack;", null, l0, l15, 3); + mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, l11, l10, 4); + mv.visitMaxs(7, 5); + mv.visitEnd();*/ + + //Lets just static call my replacement function + mv = cw.visitMethod(ACC_PUBLIC, "registerAssAchievement", "(Lgregtech/api/util/GT_Recipe;)Lnet/minecraft/stats/Achievement;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(291, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/xmod/gregtech/loaders/misc/AssLineAchievements", "registerAssAchievement", "(Lgregtech/api/util/GT_Recipe;)Lnet/minecraft/stats/Achievement;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lgregtech/loaders/misc/GT_Achievements;", null, l0, l1, 0); + mv.visitLocalVariable("recipe", "Lgregtech/api/util/GT_Recipe;", null, l0, l1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); + + didInject = true; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + + + public boolean patchOnItemPickup08(ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Injecting " + "onItemPickup" + "."); + + AnnotationVisitor av0; + mv = cw.visitMethod(ACC_PUBLIC, "onItemPickup", "(Lnet/minecraftforge/event/entity/player/EntityItemPickupEvent;)V", null, null); + av0 = mv.visitAnnotation("Lcpw/mods/fml/common/eventhandler/SubscribeEvent;", true); + av0.visitEnd(); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(418, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/event/entity/player/EntityItemPickupEvent", "entityPlayer", "Lnet/minecraft/entity/player/EntityPlayer;"); + mv.visitVarInsn(ASTORE, 2); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(419, l1); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/event/entity/player/EntityItemPickupEvent", "item", "Lnet/minecraft/entity/item/EntityItem;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/entity/item/EntityItem", "getEntityItem", "()Lnet/minecraft/item/ItemStack;", false); + mv.visitVarInsn(ASTORE, 3); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(420, l2); + mv.visitVarInsn(ALOAD, 2); + Label l3 = new Label(); + mv.visitJumpInsn(IFNULL, l3); + mv.visitVarInsn(ALOAD, 3); + Label l4 = new Label(); + mv.visitJumpInsn(IFNONNULL, l4); + mv.visitLabel(l3); + mv.visitLineNumber(421, l3); + mv.visitFrame(F_APPEND,2, new Object[] {"net/minecraft/entity/player/EntityPlayer", "net/minecraft/item/ItemStack"}, 0, null); + mv.visitInsn(RETURN); + mv.visitLabel(l4); + mv.visitLineNumber(424, l4); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "gregtech/api/util/GT_OreDictUnificator", "getItemData", "(Lnet/minecraft/item/ItemStack;)Lgregtech/api/objects/ItemData;", false); + mv.visitVarInsn(ASTORE, 4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(425, l5); + mv.visitVarInsn(ALOAD, 4); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(426, l7); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "dust", "Lgregtech/api/enums/OrePrefixes;"); + Label l8 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l8); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(427, l9); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mMaterial", "Lgregtech/api/objects/MaterialStack;"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Lutetium", "Lgregtech/api/enums/Materials;"); + Label l10 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l10); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(428, l11); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("newmetal"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l10); + mv.visitLineNumber(430, l10); + mv.visitFrame(F_APPEND,1, new Object[] {"gregtech/api/objects/ItemData"}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("cleandust"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(431, l12); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l8); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "ore", "Lgregtech/api/enums/OrePrefixes;"); + Label l13 = new Label(); + mv.visitJumpInsn(IF_ACMPEQ, l13); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "oreBlackgranite", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitJumpInsn(IF_ACMPEQ, l13); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "oreEndstone", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitJumpInsn(IF_ACMPEQ, l13); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(432, l14); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "oreNetherrack", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitJumpInsn(IF_ACMPEQ, l13); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "oreRedgranite", "Lgregtech/api/enums/OrePrefixes;"); + Label l15 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l15); + mv.visitLabel(l13); + mv.visitLineNumber(433, l13); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 5); + Label l16 = new Label(); + mv.visitLabel(l16); + Label l17 = new Label(); + mv.visitJumpInsn(GOTO, l17); + Label l18 = new Label(); + mv.visitLabel(l18); + mv.visitLineNumber(434, l18); + mv.visitFrame(F_APPEND,1, new Object[] {INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitVarInsn(ILOAD, 5); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/objects/MaterialStack"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/enums/Materials", "name", "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l19 = new Label(); + mv.visitLabel(l19); + mv.visitLineNumber(435, l19); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitVarInsn(ILOAD, 5); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/objects/MaterialStack"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "AnyIron", "Lgregtech/api/enums/Materials;"); + Label l20 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l20); + Label l21 = new Label(); + mv.visitLabel(l21); + mv.visitLineNumber(436, l21); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("iron"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l20); + mv.visitLineNumber(433, l20); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitIincInsn(5, 1); + mv.visitLabel(l17); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ILOAD, 5); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "size", "()I", false); + mv.visitJumpInsn(IF_ICMPLT, l18); + Label l22 = new Label(); + mv.visitLabel(l22); + mv.visitLineNumber(439, l22); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l15); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "crushed", "Lgregtech/api/enums/OrePrefixes;"); + Label l23 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l23); + Label l24 = new Label(); + mv.visitLabel(l24); + mv.visitLineNumber(440, l24); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("crushed"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l25 = new Label(); + mv.visitLabel(l25); + mv.visitLineNumber(441, l25); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l23); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "crushedPurified", "Lgregtech/api/enums/OrePrefixes;"); + Label l26 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l26); + Label l27 = new Label(); + mv.visitLabel(l27); + mv.visitLineNumber(442, l27); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("washing"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l28 = new Label(); + mv.visitLabel(l28); + mv.visitLineNumber(443, l28); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l26); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "crushedCentrifuged", "Lgregtech/api/enums/OrePrefixes;"); + Label l29 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l29); + Label l30 = new Label(); + mv.visitLabel(l30); + mv.visitLineNumber(444, l30); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("spinit"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l31 = new Label(); + mv.visitLabel(l31); + mv.visitLineNumber(445, l31); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l29); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mMaterial", "Lgregtech/api/objects/MaterialStack;"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Steel", "Lgregtech/api/enums/Materials;"); + Label l32 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l32); + Label l33 = new Label(); + mv.visitLabel(l33); + mv.visitLineNumber(446, l33); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "ingot", "Lgregtech/api/enums/OrePrefixes;"); + Label l34 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l34); + mv.visitVarInsn(ALOAD, 3); + mv.visitFieldInsn(GETFIELD, "net/minecraft/item/ItemStack", "stackSize", "I"); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getMaxStackSize", "()I", false); + mv.visitJumpInsn(IF_ICMPNE, l34); + Label l35 = new Label(); + mv.visitLabel(l35); + mv.visitLineNumber(447, l35); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("steel"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l36 = new Label(); + mv.visitLabel(l36); + mv.visitLineNumber(448, l36); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l34); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "nugget", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitJumpInsn(IF_ACMPNE, l6); + mv.visitLdcInsn("Thaumcraft"); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/Loader", "isModLoaded", "(Ljava/lang/String;)Z", false); + mv.visitJumpInsn(IFEQ, l6); + Label l37 = new Label(); + mv.visitLabel(l37); + mv.visitLineNumber(449, l37); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/entity/player/EntityPlayer", "getDisplayName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("GT_IRON_TO_STEEL"); + mv.visitMethodInsn(INVOKESTATIC, "thaumcraft/api/ThaumcraftApiHelper", "isResearchComplete", "(Ljava/lang/String;Ljava/lang/String;)Z", false); + mv.visitJumpInsn(IFEQ, l6); + Label l38 = new Label(); + mv.visitLabel(l38); + mv.visitLineNumber(450, l38); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("steel"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l39 = new Label(); + mv.visitLabel(l39); + mv.visitLineNumber(453, l39); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l32); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "circuit", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitJumpInsn(IF_ACMPNE, l6); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mMaterial", "Lgregtech/api/objects/MaterialStack;"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Advanced", "Lgregtech/api/enums/Materials;"); + mv.visitJumpInsn(IF_ACMPNE, l6); + Label l40 = new Label(); + mv.visitLabel(l40); + mv.visitLineNumber(454, l40); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("stepforward"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l6); + mv.visitLineNumber(457, l6); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem."); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z", false); + Label l41 = new Label(); + mv.visitJumpInsn(IFEQ, l41); + Label l42 = new Label(); + mv.visitLabel(l42); + mv.visitLineNumber(458, l42); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32500"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l43 = new Label(); + mv.visitJumpInsn(IFEQ, l43); + Label l44 = new Label(); + mv.visitLabel(l44); + mv.visitLineNumber(459, l44); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestlead"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l45 = new Label(); + mv.visitLabel(l45); + mv.visitLineNumber(460, l45); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l43); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32501"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l46 = new Label(); + mv.visitJumpInsn(IFEQ, l46); + Label l47 = new Label(); + mv.visitLabel(l47); + mv.visitLineNumber(461, l47); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestsilver"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l48 = new Label(); + mv.visitLabel(l48); + mv.visitLineNumber(462, l48); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l46); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32503"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l49 = new Label(); + mv.visitJumpInsn(IFEQ, l49); + Label l50 = new Label(); + mv.visitLabel(l50); + mv.visitLineNumber(463, l50); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestiron"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l51 = new Label(); + mv.visitLabel(l51); + mv.visitLineNumber(464, l51); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l49); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32504"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l52 = new Label(); + mv.visitJumpInsn(IFEQ, l52); + Label l53 = new Label(); + mv.visitLabel(l53); + mv.visitLineNumber(465, l53); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestgold"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l54 = new Label(); + mv.visitLabel(l54); + mv.visitLineNumber(466, l54); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l52); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32530"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l55 = new Label(); + mv.visitJumpInsn(IFEQ, l55); + Label l56 = new Label(); + mv.visitLabel(l56); + mv.visitLineNumber(467, l56); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestcopper"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l57 = new Label(); + mv.visitLabel(l57); + mv.visitLineNumber(468, l57); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l55); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32540"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l58 = new Label(); + mv.visitJumpInsn(IFEQ, l58); + Label l59 = new Label(); + mv.visitLabel(l59); + mv.visitLineNumber(469, l59); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havesttin"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l60 = new Label(); + mv.visitLabel(l60); + mv.visitLineNumber(470, l60); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l58); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32510"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l61 = new Label(); + mv.visitJumpInsn(IFEQ, l61); + Label l62 = new Label(); + mv.visitLabel(l62); + mv.visitLineNumber(471, l62); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestoil"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l63 = new Label(); + mv.visitLabel(l63); + mv.visitLineNumber(472, l63); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l61); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32511"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l64 = new Label(); + mv.visitJumpInsn(IFEQ, l64); + Label l65 = new Label(); + mv.visitLabel(l65); + mv.visitLineNumber(473, l65); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestemeralds"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l66 = new Label(); + mv.visitLabel(l66); + mv.visitLineNumber(474, l66); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l64); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32706"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l67 = new Label(); + mv.visitJumpInsn(IFEQ, l67); + Label l68 = new Label(); + mv.visitLabel(l68); + mv.visitLineNumber(475, l68); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("energyflow"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l69 = new Label(); + mv.visitLabel(l69); + mv.visitLineNumber(476, l69); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l67); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32702"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l70 = new Label(); + mv.visitJumpInsn(IFEQ, l70); + Label l71 = new Label(); + mv.visitLabel(l71); + mv.visitLineNumber(477, l71); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("bettercircuits"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l72 = new Label(); + mv.visitLabel(l72); + mv.visitLineNumber(478, l72); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l70); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32707"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l73 = new Label(); + mv.visitJumpInsn(IFEQ, l73); + Label l74 = new Label(); + mv.visitLabel(l74); + mv.visitLineNumber(479, l74); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("datasaving"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l75 = new Label(); + mv.visitLabel(l75); + mv.visitLineNumber(480, l75); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l73); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32597"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l76 = new Label(); + mv.visitJumpInsn(IFEQ, l76); + Label l77 = new Label(); + mv.visitLabel(l77); + mv.visitLineNumber(481, l77); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("orbs"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l78 = new Label(); + mv.visitLabel(l78); + mv.visitLineNumber(482, l78); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l76); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32599"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l79 = new Label(); + mv.visitJumpInsn(IFEQ, l79); + Label l80 = new Label(); + mv.visitLabel(l80); + mv.visitLineNumber(483, l80); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("thatspower"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l81 = new Label(); + mv.visitLabel(l81); + mv.visitLineNumber(484, l81); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l79); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32598"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l82 = new Label(); + mv.visitJumpInsn(IFEQ, l82); + Label l83 = new Label(); + mv.visitLabel(l83); + mv.visitLineNumber(485, l83); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("luck"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l84 = new Label(); + mv.visitLabel(l84); + mv.visitLineNumber(486, l84); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l82); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32749"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l85 = new Label(); + mv.visitJumpInsn(IFEQ, l85); + Label l86 = new Label(); + mv.visitLabel(l86); + mv.visitLineNumber(487, l86); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("closeit"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l87 = new Label(); + mv.visitLabel(l87); + mv.visitLineNumber(488, l87); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l85); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32730"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l88 = new Label(); + mv.visitJumpInsn(IFEQ, l88); + Label l89 = new Label(); + mv.visitLabel(l89); + mv.visitLineNumber(489, l89); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("manipulation"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l90 = new Label(); + mv.visitLabel(l90); + mv.visitLineNumber(490, l90); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l88); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32729"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l91 = new Label(); + mv.visitJumpInsn(IFEQ, l91); + Label l92 = new Label(); + mv.visitLabel(l92); + mv.visitLineNumber(491, l92); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("filterregulate"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l93 = new Label(); + mv.visitLabel(l93); + mv.visitLineNumber(492, l93); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l91); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32605"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l94 = new Label(); + mv.visitJumpInsn(IFEQ, l94); + Label l95 = new Label(); + mv.visitLabel(l95); + mv.visitLineNumber(493, l95); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("whatnow"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l96 = new Label(); + mv.visitLabel(l96); + mv.visitLineNumber(494, l96); + mv.visitJumpInsn(GOTO, l41); + mv.visitLabel(l94); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.Thoriumcell"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + mv.visitJumpInsn(IFEQ, l41); + Label l97 = new Label(); + mv.visitLabel(l97); + mv.visitLineNumber(495, l97); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("newfuel"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l41); + mv.visitLineNumber(498, l41); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + Label l98 = new Label(); + mv.visitLabel(l98); + mv.visitLocalVariable("this", "Lgregtech/loaders/misc/GT_Achievements;", null, l0, l98, 0); + mv.visitLocalVariable("event", "Lnet/minecraftforge/event/entity/player/EntityItemPickupEvent;", null, l0, l98, 1); + mv.visitLocalVariable("player", "Lnet/minecraft/entity/player/EntityPlayer;", null, l1, l98, 2); + mv.visitLocalVariable("stack", "Lnet/minecraft/item/ItemStack;", null, l2, l98, 3); + mv.visitLocalVariable("data", "Lgregtech/api/objects/ItemData;", null, l5, l98, 4); + mv.visitLocalVariable("i", "I", null, l16, l22, 5); + mv.visitMaxs(4, 6); + mv.visitEnd(); + + + didInject = true; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + + public boolean patchOnItemPickup09(ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Injecting " + "onItemPickup" + "."); + + /** + * Inject new, safer code + */ + AnnotationVisitor av0; + mv = cw.visitMethod(ACC_PUBLIC, "onItemPickup", "(Lnet/minecraftforge/event/entity/player/EntityItemPickupEvent;)V", null, null); + av0 = mv.visitAnnotation("Lcpw/mods/fml/common/eventhandler/SubscribeEvent;", true); + av0.visitEnd(); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(546, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/event/entity/player/EntityItemPickupEvent", "entityPlayer", "Lnet/minecraft/entity/player/EntityPlayer;"); + mv.visitVarInsn(ASTORE, 2); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(547, l1); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/event/entity/player/EntityItemPickupEvent", "item", "Lnet/minecraft/entity/item/EntityItem;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/entity/item/EntityItem", "getEntityItem", "()Lnet/minecraft/item/ItemStack;", false); + mv.visitVarInsn(ASTORE, 3); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(548, l2); + mv.visitVarInsn(ALOAD, 2); + Label l3 = new Label(); + mv.visitJumpInsn(IFNULL, l3); + mv.visitVarInsn(ALOAD, 3); + Label l4 = new Label(); + mv.visitJumpInsn(IFNONNULL, l4); + mv.visitLabel(l3); + mv.visitLineNumber(549, l3); + mv.visitFrame(F_APPEND,2, new Object[] {"net/minecraft/entity/player/EntityPlayer", "net/minecraft/item/ItemStack"}, 0, null); + mv.visitInsn(RETURN); + mv.visitLabel(l4); + mv.visitLineNumber(551, l4); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "gregtech/api/util/GT_OreDictUnificator", "getItemData", "(Lnet/minecraft/item/ItemStack;)Lgregtech/api/objects/ItemData;", false); + mv.visitVarInsn(ASTORE, 4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(552, l5); + mv.visitVarInsn(ALOAD, 4); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitJumpInsn(IFNULL, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(553, l7); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "dust", "Lgregtech/api/enums/OrePrefixes;"); + Label l8 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l8); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(554, l9); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mMaterial", "Lgregtech/api/objects/MaterialStack;"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Lutetium", "Lgregtech/api/enums/Materials;"); + Label l10 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l10); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(555, l11); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("newmetal"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l10); + mv.visitLineNumber(557, l10); + mv.visitFrame(F_APPEND,1, new Object[] {"gregtech/api/objects/ItemData"}, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mMaterial", "Lgregtech/api/objects/MaterialStack;"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Gunpowder", "Lgregtech/api/enums/Materials;"); + mv.visitJumpInsn(IF_ACMPEQ, l6); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(558, l12); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("cleandust"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(560, l13); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l8); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/enums/OrePrefixes", "name", "()Ljava/lang/String;", false); + mv.visitLdcInsn("ore"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z", false); + Label l14 = new Label(); + mv.visitJumpInsn(IFEQ, l14); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(561, l15); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "size", "()I", false); + mv.visitVarInsn(ISTORE, 5); + Label l16 = new Label(); + mv.visitLabel(l16); + mv.visitLineNumber(562, l16); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ISTORE, 6); + Label l17 = new Label(); + mv.visitLabel(l17); + Label l18 = new Label(); + mv.visitJumpInsn(GOTO, l18); + Label l19 = new Label(); + mv.visitLabel(l19); + mv.visitLineNumber(563, l19); + mv.visitFrame(F_APPEND,2, new Object[] {INTEGER, INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitVarInsn(ILOAD, 6); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/objects/MaterialStack"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/enums/Materials", "mName", "Ljava/lang/String;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l20 = new Label(); + mv.visitLabel(l20); + mv.visitLineNumber(564, l20); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitVarInsn(ILOAD, 6); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/objects/MaterialStack"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Iron", "Lgregtech/api/enums/Materials;"); + Label l21 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l21); + Label l22 = new Label(); + mv.visitLabel(l22); + mv.visitLineNumber(565, l22); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("iron"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l21); + mv.visitLineNumber(567, l21); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitVarInsn(ILOAD, 6); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/objects/MaterialStack"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Copper", "Lgregtech/api/enums/Materials;"); + Label l23 = new Label(); + mv.visitJumpInsn(IF_ACMPEQ, l23); + mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/objects/ItemData", "getAllMaterialStacks", "()Ljava/util/ArrayList;", false); + mv.visitVarInsn(ILOAD, 6); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList", "get", "(I)Ljava/lang/Object;", false); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/objects/MaterialStack"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Tin", "Lgregtech/api/enums/Materials;"); + Label l24 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l24); + mv.visitLabel(l23); + mv.visitLineNumber(568, l23); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/event/entity/player/EntityItemPickupEvent", "entityPlayer", "Lnet/minecraft/entity/player/EntityPlayer;"); + mv.visitLdcInsn("mineOre"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l24); + mv.visitLineNumber(562, l24); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitIincInsn(6, 1); + mv.visitLabel(l18); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ILOAD, 6); + mv.visitVarInsn(ILOAD, 5); + mv.visitJumpInsn(IF_ICMPLT, l19); + Label l25 = new Label(); + mv.visitLabel(l25); + mv.visitLineNumber(572, l25); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l14); + mv.visitFrame(F_CHOP,2, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "crushed", "Lgregtech/api/enums/OrePrefixes;"); + Label l26 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l26); + Label l27 = new Label(); + mv.visitLabel(l27); + mv.visitLineNumber(573, l27); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("crushed"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l28 = new Label(); + mv.visitLabel(l28); + mv.visitLineNumber(574, l28); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l26); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "crushedPurified", "Lgregtech/api/enums/OrePrefixes;"); + Label l29 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l29); + Label l30 = new Label(); + mv.visitLabel(l30); + mv.visitLineNumber(575, l30); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("washing"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l31 = new Label(); + mv.visitLabel(l31); + mv.visitLineNumber(576, l31); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l29); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "crushedCentrifuged", "Lgregtech/api/enums/OrePrefixes;"); + Label l32 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l32); + Label l33 = new Label(); + mv.visitLabel(l33); + mv.visitLineNumber(577, l33); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("spinit"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l34 = new Label(); + mv.visitLabel(l34); + mv.visitLineNumber(578, l34); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l32); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mMaterial", "Lgregtech/api/objects/MaterialStack;"); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/MaterialStack", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/Materials", "Steel", "Lgregtech/api/enums/Materials;"); + mv.visitJumpInsn(IF_ACMPNE, l6); + Label l35 = new Label(); + mv.visitLabel(l35); + mv.visitLineNumber(579, l35); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "ingot", "Lgregtech/api/enums/OrePrefixes;"); + Label l36 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l36); + mv.visitVarInsn(ALOAD, 3); + mv.visitFieldInsn(GETFIELD, "net/minecraft/item/ItemStack", "stackSize", "I"); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getMaxStackSize", "()I", false); + mv.visitJumpInsn(IF_ICMPNE, l36); + Label l37 = new Label(); + mv.visitLabel(l37); + mv.visitLineNumber(580, l37); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("steel"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l38 = new Label(); + mv.visitLabel(l38); + mv.visitLineNumber(581, l38); + mv.visitJumpInsn(GOTO, l6); + mv.visitLabel(l36); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitFieldInsn(GETFIELD, "gregtech/api/objects/ItemData", "mPrefix", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/enums/OrePrefixes", "nugget", "Lgregtech/api/enums/OrePrefixes;"); + mv.visitJumpInsn(IF_ACMPNE, l6); + mv.visitLdcInsn("Thaumcraft"); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/Loader", "isModLoaded", "(Ljava/lang/String;)Z", false); + mv.visitJumpInsn(IFEQ, l6); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/entity/player/EntityPlayer", "getDisplayName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("GT_IRON_TO_STEEL"); + mv.visitMethodInsn(INVOKESTATIC, "thaumcraft/api/ThaumcraftApiHelper", "isResearchComplete", "(Ljava/lang/String;Ljava/lang/String;)Z", false); + mv.visitJumpInsn(IFEQ, l6); + Label l39 = new Label(); + mv.visitLabel(l39); + mv.visitLineNumber(582, l39); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("steel"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l6); + mv.visitLineNumber(589, l6); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem."); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "startsWith", "(Ljava/lang/String;)Z", false); + Label l40 = new Label(); + mv.visitJumpInsn(IFEQ, l40); + Label l41 = new Label(); + mv.visitLabel(l41); + mv.visitLineNumber(590, l41); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32500"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l42 = new Label(); + mv.visitJumpInsn(IFEQ, l42); + Label l43 = new Label(); + mv.visitLabel(l43); + mv.visitLineNumber(591, l43); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestlead"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l44 = new Label(); + mv.visitLabel(l44); + mv.visitLineNumber(592, l44); + Label l45 = new Label(); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l42); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32501"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l46 = new Label(); + mv.visitJumpInsn(IFEQ, l46); + Label l47 = new Label(); + mv.visitLabel(l47); + mv.visitLineNumber(593, l47); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestsilver"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l48 = new Label(); + mv.visitLabel(l48); + mv.visitLineNumber(594, l48); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l46); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32503"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l49 = new Label(); + mv.visitJumpInsn(IFEQ, l49); + Label l50 = new Label(); + mv.visitLabel(l50); + mv.visitLineNumber(595, l50); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestiron"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l51 = new Label(); + mv.visitLabel(l51); + mv.visitLineNumber(596, l51); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l49); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32504"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l52 = new Label(); + mv.visitJumpInsn(IFEQ, l52); + Label l53 = new Label(); + mv.visitLabel(l53); + mv.visitLineNumber(597, l53); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestgold"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l54 = new Label(); + mv.visitLabel(l54); + mv.visitLineNumber(598, l54); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l52); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32530"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l55 = new Label(); + mv.visitJumpInsn(IFEQ, l55); + Label l56 = new Label(); + mv.visitLabel(l56); + mv.visitLineNumber(599, l56); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestcopper"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l57 = new Label(); + mv.visitLabel(l57); + mv.visitLineNumber(600, l57); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l55); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32540"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l58 = new Label(); + mv.visitJumpInsn(IFEQ, l58); + Label l59 = new Label(); + mv.visitLabel(l59); + mv.visitLineNumber(601, l59); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havesttin"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l60 = new Label(); + mv.visitLabel(l60); + mv.visitLineNumber(602, l60); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l58); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32510"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l61 = new Label(); + mv.visitJumpInsn(IFEQ, l61); + Label l62 = new Label(); + mv.visitLabel(l62); + mv.visitLineNumber(603, l62); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestoil"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l63 = new Label(); + mv.visitLabel(l63); + mv.visitLineNumber(604, l63); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l61); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.02.32511"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l64 = new Label(); + mv.visitJumpInsn(IFEQ, l64); + Label l65 = new Label(); + mv.visitLabel(l65); + mv.visitLineNumber(605, l65); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("havestemeralds"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l66 = new Label(); + mv.visitLabel(l66); + mv.visitLineNumber(606, l66); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l64); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.03.32082"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l67 = new Label(); + mv.visitJumpInsn(IFEQ, l67); + Label l68 = new Label(); + mv.visitLabel(l68); + mv.visitLineNumber(607, l68); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("energyflow"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l69 = new Label(); + mv.visitLabel(l69); + mv.visitLineNumber(608, l69); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l67); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32702"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l70 = new Label(); + mv.visitJumpInsn(IFEQ, l70); + Label l71 = new Label(); + mv.visitLabel(l71); + mv.visitLineNumber(609, l71); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("bettercircuits"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l72 = new Label(); + mv.visitLabel(l72); + mv.visitLineNumber(610, l72); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l70); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32707"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l73 = new Label(); + mv.visitJumpInsn(IFEQ, l73); + Label l74 = new Label(); + mv.visitLabel(l74); + mv.visitLineNumber(611, l74); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("datasaving"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l75 = new Label(); + mv.visitLabel(l75); + mv.visitLineNumber(612, l75); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l73); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32597"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l76 = new Label(); + mv.visitJumpInsn(IFEQ, l76); + Label l77 = new Label(); + mv.visitLabel(l77); + mv.visitLineNumber(613, l77); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("orbs"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l78 = new Label(); + mv.visitLabel(l78); + mv.visitLineNumber(614, l78); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l76); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32599"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l79 = new Label(); + mv.visitJumpInsn(IFEQ, l79); + Label l80 = new Label(); + mv.visitLabel(l80); + mv.visitLineNumber(615, l80); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("thatspower"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l81 = new Label(); + mv.visitLabel(l81); + mv.visitLineNumber(616, l81); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l79); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32598"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l82 = new Label(); + mv.visitJumpInsn(IFEQ, l82); + Label l83 = new Label(); + mv.visitLabel(l83); + mv.visitLineNumber(617, l83); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("luck"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l84 = new Label(); + mv.visitLabel(l84); + mv.visitLineNumber(618, l84); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l82); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32749"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l85 = new Label(); + mv.visitJumpInsn(IFEQ, l85); + Label l86 = new Label(); + mv.visitLabel(l86); + mv.visitLineNumber(619, l86); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("closeit"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l87 = new Label(); + mv.visitLabel(l87); + mv.visitLineNumber(620, l87); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l85); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32730"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l88 = new Label(); + mv.visitJumpInsn(IFEQ, l88); + Label l89 = new Label(); + mv.visitLabel(l89); + mv.visitLineNumber(621, l89); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("manipulation"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l90 = new Label(); + mv.visitLabel(l90); + mv.visitLineNumber(622, l90); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l88); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32729"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l91 = new Label(); + mv.visitJumpInsn(IFEQ, l91); + Label l92 = new Label(); + mv.visitLabel(l92); + mv.visitLineNumber(623, l92); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("filterregulate"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l93 = new Label(); + mv.visitLabel(l93); + mv.visitLineNumber(624, l93); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l91); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32605"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l94 = new Label(); + mv.visitJumpInsn(IFEQ, l94); + Label l95 = new Label(); + mv.visitLabel(l95); + mv.visitLineNumber(625, l95); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("whatnow"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l96 = new Label(); + mv.visitLabel(l96); + mv.visitLineNumber(626, l96); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l94); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32736"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l97 = new Label(); + mv.visitJumpInsn(IFEQ, l97); + Label l98 = new Label(); + mv.visitLabel(l98); + mv.visitLineNumber(627, l98); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("zpmage"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l99 = new Label(); + mv.visitLabel(l99); + mv.visitLineNumber(628, l99); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l97); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32737"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l100 = new Label(); + mv.visitJumpInsn(IFEQ, l100); + Label l101 = new Label(); + mv.visitLabel(l101); + mv.visitLineNumber(629, l101); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("uvage"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l102 = new Label(); + mv.visitLabel(l102); + mv.visitLineNumber(630, l102); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l100); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.03.32030"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l103 = new Label(); + mv.visitJumpInsn(IFEQ, l103); + Label l104 = new Label(); + mv.visitLabel(l104); + mv.visitLineNumber(631, l104); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("gtmonosilicon"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l105 = new Label(); + mv.visitLabel(l105); + mv.visitLineNumber(632, l105); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l103); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.03.32036"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l106 = new Label(); + mv.visitJumpInsn(IFEQ, l106); + Label l107 = new Label(); + mv.visitLabel(l107); + mv.visitLineNumber(633, l107); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("gtlogicwafer"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l108 = new Label(); + mv.visitLabel(l108); + mv.visitLineNumber(634, l108); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l106); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32701"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l109 = new Label(); + mv.visitJumpInsn(IFEQ, l109); + Label l110 = new Label(); + mv.visitLabel(l110); + mv.visitLineNumber(635, l110); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("gtlogiccircuit"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l111 = new Label(); + mv.visitLabel(l111); + mv.visitLineNumber(636, l111); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l109); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.03.32085"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l112 = new Label(); + mv.visitJumpInsn(IFEQ, l112); + Label l113 = new Label(); + mv.visitLabel(l113); + mv.visitLineNumber(637, l113); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("gtquantumprocessor"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l114 = new Label(); + mv.visitLabel(l114); + mv.visitLineNumber(638, l114); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l112); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.03.32089"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l115 = new Label(); + mv.visitJumpInsn(IFEQ, l115); + Label l116 = new Label(); + mv.visitLabel(l116); + mv.visitLineNumber(639, l116); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("gtcrystalprocessor"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l117 = new Label(); + mv.visitLabel(l117); + mv.visitLineNumber(640, l117); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l115); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.03.32092"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l118 = new Label(); + mv.visitJumpInsn(IFEQ, l118); + Label l119 = new Label(); + mv.visitLabel(l119); + mv.visitLineNumber(641, l119); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("gtwetware"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l120 = new Label(); + mv.visitLabel(l120); + mv.visitLineNumber(642, l120); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l118); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.03.32095"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l121 = new Label(); + mv.visitJumpInsn(IFEQ, l121); + Label l122 = new Label(); + mv.visitLabel(l122); + mv.visitLineNumber(643, l122); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("gtwetmain"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l123 = new Label(); + mv.visitLabel(l123); + mv.visitLineNumber(644, l123); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l121); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32736"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l124 = new Label(); + mv.visitJumpInsn(IFEQ, l124); + Label l125 = new Label(); + mv.visitLabel(l125); + mv.visitLineNumber(645, l125); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("zpmage"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l126 = new Label(); + mv.visitLabel(l126); + mv.visitLineNumber(646, l126); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l124); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.metaitem.01.32737"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + mv.visitJumpInsn(IFEQ, l45); + Label l127 = new Label(); + mv.visitLabel(l127); + mv.visitLineNumber(647, l127); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("uvage"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l128 = new Label(); + mv.visitLabel(l128); + mv.visitLineNumber(649, l128); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l40); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("gt.Thoriumcell"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + Label l129 = new Label(); + mv.visitJumpInsn(IFEQ, l129); + Label l130 = new Label(); + mv.visitLabel(l130); + mv.visitLineNumber(650, l130); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("newfuel"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l131 = new Label(); + mv.visitLabel(l131); + mv.visitLineNumber(651, l131); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l129); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + mv.visitFieldInsn(GETSTATIC, "ic2/core/Ic2Items", "quantumBodyarmor", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + Label l132 = new Label(); + mv.visitJumpInsn(IF_ACMPEQ, l132); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + mv.visitFieldInsn(GETSTATIC, "ic2/core/Ic2Items", "quantumBoots", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + mv.visitJumpInsn(IF_ACMPEQ, l132); + Label l133 = new Label(); + mv.visitLabel(l133); + mv.visitLineNumber(652, l133); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + mv.visitFieldInsn(GETSTATIC, "ic2/core/Ic2Items", "quantumHelmet", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + mv.visitJumpInsn(IF_ACMPEQ, l132); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + mv.visitFieldInsn(GETSTATIC, "ic2/core/Ic2Items", "quantumLeggings", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getItem", "()Lnet/minecraft/item/Item;", false); + Label l134 = new Label(); + mv.visitJumpInsn(IF_ACMPNE, l134); + mv.visitLabel(l132); + mv.visitLineNumber(653, l132); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("buildQArmor"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + Label l135 = new Label(); + mv.visitLabel(l135); + mv.visitLineNumber(654, l135); + mv.visitJumpInsn(GOTO, l45); + mv.visitLabel(l134); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", "getUnlocalizedName", "()Ljava/lang/String;", false); + mv.visitLdcInsn("ic2.itemPartCircuitAdv"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); + mv.visitJumpInsn(IFEQ, l45); + Label l136 = new Label(); + mv.visitLabel(l136); + mv.visitLineNumber(655, l136); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitLdcInsn("stepforward"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "issueAchievement", "(Lnet/minecraft/entity/player/EntityPlayer;Ljava/lang/String;)V", false); + mv.visitLabel(l45); + mv.visitLineNumber(657, l45); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + Label l137 = new Label(); + mv.visitLabel(l137); + mv.visitLocalVariable("this", "Lgregtech/loaders/misc/GT_Achievements;", null, l0, l137, 0); + mv.visitLocalVariable("event", "Lnet/minecraftforge/event/entity/player/EntityItemPickupEvent;", null, l0, l137, 1); + mv.visitLocalVariable("player", "Lnet/minecraft/entity/player/EntityPlayer;", null, l1, l137, 2); + mv.visitLocalVariable("stack", "Lnet/minecraft/item/ItemStack;", null, l2, l137, 3); + mv.visitLocalVariable("data", "Lgregtech/api/objects/ItemData;", null, l5, l137, 4); + mv.visitLocalVariable("data_getAllMaterialStacks_sS", "I", null, l16, l25, 5); + mv.visitLocalVariable("i", "I", null, l17, l25, 6); + mv.visitMaxs(4, 7); + mv.visitEnd(); + + didInject = true; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + + + + + + + + public class MethodAdaptor extends ClassVisitor { + + public MethodAdaptor(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + if (name.equals("registerAssAchievement") || name.equals("onItemPickup")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, + "Found method " + name + ", removing."); + methodVisitor = null; + if (name.equals("registerAssAchievement")) { + mDidRemoveAssLineRecipeAdder = true; + } + } else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements_CrashFix.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements_CrashFix.java new file mode 100644 index 0000000000..fb297ed76e --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Achievements_CrashFix.java @@ -0,0 +1,218 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; +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_GT_Achievements_CrashFix { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private final boolean mObfuscated; + private static boolean mDidRemoveAssLineRecipeAdder = false; + + public ClassTransformer_GT_Achievements_CrashFix(byte[] basicClass, boolean obfuscated) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + mObfuscated = obfuscated; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + + aTempReader.accept(new MethodAdaptor(aTempWriter), 0); + + if (mDidRemoveAssLineRecipeAdder) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Patching GT .09"); + injectMethod(aTempWriter); + } + else { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Patch not required, skipping."); + } + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Valid? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Injecting " + "registerAssAchievement" + ". Obfuscated? "+mObfuscated); + + /** + * Inject new, safer code + */ + + mv = cw.visitMethod(ACC_PUBLIC, "registerAssAchievement", "(Lgregtech/api/util/GT_Recipe;)Lnet/minecraft/stats/Achievement;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(293, l0); + mv.visitVarInsn(ALOAD, 1); + Label l1 = new Label(); + mv.visitJumpInsn(IFNONNULL, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(294, l2); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("GTPP_MOD: Someone tried to register an achievement for an invalid recipe. Please report this to Alkalus."); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(295, l3); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + mv.visitLabel(l1); + mv.visitLineNumber(297, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/util/GT_Recipe", "getOutput", "(I)Lnet/minecraft/item/ItemStack;", false); + Label l4 = new Label(); + mv.visitJumpInsn(IFNONNULL, l4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(298, l5); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("GTPP_MOD: Someone tried to register an achievement for a recipe with null output. Please report this to Alkalus."); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(299, l6); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + mv.visitLabel(l4); + mv.visitLineNumber(301, l4); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/util/GT_Recipe", "getOutput", "(I)Lnet/minecraft/item/ItemStack;", false); + mv.visitVarInsn(ASTORE, 3); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(302, l7); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/ItemUtils", "getUnlocalizedItemName", "(Lnet/minecraft/item/ItemStack;)Ljava/lang/String;", false); + mv.visitVarInsn(ASTORE, 2); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(304, l8); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/loaders/misc/GT_Achievements", "achievementList", "Ljava/util/concurrent/ConcurrentHashMap;"); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", false); + Label l9 = new Label(); + mv.visitJumpInsn(IFNONNULL, l9); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(305, l10); + mv.visitFieldInsn(GETSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + mv.visitInsn(ICONST_1); + mv.visitInsn(IADD); + mv.visitFieldInsn(PUTSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(306, l11); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 2); + mv.visitIntInsn(BIPUSH, 11); + mv.visitFieldInsn(GETSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + mv.visitInsn(ICONST_5); + mv.visitInsn(IREM); + mv.visitInsn(IADD); + mv.visitInsn(INEG); + mv.visitFieldInsn(GETSTATIC, "gregtech/loaders/misc/GT_Achievements", "assReg", "I"); + mv.visitInsn(ICONST_5); + mv.visitInsn(IDIV); + mv.visitIntInsn(BIPUSH, 8); + mv.visitInsn(ISUB); + mv.visitVarInsn(ALOAD, 1); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/util/GT_Recipe", "getOutput", "(I)Lnet/minecraft/item/ItemStack;", false); + mv.visitLdcInsn("NO_REQUIREMENT"); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/loaders/misc/GT_Achievements", "registerAchievement", "(Ljava/lang/String;IILnet/minecraft/item/ItemStack;Ljava/lang/String;Z)Lnet/minecraft/stats/Achievement;", false); + mv.visitVarInsn(ASTORE, 4); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(307, l12); + Label l13 = new Label(); + mv.visitJumpInsn(GOTO, l13); + mv.visitLabel(l9); + mv.visitLineNumber(309, l9); + mv.visitFrame(F_APPEND,2, new Object[] {"java/lang/String", "net/minecraft/item/ItemStack"}, 0, null); + mv.visitInsn(ACONST_NULL); + mv.visitVarInsn(ASTORE, 4); + mv.visitLabel(l13); + mv.visitLineNumber(311, l13); + mv.visitFrame(F_APPEND,1, new Object[] {"net/minecraft/stats/Achievement"}, 0, null); + mv.visitVarInsn(ALOAD, 4); + mv.visitInsn(ARETURN); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLocalVariable("this", "Lgregtech/loaders/misc/GT_Achievements;", null, l0, l14, 0); + mv.visitLocalVariable("recipe", "Lgregtech/api/util/GT_Recipe;", null, l0, l14, 1); + mv.visitLocalVariable("aSafeUnlocalName", "Ljava/lang/String;", null, l8, l14, 2); + mv.visitLocalVariable("aStack", "Lnet/minecraft/item/ItemStack;", null, l7, l14, 3); + mv.visitLocalVariable("aYouDidSomethingInGT", "Lnet/minecraft/stats/Achievement;", null, l12, l9, 4); + mv.visitLocalVariable("aYouDidSomethingInGT", "Lnet/minecraft/stats/Achievement;", null, l13, l14, 4); + mv.visitMaxs(7, 5); + mv.visitEnd(); + + didInject = true; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + + + public class MethodAdaptor extends ClassVisitor { + + public MethodAdaptor(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + if (name.equals("registerAssAchievement")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Found method " + name + ", removing."); + methodVisitor = null; + mDidRemoveAssLineRecipeAdder = true; + } else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BaseMetaTileEntity.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BaseMetaTileEntity.java new file mode 100644 index 0000000000..da5859eb55 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BaseMetaTileEntity.java @@ -0,0 +1,158 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +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; + +public class ClassTransformer_GT_BaseMetaTileEntity { + + //The qualified name of the class we plan to transform. + //gregtech/common/blocks/GT_Block_Machines + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + + public ClassTransformer_GT_BaseMetaTileEntity(byte[] basicClass) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + FMLRelaunchLog.log("[GT++ ASM] Gregtech setMetaTileEntity Patch", Level.INFO, "Attempting to make setMetaTileEntity(IMetaTileEntity) safer."); + + 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; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech setMetaTileEntity Patch", Level.INFO, "Valid patch? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + + + if (reader != null && writer != null) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech setMetaTileEntity Patch", Level.INFO, "Attempting Method Injection."); + injectMethod("setMetaTileEntity"); + } + + } + + 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; + FMLRelaunchLog.log("[GT++ ASM] Gregtech setMetaTileEntity Patch", Level.INFO, "Injecting "+aMethodName+"."); + if (aMethodName.equals("setMetaTileEntity")) { + + mv = getWriter().visitMethod(ACC_PUBLIC, "setMetaTileEntity", "(Lgregtech/api/interfaces/metatileentity/IMetaTileEntity;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); + mv.visitLabel(l0); + mv.visitLineNumber(1568, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/metatileentity/MetaTileEntity"); + mv.visitFieldInsn(PUTFIELD, "gregtech/api/metatileentity/BaseMetaTileEntity", "mMetaTileEntity", "Lgregtech/api/metatileentity/MetaTileEntity;"); + mv.visitLabel(l1); + mv.visitLineNumber(1569, l1); + Label l3 = new Label(); + mv.visitJumpInsn(GOTO, l3); + mv.visitLabel(l2); + mv.visitLineNumber(1570, l2); + mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"}); + mv.visitVarInsn(ASTORE, 2); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(1571, l4); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("[BMTE] Bad Tile Entity set in world, your game would have crashed if not for me!"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(1572, l5); + mv.visitVarInsn(ALOAD, 1); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(1573, l7); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); + mv.visitInsn(DUP); + mv.visitLdcInsn("Tile was of type: "); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEINTERFACE, "gregtech/api/interfaces/metatileentity/IMetaTileEntity", "getInventoryName", "()Ljava/lang/String;", true); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + mv.visitLabel(l6); + mv.visitLineNumber(1574, l6); + mv.visitFrame(F_APPEND,1, new Object[] {"java/lang/Throwable"}, 0, null); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false); + mv.visitLabel(l3); + mv.visitLineNumber(1576, l3); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitInsn(RETURN); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLocalVariable("this", "Lgregtech/api/metatileentity/BaseMetaTileEntity;", null, l0, l8, 0); + mv.visitLocalVariable("aMetaTileEntity", "Lgregtech/api/interfaces/metatileentity/IMetaTileEntity;", null, l0, l8, 1); + mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, l4, l3, 2); + mv.visitMaxs(4, 3); + mv.visitEnd(); + + didInject = true; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech setMetaTileEntity Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public 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) { + MethodVisitor methodVisitor; + if (name.equals("setMetaTileEntity")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech setMetaTileEntity Patch", Level.INFO, "Found method "+name+", removing."); + methodVisitor = null; + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_MetaPipeEntity.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_MetaPipeEntity.java new file mode 100644 index 0000000000..dce1fa15d2 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_MetaPipeEntity.java @@ -0,0 +1,286 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ARETURN; +import static org.objectweb.asm.Opcodes.ASM5; +import static org.objectweb.asm.Opcodes.GETFIELD; +import static org.objectweb.asm.Opcodes.ILOAD; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.objectweb.asm.Opcodes.IRETURN; + +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 gregtech.api.GregTech_API; +import gregtech.api.enums.Materials; +import gregtech.api.enums.SubTag; +import gregtech.api.metatileentity.BaseMetaPipeEntity; +import gtPlusPlus.xmod.gregtech.common.Meta_GT_Proxy; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public class ClassTransformer_GT_BlockMachines_MetaPipeEntity { + + //The qualified name of the class we plan to transform. + //gregtech/common/blocks/GT_Block_Machines + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + /** + * Utility Functions + */ + + public static String getHarvestTool(int aMeta) { + //FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Attempting to call getHarvestTool. Meta: "+aMeta); + if (aMeta >= 8 && aMeta <= 11) { + return "cutter"; + } + return "wrench"; + } + + /* + * Used to patch the method in Fluid pipes, Frame Boxes and Item Pipes + */ + /** + * This determines the BaseMetaTileEntity belonging to this MetaTileEntity by using the Meta ID of the Block itself. + * <p/> + * 0 = BaseMetaTileEntity, Wrench lvl 0 to dismantle + * 1 = BaseMetaTileEntity, Wrench lvl 1 to dismantle + * <p/> + * 2 = BaseMetaTileEntity, Wrench lvl 2 to dismantle + * 3 = BaseMetaTileEntity, Wrench lvl 3 to dismantle + * <p/> + * 4 = BaseMetaPipeEntity, Wrench lvl 0 to dismantle + * 5 = BaseMetaPipeEntity, Wrench lvl 1 to dismantle + * <p/> + * 6 = BaseMetaPipeEntity, Wrench lvl 2 to dismantle + * 7 = BaseMetaPipeEntity, Wrench lvl 3 to dismantle + * <p/> + * 8 = BaseMetaPipeEntity, Cutter lvl 0 to dismantle + * 9 = BaseMetaPipeEntity, Cutter lvl 1 to dismantle + * <p/> + * 10 = BaseMetaPipeEntity, Cutter lvl 2 to dismantle + * 11 = BaseMetaPipeEntity, Cutter lvl 3 to dismantle + * <p/> + * == Reserved For Alkalus (Was previously used to allow axes on wooden blocks, but that's fucking stupid.) + * <p/> + * 12 = BaseCustomPower_MTE, Wrench lvl 0 to dismantle + * 13 = BaseCustomTileEntity, Wrench lvl 1 to dismantle + * <p/> + * 14 = BaseCustomTileEntity, Wrench lvl 2 to dismantle + * 15 = BaseCustomTileEntity, Wrench lvl 3 to dismantle + */ + public static byte getTileEntityBaseType(Materials mMaterial) { + byte mMetaID; + //Modified code that should never return 12-15 for Wooden items. + //mMetaID = (byte) (mMaterial == null ? 4 : (byte) (4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); + //Original Code for debug purposes + mMetaID = mMaterial == null ? 4 : (byte) ((mMaterial.contains(SubTag.WOOD) ? 4 : 4) + Math.max(0, Math.min(3, mMaterial.mToolQuality))); + //FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Attempting to call getTileEntityBaseType. Using Meta: "+mMetaID); + return mMetaID; + } + + + + /** + * This determines the BaseMetaTileEntity belonging to this MetaTileEntity by using the Meta ID of the Block itself. + * <p/> + * 0 = BaseMetaTileEntity, Wrench lvl 0 to dismantle + * 1 = BaseMetaTileEntity, Wrench lvl 1 to dismantle + * <p/> + * 2 = BaseMetaTileEntity, Wrench lvl 2 to dismantle + * 3 = BaseMetaTileEntity, Wrench lvl 3 to dismantle + * <p/> + * 4 = BaseMetaPipeEntity, Wrench lvl 0 to dismantle + * 5 = BaseMetaPipeEntity, Wrench lvl 1 to dismantle + * <p/> + * 6 = BaseMetaPipeEntity, Wrench lvl 2 to dismantle + * 7 = BaseMetaPipeEntity, Wrench lvl 3 to dismantle + * <p/> + * 8 = BaseMetaPipeEntity, Cutter lvl 0 to dismantle + * 9 = BaseMetaPipeEntity, Cutter lvl 1 to dismantle + * <p/> + * 10 = BaseMetaPipeEntity, Cutter lvl 2 to dismantle + * 11 = BaseMetaPipeEntity, Cutter lvl 3 to dismantle + * <p/> + * == Reserved For Alkalus (Was previously used to allow axes on wooden blocks, but that's fucking stupid.) + * <p/> + * 12 = BaseCustomPower_MTE, Wrench lvl 2 to dismantle + * 13 = BaseCustomTileEntity, Wrench lvl 2 to dismantle + * <p/> + * 14 = BaseCustomTileEntity, Wrench lvl 3 to dismantle + * 15 = BaseCustomTileEntity, Wrench lvl 3 to dismantle + */ + public static TileEntity createTileEntity(World aWorld, int aMeta) { + //Logger.INFO("Creating Tile Entity with Meta of "+aMeta); + if (aMeta < 4) { + return GregTech_API.constructBaseMetaTileEntity(); + } else if (aMeta < 12) { + return new BaseMetaPipeEntity(); + } else { + //Because Wooden pipes/frames may exist in world, we try cast to the GT++ tile first, if tht fails, we cast a pipe.. + try { + return Meta_GT_Proxy.constructCustomGregtechMetaTileEntityByMeta(aMeta); + } + catch (Throwable c) { + //Returns a pipe entity, once this returns, it should correct itself and no longer error in future. + return new BaseMetaPipeEntity(); + } + } + } + + public static TileEntity createTileEntity_Original(World aWorld, int aMeta) { + // Logger.INFO("Creating Tile Entity with Meta of "+aMeta); + if (aMeta < 4) { + return GregTech_API.constructBaseMetaTileEntity(); + } else { + return new BaseMetaPipeEntity(); + } + } + + int mMode; + + public ClassTransformer_GT_BlockMachines_MetaPipeEntity(byte[] basicClass, int aMode) { + mMode = aMode; + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Attempting to patch in mode "+aMode+"."); + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitor(aTempWriter, mMode), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Valid patch? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + + + if (reader != null && writer != null) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Attempting Method Injection."); + if (aMode == 0) { + injectMethod("getHarvestTool"); + injectMethod("createTileEntity"); + } + else { + injectMethod("getTileEntityBaseType"); + } + } + + } + + 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; + FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Injecting "+aMethodName+"."); + if (aMethodName.equals("getHarvestTool")) { + mv = getWriter().visitMethod(ACC_PUBLIC, "getHarvestTool", "(I)Ljava/lang/String;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(63, l0); + mv.visitVarInsn(ILOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_MetaPipeEntity", "getHarvestTool", "(I)Ljava/lang/String;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lgregtech/common/blocks/GT_Block_Machines;", null, l0, l1, 0); + mv.visitLocalVariable("aMeta", "I", null, l0, l1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals("createTileEntity")) { + mv = getWriter().visitMethod(ACC_PUBLIC, "createTileEntity", "(Lnet/minecraft/world/World;I)Lnet/minecraft/tileentity/TileEntity;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(442, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_MetaPipeEntity", "createTileEntity", "(Lnet/minecraft/world/World;I)Lnet/minecraft/tileentity/TileEntity;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lgregtech/common/blocks/GT_Block_Machines;", null, l0, l1, 0); + mv.visitLocalVariable("aWorld", "Lnet/minecraft/world/World;", null, l0, l1, 1); + mv.visitLocalVariable("aMeta", "I", null, l0, l1, 2); + mv.visitMaxs(2, 3); + mv.visitEnd(); + didInject = true; + + } + else if (aMethodName.equals("getTileEntityBaseType")) { + + String aClassName = mMode == 1 ? "gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Item" : mMode == 2 ? "gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Frame" : "gregtech/api/metatileentity/implementations/GT_MetaPipeEntity_Fluid"; + mv = getWriter().visitMethod(ACC_PUBLIC, "getTileEntityBaseType", "()B", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(37, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, ""+aClassName+"", "mMaterial", "Lgregtech/api/enums/Materials;"); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_MetaPipeEntity", "getTileEntityBaseType", "(Lgregtech/api/enums/Materials;)B", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "L"+aClassName+";", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public final class localClassVisitor extends ClassVisitor { + + private final int mMode; + + public localClassVisitor(ClassVisitor cv, int aMode) { + super(ASM5, cv); + mMode = aMode; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + if ((mMode == 0 && (name.equals("createTileEntity") || name.equals("getHarvestTool"))) || (mMode > 0 && name.equals("getTileEntityBaseType"))) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech getTileEntityBaseType Patch", Level.INFO, "Found method "+name+", removing."); + methodVisitor = null; + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_NBT.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_NBT.java new file mode 100644 index 0000000000..349bdc3e88 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_BlockMachines_NBT.java @@ -0,0 +1,193 @@ +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.core.lib.CORE; +import gtPlusPlus.preloader.DevHelper; +import gtPlusPlus.preloader.asm.AsmConfig; + +public class ClassTransformer_GT_BlockMachines_NBT { + + //The qualified name of the class we plan to transform. + private static final String className = "gregtech.common.blocks.GT_Block_Machines"; + //gregtech/common/blocks/GT_Block_Machines + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + String aEntityPlayer; + String aEntityPlayerMP; + String aWorld; + + public static boolean isNbtPersistencyPatchAlreadyApplied = false; + + public ClassTransformer_GT_BlockMachines_NBT(byte[] basicClass, boolean obfuscated) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + FMLRelaunchLog.log("[GT++ ASM] Gregtech NBT Persistency Patch", Level.INFO, "Attempting to patch "+className+"."); + + 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; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech NBT Persistency Patch", Level.INFO, "Valid patch? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + + CORE.NBT_PERSISTENCY_PATCH_APPLIED = isNbtPersistencyPatchAlreadyApplied; + + if (reader != null && writer != null && !isNbtPersistencyPatchAlreadyApplied && AsmConfig.enableGtNbtFix) { + aEntityPlayer = obfuscated ? DevHelper.getObfuscated("net/minecraft/entity/player/EntityPlayer") : "net/minecraft/entity/player/EntityPlayer"; + aEntityPlayerMP = obfuscated ? DevHelper.getObfuscated("net/minecraft/entity/player/EntityPlayerMP") : "net/minecraft/entity/player/EntityPlayerMP"; + aWorld = obfuscated ? DevHelper.getObfuscated("net/minecraft/world/World") : "net/minecraft/world/World"; + FMLRelaunchLog.log("[GT++ ASM] Gregtech NBT Persistency Patch", Level.INFO, "Attempting Method Injection."); + if (injectMethod("removedByPlayer") && injectMethod("harvestBlock")) { + CORE.NBT_PERSISTENCY_PATCH_APPLIED = true; + } + } + + } + + 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; + FMLRelaunchLog.log("[GT++ ASM] Gregtech NBT Persistency Patch", Level.INFO, "Injecting "+aMethodName+" into "+className+"."); + if (aMethodName.equals("removedByPlayer")) { + + mv = getWriter().visitMethod(ACC_PUBLIC, "removedByPlayer", "(L"+aWorld+";L"+aEntityPlayer+";IIIZ)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(535, l0); + mv.visitVarInsn(ILOAD, 6); + Label l1 = new Label(); + mv.visitJumpInsn(IFEQ, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(536, l2); + mv.visitInsn(ICONST_1); + mv.visitInsn(IRETURN); + mv.visitLabel(l1); + mv.visitLineNumber(538, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(ILOAD, 5); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/items/GT_Generic_Block", "removedByPlayer", "(L"+aWorld+";L"+aEntityPlayer+";IIIZ)Z", false); + mv.visitInsn(IRETURN); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLocalVariable("this", "Lgregtech/common/blocks/GT_Block_Machines;", null, l0, l3, 0); + mv.visitLocalVariable("aWorld", "L"+aWorld+";", null, l0, l3, 1); + mv.visitLocalVariable("aPlayer", "L"+aEntityPlayer+";", null, l0, l3, 2); + mv.visitLocalVariable("aX", "I", null, l0, l3, 3); + mv.visitLocalVariable("aY", "I", null, l0, l3, 4); + mv.visitLocalVariable("aZ", "I", null, l0, l3, 5); + mv.visitLocalVariable("aWillHarvest", "Z", null, l0, l3, 6); + mv.visitMaxs(7, 7); + mv.visitEnd(); + didInject = true; + + } + else if (aMethodName.equals("harvestBlock")) { + + mv = getWriter().visitMethod(ACC_PUBLIC, "harvestBlock", "(L"+aWorld+";L"+aEntityPlayer+";IIII)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(544, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(ILOAD, 5); + mv.visitVarInsn(ILOAD, 6); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/items/GT_Generic_Block", "harvestBlock", "(L"+aWorld+";L"+aEntityPlayer+";IIII)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(545, l1); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(ILOAD, 5); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aWorld+"", "setBlockToAir", "(III)Z", false); + mv.visitInsn(POP); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(546, l2); + mv.visitInsn(RETURN); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLocalVariable("this", "Lgregtech/common/blocks/GT_Block_Machines;", null, l0, l3, 0); + mv.visitLocalVariable("aWorld", "L"+aWorld+";", null, l0, l3, 1); + mv.visitLocalVariable("aPlayer", "L"+aEntityPlayer+";", null, l0, l3, 2); + mv.visitLocalVariable("aX", "I", null, l0, l3, 3); + mv.visitLocalVariable("aY", "I", null, l0, l3, 4); + mv.visitLocalVariable("aZ", "I", null, l0, l3, 5); + mv.visitLocalVariable("aMeta", "I", null, l0, l3, 6); + mv.visitMaxs(7, 7); + mv.visitEnd(); + didInject = true; + + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech NBT Persistency Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + 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("removedByPlayer")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech NBT Persistency Patch", Level.INFO, "Found method "+name+", skipping patch."); + isNbtPersistencyPatchAlreadyApplied = true; + } + if (name.equals("harvestBlock")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech NBT Persistency Patch", Level.INFO, "Found method "+name+", skipping patch."); + isNbtPersistencyPatchAlreadyApplied = true; + } + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java new file mode 100644 index 0000000000..1e54bd3632 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java @@ -0,0 +1,184 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +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 cpw.mods.fml.relauncher.FMLRelaunchLog; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.util.GT_Utility; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import net.minecraft.block.Block; +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + +public class ClassTransformer_GT_CharcoalPit { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public static boolean isWoodLog(Block log) { + return isWoodLog(log, Short.MAX_VALUE); + } + + public static boolean isWoodLog(Block log, int meta) { + ItemStack aLogStack = ItemUtils.getSimpleStack(log, meta, 1); + ArrayList<ItemStack> aData = OrePrefixes.log.mPrefixedItems; + for (ItemStack aStack : aData) { + if (GT_Utility.areStacksEqual(aStack, aLogStack)) { + return true; + } + } + aData.clear(); + aData = OreDictionary.getOres("logWood"); + for (ItemStack aStack : aData) { + if (GT_Utility.areStacksEqual(aStack, aLogStack)) { + return true; + } + } + return false; + } + + public ClassTransformer_GT_CharcoalPit(byte[] basicClass, boolean obfuscated) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + boolean aBadTime = false; + if (ReflectionUtils.doesClassExist("aji")) { + obfuscated = true; + } + else { + if (ReflectionUtils.doesClassExist("net.minecraft.block.Block")) { + obfuscated = false; + } + else { + // Bad... Like.. very bad.. + FMLRelaunchLog.log("[GT++ ASM] GT Charcoal Pit Fix", Level.INFO, "Unable to find Block.class/aji.class, this is BAD. Not Patching."); + } + } + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + if (!aBadTime) { + aTempReader.accept(new CustomClassVisitor(aTempWriter), 0); + injectMethod("isWoodLog", obfuscated, aTempWriter); + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } else { + isValid = false; + } + } + else { + isValid = false; + } + FMLRelaunchLog.log("[GT++ ASM] GT Charcoal Pit Fix", Level.INFO, "Valid? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(String aMethodName, boolean obfuscated, ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] GT Charcoal Pit Fix", Level.INFO, "Injecting " + aMethodName + "."); + + String aBlockClassName = "net/minecraft/block/Block"; + if (obfuscated) { + aBlockClassName = "aji"; + } + if (aMethodName.equals("isWoodLog")) { + + // Inject original Method with only block arg. + mv = cw.visitMethod(ACC_PUBLIC, "isWoodLog", "(L"+aBlockClassName+";)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(197, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit", "isWoodLog", "(L"+aBlockClassName+";)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lgregtech/common/tileentities/machines/multi/GT_MetaTileEntity_Charcoal_Pit;", null, l0, l1, 0); + mv.visitLocalVariable("log", "L"+aBlockClassName+";", null, l0, l1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); + + + // Inject better Method with block & meta arg. + mv = cw.visitMethod(ACC_PUBLIC, "isWoodLog", "(L"+aBlockClassName+";I)Z", null, null); + mv.visitCode(); + Label label0 = new Label(); + mv.visitLabel(label0); + mv.visitLineNumber(201, label0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit", "isWoodLog", "(L"+aBlockClassName+";I)Z", false); + mv.visitInsn(IRETURN); + Label label1 = new Label(); + mv.visitLabel(label1); + mv.visitLocalVariable("this", "Lgregtech/common/tileentities/machines/multi/GT_MetaTileEntity_Charcoal_Pit;", null, label0, label1, 0); + mv.visitLocalVariable("log", "L"+aBlockClassName+";", null, label0, label1, 1); + mv.visitLocalVariable("meta", "I", null, label0, label1, 2); + mv.visitMaxs(2, 3); + mv.visitEnd(); + + didInject = true; + + } + FMLRelaunchLog.log("[GT++ ASM] GT Charcoal Pit Fix", Level.INFO, "Method injection complete."); + return didInject; + } + + public class CustomClassVisitor extends ClassVisitor { + + public CustomClassVisitor(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + private final String[] aMethodsToStrip = new String[] { "isWoodLog" }; + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + boolean found = false; + + for (String s : aMethodsToStrip) { + if (name.equals(s)) { + found = true; + break; + } + } + if (!found) { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } else { + methodVisitor = null; + } + if (found) { + FMLRelaunchLog.log("[GT++ ASM] GT Charcoal Pit Fix", Level.INFO, "Found method " + name + ", removing."); + } + return methodVisitor; + } + + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Client.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Client.java new file mode 100644 index 0000000000..e2d34c38e7 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Client.java @@ -0,0 +1,410 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ASM5; +import static org.objectweb.asm.Opcodes.INVOKESPECIAL; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.objectweb.asm.Opcodes.RETURN; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.AnnotationVisitor; +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.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.common.reflect.ClassPath; +import com.google.common.reflect.ClassPath.ClassInfo; + +import cpw.mods.fml.common.gameevent.TickEvent.Phase; +import cpw.mods.fml.common.gameevent.TickEvent.PlayerTickEvent; +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gregtech.api.GregTech_API; +import gregtech.api.util.GT_Log; +import gregtech.api.util.GT_PlayedSound; +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Recipe.GT_Recipe_Map; +import gregtech.api.util.GT_Utility; +import gtPlusPlus.api.objects.Logger; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import gtPlusPlus.xmod.gregtech.common.StaticFields59; +import gtPlusPlus.xmod.gregtech.loaders.misc.AssLineAchievements; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatFileWriter; + +public class ClassTransformer_GT_Client { + + private final boolean valid; + private final ClassReader read; + private final ClassWriter write; + private boolean mModern = true; + private boolean mObfuscated = true; + private byte[] mTooledClass; + + public ClassTransformer_GT_Client(byte[] basicClass, boolean obfuscated) { + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + mObfuscated = obfuscated; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + + /** + * Let's just read the GT archive for some info + */ + //mModern = findAssemblyLineClass(); + //FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Found Assembly Line? "+mModern+"."); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Fixing Issues in vanilla GT."); + if (mModern) { + aTempReader.accept(new MethodAdaptor2(aTempWriter), 0); + //FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Patching Client handling of Assembly Line recipe visibility for GT 5.09"); + //injectMethod(aTempWriter, "onPlayerTickEventClient"); + injectMethod(aTempWriter, "onPostLoad"); + if (aTempReader != null && aTempWriter != null) { + valid = true; + mTooledClass = aTempWriter.toByteArray(); + } + else { + valid = false; + } + } + else { + mTooledClass = basicClass; + valid = true; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Valid? "+valid+"."); + read = aTempReader; + write = aTempWriter; + } + + public boolean isValidTransformer() { + return valid; + } + + public ClassReader getReader() { + return read; + } + + public ClassWriter getWriter() { + return write; + } + + public boolean findAssemblyLineClass() { + ClassLoader cl = getClass().getClassLoader(); + try { + Set<ClassPath.ClassInfo> classesInPackage = ClassPath.from(cl).getTopLevelClassesRecursive("gregtech"); + if (classesInPackage != null && classesInPackage.size() > 0) { + for (ClassInfo x : classesInPackage) { + if (x.getResourceName().contains("GT_MetaTileEntity_AssemblyLine")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, + "Patchable class | " + x.getResourceName()); + return true; + } + } + } + } catch (IOException e) { + } + + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Failed to find Gregtech classes using prefered method, using backup."); + + cl = ClassLoader.getSystemClassLoader(); + ImmutableMap<File, ClassLoader> g = getClassPathEntries(cl); + File aGregtech = null; + if (g.size() > 0) { + for (int i = 0; i < g.size(); i++) { + String aName; + try { + File aF = g.keySet().asList().get(i); + aName = aF.getName(); + if (aName != null && aName.length() > 0) { + if (aName.toLowerCase().contains("gregtech")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Patchable class | "+aName); + aGregtech = aF; + } + } + } + catch (Throwable t) {} + } + } + + if (aGregtech != null) { + File file = aGregtech; + FileInputStream fis; + JarInputStream jis; + try { + fis = new FileInputStream(file); + jis = new JarInputStream(fis); + System.out.println(jis.markSupported()); + JarEntry je; + while((je=jis.getNextJarEntry())!=null){ + if (je.getName().contains("GT_MetaTileEntity_AssemblyLine")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Patchable class | "+je.getName()); + jis.close(); + return true; + } + } + if (jis != null) { + jis.close(); + } + return true; + } catch (IOException e1) { + } + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Failed to find Gregtech classes using backup method, probably using GT 5.08"); + + return false; + } + + static ImmutableMap<File, ClassLoader> getClassPathEntries(ClassLoader classloader) { + LinkedHashMap<File, ClassLoader> entries = Maps.newLinkedHashMap(); + // Search parent first, since it's the order ClassLoader#loadClass() uses. + ClassLoader parent = classloader.getParent(); + if (parent != null) { + entries.putAll(getClassPathEntries(parent)); + } + if (classloader instanceof URLClassLoader) { + URLClassLoader urlClassLoader = (URLClassLoader) classloader; + for (URL entry : urlClassLoader.getURLs()) { + if (entry.getProtocol().equals("file")) { + File file = new File(entry.getFile()); + if (!entries.containsKey(file)) { + entries.put(file, classloader); + } + } + } + } + return ImmutableMap.copyOf(entries); + } + + public boolean injectMethod(ClassWriter cw, String string) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Injecting " + string + ". Obfuscated? "+mObfuscated); + + if (string.equals("onPlayerTickEventClient")) { + /** + * Inject new, safer code + */ + AnnotationVisitor av0; + /** + * Static invocation of custom handler instead + */ + mv = cw.visitMethod(ACC_PUBLIC, "onPlayerTickEventClient", "(Lcpw/mods/fml/common/gameevent/TickEvent$PlayerTickEvent;)V", null, null); + av0 = mv.visitAnnotation("Lcpw/mods/fml/common/eventhandler/SubscribeEvent;", true); + av0.visitEnd(); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(371, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Client", "onPlayerTickEventClient", "(Lcpw/mods/fml/common/gameevent/TickEvent$PlayerTickEvent;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(372, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lgregtech/common/GT_Client;", null, l0, l2, 0); + mv.visitLocalVariable("aEvent", "Lcpw/mods/fml/common/gameevent/TickEvent$PlayerTickEvent;", null, l0, l2, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); + didInject = true; + } + else if (string.equals("onPostLoad")) { + mv = cw.visitMethod(ACC_PUBLIC, "onPostLoad", "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(315, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/common/GT_Proxy", "onPostLoad", "()V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(316, l1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Client", "onPostLoad", "()V", false); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(317, l2); + mv.visitInsn(RETURN); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLocalVariable("this", "Lgregtech/common/GT_Client;", null, l0, l3, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + + + + + + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, "Method injection complete."); + return didInject; + + } + + public class MethodAdaptor2 extends ClassVisitor { + + public MethodAdaptor2(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + if (/*name.equals("onPlayerTickEventClient") || */name.equals("onPostLoad")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Client Proxy Patch", Level.INFO, + "Found method " + name + ", removing."); + methodVisitor = null; + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + return methodVisitor; + } + } + + public byte[] getByteArray() { + if (mTooledClass != null) { + return mTooledClass; + } + return getWriter().toByteArray(); + } + + + private static final Map<UUID, Long> aTimeMap = new HashMap<UUID, Long>(); + + + public static void onPlayerTickEventClient(PlayerTickEvent aEvent) { + if (aEvent.side.isClient() && aEvent.phase == Phase.END && !aEvent.player.isDead) { + long aTime = 0; + if (aTimeMap.get(aEvent.player.getUniqueID()) == null) { + aTimeMap.put(aEvent.player.getUniqueID(), 0l); + } + else { + aTime = aTimeMap.get(aEvent.player.getUniqueID()) + 1; + aTimeMap.put(aEvent.player.getUniqueID(), aTime); + } + if (aTime >= 100L) { + aTimeMap.put(aEvent.player.getUniqueID(), 0l); + /** + * Remove original handling + */ + if (StaticFields59.mAssLineVisualMapNEI != null) { + StatFileWriter tList = Minecraft.getMinecraft().thePlayer.getStatFileWriter(); + GT_Recipe_Map aAssLineNei; + try { + aAssLineNei = (GT_Recipe_Map) StaticFields59.mAssLineVisualMapNEI.get(null); + for (GT_Recipe aFakeAssLineRecipe : aAssLineNei.mRecipeList) { + String aSafeUnlocalName; + if (aFakeAssLineRecipe.getOutput(0) == null) { + Logger.INFO( + "Someone tried to register an achievement for a recipe with null output. Please report this to Alkalus."); + continue; + } + ItemStack aStack = aFakeAssLineRecipe.getOutput(0); + try { + aSafeUnlocalName = aStack.getUnlocalizedName(); + } catch (Throwable t) { + aSafeUnlocalName = ItemUtils.getUnlocalizedItemName(aStack); + } + boolean aHidden = true; + try { + aHidden = tList.hasAchievementUnlocked(AssLineAchievements.getAchievement(aSafeUnlocalName)); + Logger.INFO("Found achievement for "+aSafeUnlocalName); + } + catch (NullPointerException rrr) { + aHidden = true; + //Logger.INFO("Exception handling achievement for "+aSafeUnlocalName); + //rrr.printStackTrace(); + } + aFakeAssLineRecipe.mHidden = !aHidden; + } + } catch (IllegalArgumentException | IllegalAccessException e) { + } + } + } + + Iterator tKey; + ArrayList arg5 = new ArrayList(); + tKey = GT_Utility.sPlayedSoundMap.entrySet().iterator(); + + while (tKey.hasNext()) { + Entry arg7 = (Entry) tKey.next(); + if (((Integer) arg7.getValue()).intValue() < 0) { + arg5.add(arg7.getKey()); + } else { + arg7.setValue(Integer.valueOf(((Integer) arg7.getValue()).intValue() - 1)); + } + } + + Iterator arg8 = arg5.iterator(); + + while (arg8.hasNext()) { + GT_PlayedSound arg6 = (GT_PlayedSound) arg8.next(); + GT_Utility.sPlayedSoundMap.remove(arg6); + } + + if (!GregTech_API.mServerStarted) { + GregTech_API.mServerStarted = true; + } + } + } + + + + + /** + * GT_Client's onPostLoad + */ + + public static void onPostLoad() { + try { + for (int i = 0; i < GregTech_API.METATILEENTITIES.length; i++) { + try { + if (GregTech_API.METATILEENTITIES[i] != null) { + GregTech_API.METATILEENTITIES[i].getStackForm(1L).getTooltip((EntityPlayer) null, true); + } + } + catch (Throwable t) { + GT_Log.err.println("Error in MetaTileEntity with ID of "+i); + t.printStackTrace(GT_Log.err); + } + } + } catch (Throwable var2) { + var2.printStackTrace(); + } + } + + + + + + + +}
\ No newline at end of file diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_EnergyHatchPatch.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_EnergyHatchPatch.java new file mode 100644 index 0000000000..83560eb6c3 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_EnergyHatchPatch.java @@ -0,0 +1,317 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.*; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gtPlusPlus.preloader.asm.ClassesToTransform; + +public class ClassTransformer_GT_EnergyHatchPatch { + + private static final String aRtgInputFormatted = ClassesToTransform.GTPP_MTE_HATCH_RTG.replace(".", "/"); + private static final String aEnergyFormatted = ClassesToTransform.GT_MTE_HATCH_ENERGY.replace(".", "/"); + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + + public ClassTransformer_GT_EnergyHatchPatch(byte[] basicClass, String aClassName) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Attempting to add slots capabilities to GT Energy Hatches."); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Patching "+aClassName+"."); + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitor(aTempWriter, aClassName), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Valid patch? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + + + if (reader != null && writer != null) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Attempting Method Injection."); + injectMethod(aClassName); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + + public boolean injectMethod(String aClassName) { + + boolean didInject = false; + MethodVisitor mv; + ClassWriter cw = getWriter(); + int aConID = 1; + + //GT_MetaTileEntity_Hatch_Energy + //Constructor + if (aClassName.equals(ClassesToTransform.GT_MTE_HATCH_ENERGY)){ + + + //Constructor 1 + { + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(ILjava/lang/String;Ljava/lang/String;II[Ljava/lang/String;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(26, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(ILOAD, 5); + mv.visitVarInsn(ALOAD, 6); + mv.visitInsn(ICONST_0); + mv.visitTypeInsn(ANEWARRAY, "gregtech/api/interfaces/ITexture"); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch", "<init>", "(ILjava/lang/String;Ljava/lang/String;II[Ljava/lang/String;[Lgregtech/api/interfaces/ITexture;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(27, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lgregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy;", null, l0, l2, 0); + mv.visitLocalVariable("aID", "I", null, l0, l2, 1); + mv.visitLocalVariable("aName", "Ljava/lang/String;", null, l0, l2, 2); + mv.visitLocalVariable("aNameRegional", "Ljava/lang/String;", null, l0, l2, 3); + mv.visitLocalVariable("aTier", "I", null, l0, l2, 4); + mv.visitLocalVariable("aSlots", "I", null, l0, l2, 5); + mv.visitLocalVariable("aDesc", "[Ljava/lang/String;", null, l0, l2, 6); + mv.visitMaxs(8, 7); + mv.visitEnd(); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Injection new constructor "+(aConID++)); + } + + //Constructor 2 + { + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;IILjava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(30, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch", "<init>", "(Ljava/lang/String;IILjava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(31, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lgregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy;", null, l0, l2, 0); + mv.visitLocalVariable("aName", "Ljava/lang/String;", null, l0, l2, 1); + mv.visitLocalVariable("aTier", "I", null, l0, l2, 2); + mv.visitLocalVariable("aSlots", "I", null, l0, l2, 3); + mv.visitLocalVariable("aDescription", "Ljava/lang/String;", null, l0, l2, 4); + mv.visitLocalVariable("aTextures", "[[[Lgregtech/api/interfaces/ITexture;", null, l0, l2, 5); + mv.visitMaxs(6, 6); + mv.visitEnd(); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Injection new constructor "+(aConID++)); + } + + //Third constructor with String[] for GT 5.09 + { + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;II[Ljava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(34, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch", "<init>", "(Ljava/lang/String;II[Ljava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(35, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lgregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy;", null, l0, l2, 0); + mv.visitLocalVariable("aName", "Ljava/lang/String;", null, l0, l2, 1); + mv.visitLocalVariable("aTier", "I", null, l0, l2, 2); + mv.visitLocalVariable("aSlots", "I", null, l0, l2, 3); + mv.visitLocalVariable("aDescription", "[Ljava/lang/String;", null, l0, l2, 4); + mv.visitLocalVariable("aTextures", "[[[Lgregtech/api/interfaces/ITexture;", null, l0, l2, 5); + mv.visitMaxs(6, 6); + mv.visitEnd(); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Injection new constructor "+(aConID++)); + } + didInject = true; + } + + //GT_MetaTileEntity_Hatch_Energy_RTG + //Constructor + if (aClassName.equals(ClassesToTransform.GTPP_MTE_HATCH_RTG)){ + + { + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(ILjava/lang/String;Ljava/lang/String;II)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(38, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(ILOAD, 5); + mv.visitInsn(ICONST_2); + mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_0); + mv.visitLdcInsn("Energy Injector for Multiblocks"); + mv.visitInsn(AASTORE); + mv.visitInsn(DUP); + mv.visitInsn(ICONST_1); + mv.visitLdcInsn("Accepts RTG pellets for Fuel"); + mv.visitInsn(AASTORE); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy", "<init>", "(ILjava/lang/String;Ljava/lang/String;II[Ljava/lang/String;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(39, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "LgtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy_RTG;", null, l0, l2, 0); + mv.visitLocalVariable("aID", "I", null, l0, l2, 1); + mv.visitLocalVariable("aName", "Ljava/lang/String;", null, l0, l2, 2); + mv.visitLocalVariable("aNameRegional", "Ljava/lang/String;", null, l0, l2, 3); + mv.visitLocalVariable("aTier", "I", null, l0, l2, 4); + mv.visitLocalVariable("aSlots", "I", null, l0, l2, 5); + mv.visitMaxs(10, 6); + mv.visitEnd(); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Injection new constructor "+(aConID++)); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;IILjava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(42, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy", "<init>", "(Ljava/lang/String;IILjava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(43, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "LgtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy_RTG;", null, l0, l2, 0); + mv.visitLocalVariable("aName", "Ljava/lang/String;", null, l0, l2, 1); + mv.visitLocalVariable("aTier", "I", null, l0, l2, 2); + mv.visitLocalVariable("aSlots", "I", null, l0, l2, 3); + mv.visitLocalVariable("aDescription", "Ljava/lang/String;", null, l0, l2, 4); + mv.visitLocalVariable("aTextures", "[[[Lgregtech/api/interfaces/ITexture;", null, l0, l2, 5); + mv.visitMaxs(6, 6); + mv.visitEnd(); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Injection new constructor "+(aConID++)); + } + { + mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;II[Ljava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(46, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ALOAD, 5); + mv.visitMethodInsn(INVOKESPECIAL, "gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy", "<init>", "(Ljava/lang/String;II[Ljava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(47, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "LgtPlusPlus/xmod/gregtech/api/metatileentity/implementations/GT_MetaTileEntity_Hatch_Energy_RTG;", null, l0, l2, 0); + mv.visitLocalVariable("aName", "Ljava/lang/String;", null, l0, l2, 1); + mv.visitLocalVariable("aTier", "I", null, l0, l2, 2); + mv.visitLocalVariable("aSlots", "I", null, l0, l2, 3); + mv.visitLocalVariable("aDescription", "[Ljava/lang/String;", null, l0, l2, 4); + mv.visitLocalVariable("aTextures", "[[[Lgregtech/api/interfaces/ITexture;", null, l0, l2, 5); + mv.visitMaxs(6, 6); + mv.visitEnd(); + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Injection new constructor "+(aConID++)); + } + + + didInject = true; + } + + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Method injection complete. Successful? "+didInject); + return didInject; + + } + + public final class localClassVisitor extends ClassVisitor { + + private final String mClassName; + + public localClassVisitor(ClassVisitor cv, String aClassName) { + super(ASM5, cv); + mClassName = aClassName; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor = null; + if ((mClassName.equals(ClassesToTransform.GTPP_MTE_HATCH_RTG)) && access == ACC_PUBLIC && name.equals("<init>") && (desc.equals("(Ljava/lang/String;ILjava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V") || desc.equals("(Ljava/lang/String;I[Ljava/lang/String;[[[Lgregtech/api/interfaces/ITexture;)V"))) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Found Constructor, "+"'"+access+"', "+"'"+name+"', "+"'"+desc+"', "+"'"+signature+"'"); + methodVisitor = null; + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + if (methodVisitor == null) { + if (mClassName.equals(ClassesToTransform.GT_MTE_HATCH_ENERGY)){ + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Removed method from "+mClassName); + } + else { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Energy Hatch Patch", Level.INFO, "Removed Constructor with descriptor '"+desc+"' from "+mClassName); + } + } + return methodVisitor; + } + } + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_ItemMachines_Tooltip.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_ItemMachines_Tooltip.java new file mode 100644 index 0000000000..4b2a10df07 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_ItemMachines_Tooltip.java @@ -0,0 +1,139 @@ +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_GT_ItemMachines_Tooltip { + + //The qualified name of the class we plan to transform. + private static final String className = "gregtech.common.blocks.GT_Item_Machines"; + //gregtech/common/blocks/GT_Item_Machines + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + String aEntityPlayer; + String aItemStack; + String aWorld; + + private static boolean doesMethodAlreadyExist = false; + + public ClassTransformer_GT_ItemMachines_Tooltip(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) { + aEntityPlayer = obfuscated ? DevHelper.getObfuscated("net/minecraft/entity/player/EntityPlayer") : "net/minecraft/entity/player/EntityPlayer"; + aItemStack = obfuscated ? DevHelper.getObfuscated("net/minecraft/item/ItemStack") : "net/minecraft/item/ItemStack"; + aWorld = obfuscated ? DevHelper.getObfuscated("net/minecraft/world/World") : "net/minecraft/world/World"; + + injectMethod("addInformation"); + } + + } + + 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] Gregtech Tooltip Patch", Level.INFO, "Injecting "+aMethodName+" into "+className+"."); + if (aMethodName.equals("addInformation")) { + + mv = getWriter().visitMethod(ACC_PUBLIC, "addInformation", "(L"+aItemStack+";L"+aEntityPlayer+";Ljava/util/List;Z)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); + mv.visitLabel(l0); + mv.visitLineNumber(120, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/xmod/gregtech/common/Meta_GT_Proxy", "conStructGtTileBlockTooltip", "(L"+aItemStack+";L"+aEntityPlayer+";Ljava/util/List;Z)V", false); + mv.visitLabel(l1); + mv.visitLineNumber(121, l1); + Label l3 = new Label(); + mv.visitJumpInsn(GOTO, l3); + mv.visitLabel(l2); + mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"}); + mv.visitVarInsn(ASTORE, 5); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(122, l4); + mv.visitVarInsn(ALOAD, 5); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "(Ljava/io/PrintStream;)V", false); + mv.visitLabel(l3); + mv.visitLineNumber(124, l3); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLocalVariable("this", "Lgregtech/common/blocks/GT_Item_Machines;", null, l0, l5, 0); + mv.visitLocalVariable("aStack", "L"+aItemStack+";", null, l0, l5, 1); + mv.visitLocalVariable("aPlayer", "L"+aEntityPlayer+";", null, l0, l5, 2); + mv.visitLocalVariable("aList", "Ljava/util/List;", null, l0, l5, 3); + mv.visitLocalVariable("par4", "Z", null, l0, l5, 4); + mv.visitLocalVariable("e", "Ljava/lang/Throwable;", null, l4, l3, 5); + mv.visitMaxs(4, 6); + mv.visitEnd(); +} + FMLRelaunchLog.log("[GT++ ASM] Gregtech Tooltip 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("addInformation")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech Tooltip Patch", Level.INFO, "Found method "+name+", Patching."); + return null; + } + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_MetaGenerated_Tool.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_MetaGenerated_Tool.java new file mode 100644 index 0000000000..b6cd9c8d67 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_MetaGenerated_Tool.java @@ -0,0 +1,116 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.ACC_FINAL; +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +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 org.apache.logging.log4j.Level; +import org.objectweb.asm.AnnotationVisitor; +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 gtPlusPlus.preloader.Preloader_Logger; + +public class ClassTransformer_GT_MetaGenerated_Tool { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public ClassTransformer_GT_MetaGenerated_Tool(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); + boolean completed = injectMethod("getSubItems", aTempWriter); + if (aTempReader != null && aTempWriter != null && completed) { + isValid = true; + } else { + isValid = false; + } + Preloader_Logger.LOG("GT Tool Fix", Level.INFO, "Valid? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(String aMethodName, ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + Preloader_Logger.LOG("GT Tool Fix", Level.INFO, "Injecting " + aMethodName + "."); + if (aMethodName.equals("getSubItems")) { + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "getSubItems", "(Lnet/minecraft/item/Item;Lnet/minecraft/creativetab/CreativeTabs;Ljava/util/List;)V", null, null); + { + AnnotationVisitor av0 = mv.visitAnnotation("Lcpw/mods/fml/relauncher/SideOnly;", true); + av0.visitEnum("value", "Lcpw/mods/fml/relauncher/Side;", "CLIENT"); + av0.visitEnd(); + } + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(321, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/helpers/MethodHelper_GT", "getSubItems", "(Lgregtech/api/items/GT_MetaGenerated_Tool;Lnet/minecraft/item/Item;Lnet/minecraft/creativetab/CreativeTabs;Ljava/util/List;)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(322, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lgregtech/api/items/GT_MetaGenerated_Tool;", null, l0, l2, 0); + mv.visitLocalVariable("var1", "Lnet/minecraft/item/Item;", null, l0, l2, 1); + mv.visitLocalVariable("aCreativeTab", "Lnet/minecraft/creativetab/CreativeTabs;", null, l0, l2, 2); + mv.visitLocalVariable("aList", "Ljava/util/List;", null, l0, l2, 3); + mv.visitMaxs(4, 4); + mv.visitEnd(); + didInject = true; + } + + } + Preloader_Logger.LOG("GT Tool Fix", Level.INFO, "Method injection complete."); + return didInject; + } + + public 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) { + MethodVisitor methodVisitor; + if (name.equals("getSubItems") && desc.equals("(Lnet/minecraft/item/Item;Lnet/minecraft/creativetab/CreativeTabs;Ljava/util/List;)V")) { + methodVisitor = null; + Preloader_Logger.LOG("GT Tool Fix", Level.INFO, "Found method "+name+", removing."); + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Packet_TileEntity.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Packet_TileEntity.java new file mode 100644 index 0000000000..1f281ce492 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Packet_TileEntity.java @@ -0,0 +1,319 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +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; + +public class ClassTransformer_GT_Packet_TileEntity { + + //The qualified name of the class we plan to transform. + //gregtech/common/blocks/GT_Block_Machines + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + + public ClassTransformer_GT_Packet_TileEntity(byte[] basicClass, boolean obfuscated) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + FMLRelaunchLog.log("[GT++ ASM] Gregtech GT_Packet_TileEntity Patch", Level.INFO, "Attempting to make GT Packets safer."); + + 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; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech GT_Packet_TileEntity Patch", Level.INFO, "Valid patch? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + + + if (reader != null && writer != null) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech GT_Packet_TileEntity Patch", Level.INFO, "Attempting Method Injection."); + injectMethod("process", obfuscated); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(String aMethodName, boolean obfuscated) { + MethodVisitor mv; + boolean didInject = false; + String aGetTile = obfuscated ? "func_147438_o" : "getTileEntity"; + + FMLRelaunchLog.log("[GT++ ASM] Gregtech GT_Packet_TileEntity Patch", Level.INFO, "Injecting "+aMethodName+"."); + if (aMethodName.equals("process")) { + mv = getWriter().visitMethod(ACC_PUBLIC, "process", "(Lnet/minecraft/world/IBlockAccess;)V", null, null); + mv.visitCode(); + Label l0 = new Label(); + Label l1 = new Label(); + Label l2 = new Label(); + mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable"); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(93, l3); + mv.visitVarInsn(ALOAD, 1); + Label l4 = new Label(); + mv.visitJumpInsn(IFNULL, l4); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(94, l5); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mX", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mY", "S"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mZ", "I"); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/world/IBlockAccess", ""+aGetTile+"", "(III)Lnet/minecraft/tileentity/TileEntity;", true); + mv.visitVarInsn(ASTORE, 2); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(95, l6); + mv.visitVarInsn(ALOAD, 2); + mv.visitJumpInsn(IFNULL, l4); + mv.visitLabel(l0); + mv.visitLineNumber(97, l0); + mv.visitVarInsn(ALOAD, 2); + mv.visitTypeInsn(INSTANCEOF, "gregtech/api/metatileentity/BaseMetaTileEntity"); + Label l7 = new Label(); + mv.visitJumpInsn(IFEQ, l7); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(98, l8); + mv.visitVarInsn(ALOAD, 2); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/metatileentity/BaseMetaTileEntity"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mID", "S"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC0", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC1", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC2", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC3", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC4", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC5", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mTexture", "B"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mTexturePage", "B"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mUpdate", "B"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mRedstone", "B"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mColor", "B"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/metatileentity/BaseMetaTileEntity", "receiveMetaTileEntityData", "(SIIIIIIBBBBB)V", false); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(99, l9); + mv.visitJumpInsn(GOTO, l4); + mv.visitLabel(l7); + mv.visitLineNumber(101, l7); + mv.visitFrame(F_APPEND,1, new Object[] {"net/minecraft/tileentity/TileEntity"}, 0, null); + mv.visitVarInsn(ALOAD, 2); + mv.visitTypeInsn(INSTANCEOF, "gregtech/api/metatileentity/BaseMetaPipeEntity"); + mv.visitJumpInsn(IFEQ, l4); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(102, l10); + mv.visitVarInsn(ALOAD, 2); + mv.visitTypeInsn(CHECKCAST, "gregtech/api/metatileentity/BaseMetaPipeEntity"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mID", "S"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC0", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC1", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC2", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC3", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC4", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mC5", "I"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mTexture", "B"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mUpdate", "B"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mRedstone", "B"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mColor", "B"); + mv.visitMethodInsn(INVOKEVIRTUAL, "gregtech/api/metatileentity/BaseMetaPipeEntity", "receiveMetaTileEntityData", "(SIIIIIIBBBB)V", false); + mv.visitLabel(l1); + mv.visitLineNumber(104, l1); + mv.visitJumpInsn(GOTO, l4); + mv.visitLabel(l2); + mv.visitLineNumber(105, l2); + mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {"java/lang/Throwable"}); + mv.visitVarInsn(ASTORE, 3); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(106, l11); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); + mv.visitInsn(DUP); + mv.visitLdcInsn("[GTPTE] Bad Tile Entity set in world, your game would have crashed if not for me! Was Null? "); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); + mv.visitVarInsn(ALOAD, 2); + Label l12 = new Label(); + mv.visitJumpInsn(IFNONNULL, l12); + mv.visitInsn(ICONST_1); + Label l13 = new Label(); + mv.visitJumpInsn(GOTO, l13); + mv.visitLabel(l12); + mv.visitFrame(F_FULL, 4, new Object[] {"gregtech/api/net/GT_Packet_TileEntity", "net/minecraft/world/IBlockAccess", "net/minecraft/tileentity/TileEntity", "java/lang/Throwable"}, 2, new Object[] {"java/io/PrintStream", "java/lang/StringBuilder"}); + mv.visitInsn(ICONST_0); + mv.visitLabel(l13); + mv.visitFrame(F_FULL, 4, new Object[] {"gregtech/api/net/GT_Packet_TileEntity", "net/minecraft/world/IBlockAccess", "net/minecraft/tileentity/TileEntity", "java/lang/Throwable"}, 3, new Object[] {"java/io/PrintStream", "java/lang/StringBuilder", INTEGER}); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Z)Ljava/lang/StringBuilder;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(107, l14); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); + mv.visitInsn(DUP); + mv.visitLdcInsn("Tile location ["); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mX", "I"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); + mv.visitLdcInsn("]["); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mY", "S"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); + mv.visitLdcInsn("]["); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "gregtech/api/net/GT_Packet_TileEntity", "mZ", "I"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;", false); + mv.visitLdcInsn("]"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(108, l15); + mv.visitVarInsn(ALOAD, 2); + Label l16 = new Label(); + mv.visitJumpInsn(IFNULL, l16); + Label l17 = new Label(); + mv.visitLabel(l17); + mv.visitLineNumber(109, l17); + mv.visitVarInsn(ALOAD, 2); + mv.visitTypeInsn(INSTANCEOF, "gregtech/api/metatileentity/BaseMetaPipeEntity"); + Label l18 = new Label(); + mv.visitJumpInsn(IFEQ, l18); + Label l19 = new Label(); + mv.visitLabel(l19); + mv.visitLineNumber(110, l19); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("Type: Pipe"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l20 = new Label(); + mv.visitLabel(l20); + mv.visitLineNumber(111, l20); + mv.visitJumpInsn(GOTO, l16); + mv.visitLabel(l18); + mv.visitLineNumber(112, l18); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 2); + mv.visitTypeInsn(INSTANCEOF, "gregtech/api/metatileentity/BaseMetaTileEntity"); + Label l21 = new Label(); + mv.visitJumpInsn(IFEQ, l21); + Label l22 = new Label(); + mv.visitLabel(l22); + mv.visitLineNumber(113, l22); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("Type: Machine"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + Label l23 = new Label(); + mv.visitLabel(l23); + mv.visitLineNumber(114, l23); + mv.visitJumpInsn(GOTO, l16); + mv.visitLabel(l21); + mv.visitLineNumber(116, l21); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitFieldInsn(GETSTATIC, "gregtech/api/util/GT_Log", "err", "Ljava/io/PrintStream;"); + mv.visitLdcInsn("Type: Non-GT (Could be GT++/TT/BW)"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); + mv.visitLabel(l16); + mv.visitLineNumber(119, l16); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 3); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false); + mv.visitLabel(l4); + mv.visitLineNumber(123, l4); + mv.visitFrame(F_CHOP,2, null, 0, null); + mv.visitInsn(RETURN); + Label l24 = new Label(); + mv.visitLabel(l24); + mv.visitLocalVariable("this", "Lgregtech/api/net/GT_Packet_TileEntity;", null, l3, l24, 0); + mv.visitLocalVariable("aWorld", "Lnet/minecraft/world/IBlockAccess;", null, l3, l24, 1); + mv.visitLocalVariable("tTileEntity", "Lnet/minecraft/tileentity/TileEntity;", null, l6, l4, 2); + mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, l11, l4, 3); + mv.visitMaxs(13, 4); + mv.visitEnd(); + + + didInject = true; + } + FMLRelaunchLog.log("[GT++ ASM] Gregtech GT_Packet_TileEntity Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public 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) { + MethodVisitor methodVisitor; + if (name.equals("process")) { + FMLRelaunchLog.log("[GT++ ASM] Gregtech GT_Packet_TileEntity Patch", Level.INFO, "Found method "+name+", removing."); + methodVisitor = null; + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Utility.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Utility.java new file mode 100644 index 0000000000..fa711e5693 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_Utility.java @@ -0,0 +1,283 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +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 gtPlusPlus.core.util.Utils; +import gtPlusPlus.preloader.Preloader_Logger; +import ic2.core.IC2Potion; +import ic2.core.item.armor.ItemArmorHazmat; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; + +public class ClassTransformer_GT_Utility { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private final String className; + + + + public ClassTransformer_GT_Utility(byte[] basicClass, String aClassName) { + + className = aClassName; + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitor(aTempWriter, className), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } else { + isValid = false; + } + + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Valid patch? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null) { + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Attempting Method Injection."); + injectMethod("getTier"); + injectMethod("applyRadioactivity"); + injectMethod("isWearingFullFrostHazmat"); + injectMethod("isWearingFullHeatHazmat"); + injectMethod("isWearingFullBioHazmat"); + injectMethod("isWearingFullRadioHazmat"); + injectMethod("isWearingFullElectroHazmat"); + injectMethod("isWearingFullGasHazmat"); + } + + } + + 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; + ClassWriter cw = getWriter(); + String aClassNameFormatted = Utils.class.getName().replace(".", "/"); + + if (aMethodName.equals("isWearingFullFrostHazmat")){ + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "isWearingFullFrostHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1273, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/EntityUtils", "isWearingFullFrostHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("aEntity", "Lnet/minecraft/entity/EntityLivingBase;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + + if (aMethodName.equals("isWearingFullHeatHazmat")){ + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "isWearingFullHeatHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1277, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/EntityUtils", "isWearingFullHeatHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("aEntity", "Lnet/minecraft/entity/EntityLivingBase;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + + if (aMethodName.equals("isWearingFullBioHazmat")){ + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "isWearingFullBioHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1281, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/EntityUtils", "isWearingFullBioHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("aEntity", "Lnet/minecraft/entity/EntityLivingBase;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + + if (aMethodName.equals("isWearingFullRadioHazmat")){ + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "isWearingFullRadioHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1285, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/EntityUtils", "isWearingFullRadioHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("aEntity", "Lnet/minecraft/entity/EntityLivingBase;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + + if (aMethodName.equals("isWearingFullElectroHazmat")){ + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "isWearingFullElectroHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1289, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/EntityUtils", "isWearingFullElectroHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("aEntity", "Lnet/minecraft/entity/EntityLivingBase;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + + if (aMethodName.equals("isWearingFullGasHazmat")){ + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "isWearingFullGasHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1293, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/EntityUtils", "isWearingFullGasHazmat", "(Lnet/minecraft/entity/EntityLivingBase;)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("aEntity", "Lnet/minecraft/entity/EntityLivingBase;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + + if (aMethodName.equals("getTier")) { + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + ", static replacement call to "+aClassNameFormatted+"."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "getTier", "(J)B", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(23, l0); + mv.visitVarInsn(LLOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, aClassNameFormatted, "getTier", "(J)B", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("l", "J", null, l0, l1, 0); + mv.visitMaxs(2, 2); + mv.visitEnd(); + didInject = true; + } + + if (aMethodName.equals("applyRadioactivity")){ + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "applyRadioactivity", "(Lnet/minecraft/entity/EntityLivingBase;II)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(1342, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/EntityUtils", "applyRadioactivity", "(Lnet/minecraft/entity/EntityLivingBase;II)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("aEntity", "Lnet/minecraft/entity/EntityLivingBase;", null, l0, l1, 0); + mv.visitLocalVariable("aLevel", "I", null, l0, l1, 1); + mv.visitLocalVariable("aAmountOfItems", "I", null, l0, l1, 2); + mv.visitMaxs(3, 3); + mv.visitEnd(); + didInject = true; + } + + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public final class localClassVisitor extends ClassVisitor { + + String aClassName; + + public localClassVisitor(ClassVisitor cv, String aName) { + super(ASM5, cv); + aClassName = aName; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + + if (name.equals("getTier")) { + methodVisitor = null; + } + else if (name.equals("applyRadioactivity")){ + methodVisitor = null; + } + else if (name.equals("isWearingFullFrostHazmat")){ + methodVisitor = null; + } + else if (name.equals("isWearingFullHeatHazmat")){ + methodVisitor = null; + } + else if (name.equals("isWearingFullBioHazmat")){ + methodVisitor = null; + } + else if (name.equals("isWearingFullRadioHazmat")){ + methodVisitor = null; + } + else if (name.equals("isWearingFullElectroHazmat")){ + methodVisitor = null; + } + else if (name.equals("isWearingFullGasHazmat")){ + methodVisitor = null; + } + else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + + if (methodVisitor == null) { + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Found method " + name + ", removing."); + Preloader_Logger.LOG("Gregtech Utilities Patch", Level.INFO, "Descriptor: "+desc); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_GetHarvestTool.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_GetHarvestTool.java new file mode 100644 index 0000000000..6aad6831cb --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_GetHarvestTool.java @@ -0,0 +1,214 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import java.util.Random; + +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 net.minecraft.block.Block; +import net.minecraft.item.Item; + +public class ClassTransformer_IC2_GetHarvestTool { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private final String className; + + private final String aName_getItemDropped; + private final String aName_damageDropped; + + public static String getHarvestTool(int aMeta) { + return "wrench"; + } + + public static Item getItemDropped(Block aBlock, int meta, Random random, int fortune) { + return Item.getItemFromBlock(aBlock); + } + + public static int damageDropped(int aMeta) { + return aMeta; + } + + public ClassTransformer_IC2_GetHarvestTool(byte[] basicClass, boolean obfuscated, String aClassName) { + className = aClassName; + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + aName_getItemDropped = obfuscated ? "func_149650_a" : "getItemDropped"; + aName_damageDropped = obfuscated ? "func_149692_a" : "damageDropped"; + + FMLRelaunchLog.log("[GT++ ASM] IC2 getHarvestTool Patch", Level.INFO, + "Attempting to patch in mode " + className + ". Obfuscated? "+obfuscated); + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitor(aTempWriter, className), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } else { + isValid = false; + } + + FMLRelaunchLog.log("[GT++ ASM] IC2 getHarvestTool Patch", Level.INFO, "Valid patch? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null) { + FMLRelaunchLog.log("[GT++ ASM] IC2 getHarvestTool Patch", Level.INFO, "Attempting Method Injection."); + injectMethod("getHarvestTool"); + if (aClassName.equals("ic2.core.block.machine.BlockMachine2") + || aClassName.equals("ic2.core.block.machine.BlockMachine3") + || aClassName.equals("ic2.core.block.wiring.BlockElectric")) { + injectMethod(aName_getItemDropped); + injectMethod(aName_damageDropped); + } + else if (aClassName.equals("ic2.core.block.generator.block.BlockGenerator") + || aClassName.equals("ic2.core.block.machine.BlockMachine")) { + injectMethod(aName_damageDropped); + } + } + + } + + 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 aFormattedClassName = className.replace('.', '/'); + ClassWriter cw = getWriter(); + + + FMLRelaunchLog.log("[GT++ ASM] IC2 getHarvestTool Patch", Level.INFO, "Injecting " + aMethodName + "."); + if (aMethodName.equals("getHarvestTool")) { + mv = getWriter().visitMethod(ACC_PUBLIC, "getHarvestTool", "(I)Ljava/lang/String;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(63, l0); + mv.visitVarInsn(ILOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, + "gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_GetHarvestTool", "getHarvestTool", + "(I)Ljava/lang/String;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "L" + aFormattedClassName + ";", null, l0, l1, 0); + mv.visitLocalVariable("aMeta", "I", null, l0, l1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals(aName_getItemDropped)) { + mv = cw.visitMethod(ACC_PUBLIC, aName_getItemDropped, "(ILjava/util/Random;I)Lnet/minecraft/item/Item;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(44, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_GetHarvestTool", "getItemDropped", "(Lnet/minecraft/block/Block;ILjava/util/Random;I)Lnet/minecraft/item/Item;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "L"+aFormattedClassName+";", null, l0, l1, 0); + mv.visitLocalVariable("meta", "I", null, l0, l1, 1); + mv.visitLocalVariable("random", "Ljava/util/Random;", null, l0, l1, 2); + mv.visitLocalVariable("fortune", "I", null, l0, l1, 3); + mv.visitMaxs(4, 4); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals(aName_damageDropped)) { + mv = cw.visitMethod(ACC_PUBLIC, aName_damageDropped, "(I)I", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(48, l0); + mv.visitVarInsn(ILOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_GetHarvestTool", "damageDropped", "(I)I", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "L"+aFormattedClassName+";", null, l0, l1, 0); + mv.visitLocalVariable("meta", "I", null, l0, l1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd(); + didInject = true; + } + FMLRelaunchLog.log("[GT++ ASM] IC2 getHarvestTool Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public final class localClassVisitor extends ClassVisitor { + + String aClassName; + + public localClassVisitor(ClassVisitor cv, String aName) { + super(ASM5, cv); + aClassName = aName; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + if (aClassName.equals("ic2.core.block.machine.BlockMachine2") + || aClassName.equals("ic2.core.block.machine.BlockMachine3") + || aClassName.equals("ic2.core.block.wiring.BlockElectric")) { + if (name.equals(aName_getItemDropped)) { + methodVisitor = null; + } else if (name.equals(aName_damageDropped)) { + methodVisitor = null; + } else if (name.equals("getHarvestTool")) { + methodVisitor = null; + } else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + } + else if (aClassName.equals("ic2.core.block.generator.block.BlockGenerator") + || aClassName.equals("ic2.core.block.machine.BlockMachine")) { + if (name.equals(aName_damageDropped)) { + methodVisitor = null; + } else if (name.equals("getHarvestTool")) { + methodVisitor = null; + } else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + } + else { + if (name.equals("getHarvestTool")) { + methodVisitor = null; + } else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + } + if (methodVisitor == null) { + FMLRelaunchLog.log("[GT++ ASM] IC2 getHarvestTool Patch", Level.INFO, + "Found method " + name + ", removing."); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_Hazmat.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_Hazmat.java new file mode 100644 index 0000000000..10f04e7a48 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_IC2_Hazmat.java @@ -0,0 +1,147 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.*; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gtPlusPlus.core.util.minecraft.HazmatUtils; +import net.minecraft.entity.EntityLivingBase; + +public class ClassTransformer_IC2_Hazmat { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private final String className; + + public static boolean hasCompleteHazmat(EntityLivingBase living) { + return HazmatUtils.hasCompleteHazmat(living); + } + + public ClassTransformer_IC2_Hazmat(byte[] basicClass, String aClassName) { + className = aClassName; + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, "Attempting to patch in mode " + className + "."); + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitor(aTempWriter, className), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } else { + isValid = false; + } + + FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, "Valid patch? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null) { + FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, "Attempting Method Injection."); + injectMethod("hasCompleteHazmat"); + } + + } + + 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; + ClassWriter cw = getWriter(); + + boolean isObf; + try { + isObf = Class.forName("net.minecraft.entity.EntityLivingBase") == null; + } catch (ClassNotFoundException e) { + isObf = true; + } + String aEntityLivingBase = "net/minecraft/entity/EntityLivingBase"; + if (isObf) { + aEntityLivingBase = "sv"; + } + FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, "Method Handler: "+aEntityLivingBase); + + + FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, "Injecting " + aMethodName + "."); + if (aMethodName.equals("hasCompleteHazmat")) { + + //Bad Local Variable - https://pastebin.com/TUCfdHqS + /*mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "hasCompleteHazmat", "(L"+aEntityLivingBase+";)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(23, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/HazmatUtils", "hasCompleteHazmat", "(L"+aEntityLivingBase+";)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("this", "Lic2/core/item/armor/ItemArmorHazmat;", null, l0, l1, 0); + mv.visitLocalVariable("living", "L"+aEntityLivingBase+";", null, l0, l1, 1); + mv.visitMaxs(1, 2); + mv.visitEnd();*/ + + + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "hasCompleteHazmat", "(L"+aEntityLivingBase+";)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(24, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/core/util/minecraft/HazmatUtils", "hasCompleteHazmat", "(L"+aEntityLivingBase+";)Z", false); + mv.visitInsn(IRETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("living", "L"+aEntityLivingBase+";", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, "Method injection complete."); + return didInject; + } + + public final class localClassVisitor extends ClassVisitor { + + String aClassName; + + public localClassVisitor(ClassVisitor cv, String aName) { + super(ASM5, cv); + aClassName = aName; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + + if (name.equals("hasCompleteHazmat")) { + methodVisitor = null; + } else { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + + if (methodVisitor == null) { + FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, + "Found method " + name + ", removing."); + } + return methodVisitor; + } + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java new file mode 100644 index 0000000000..3ec4426ec1 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java @@ -0,0 +1,278 @@ +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.ACC_SYNCHRONIZED; +import static org.objectweb.asm.Opcodes.ARETURN; +import static org.objectweb.asm.Opcodes.ASM5; +import static org.objectweb.asm.Opcodes.ILOAD; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; + +import java.lang.reflect.Field; +import java.util.HashMap; + +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.core.util.Utils; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.GameSettings; +import net.minecraft.client.settings.KeyBinding; + +public class ClassTransformer_LWJGL_Keyboard { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + private static final HashMap<String, String> mBadKeyCache = new HashMap<String, String>(); + + /** + * Gets a key's name + * + * @param key The key + * @return a String with the key's human readable name in it or null if the key + * is unnamed + */ + public static synchronized String getKeyName(int key) { + if (init()) { + String[] aTemp = getKeyName(); + if (key < aTemp.length && key >= 0) { + return aTemp[key]; + } + } + String aCachedValue = mBadKeyCache.get("key-"+key); + if (aCachedValue == null) { + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Unable to map key code "+key+" to LWJGL keymap."); + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Caching key value to be empty."); + //mBadKeyCache.put("key-"+key, getKeyName()[0x00]); + aCachedValue = "FIX!"; + mBadKeyCache.put("key-"+key, aCachedValue); + trySetClientKey(key); + } + return aCachedValue; // Return nothing + } + + public static void trySetClientKey(int aKey) { + if (Utils.isClient() && ReflectionUtils.doesClassExist("net.minecraft.client.Minecraft")) { + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Trying to set key value to be empty."); + GameSettings options = Minecraft.getMinecraft().gameSettings; + KeyBinding[] akeybinding = Minecraft.getMinecraft().gameSettings.keyBindings; + int i = akeybinding.length; + for (int j = 0; j < i; ++j) { + KeyBinding keybinding = akeybinding[j]; + if (keybinding != null && keybinding.getKeyCode() == aKey) { + options.setOptionKeyBinding(keybinding, 0); + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Set keybind "+aKey+" to 0."); + break; + } + } + } + } + + @SuppressWarnings("rawtypes") + private static Class mKeyboard; + private static Field mKeyName; + + @SuppressWarnings("rawtypes") + private static boolean init() { + if (mKeyName != null) { + return true; + } + Class aKeyboard = ReflectionUtils.getClass("org.lwjgl.input.Keyboard"); + if (aKeyboard != null) { + mKeyboard = aKeyboard; + Field aKeyName = ReflectionUtils.getField(mKeyboard, "keyName"); + if (aKeyName != null) { + mKeyName = aKeyName; + } + } + return mKeyName != null; + } + + private static String[] getKeyName() { + if (init()) { + try { + Object o = mKeyName.get(null); + if (o instanceof String[]) { + String[] y = (String[]) o; + return y; + } + } catch (IllegalArgumentException | IllegalAccessException e) { + } + } + return new String[] {}; + } + + public ClassTransformer_LWJGL_Keyboard(byte[] basicClass, boolean isClientSettings) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + if (!isClientSettings) { + //gtPlusPlus.preloader.keyboard.BetterKeyboard.init(); + aTempReader.accept(new PatchLWJGL(aTempWriter), 0); + injectLWJGLPatch(aTempWriter); + } + else { + //gtPlusPlus.preloader.keyboard.BetterKeyboard.init(); + aTempReader.accept(new PatchClientSettings(aTempWriter), 0); + injectClientSettingPatch(aTempWriter); + } + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } else { + isValid = false; + } + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Valid? " + isValid + "."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + private boolean isClientSettingsObfuscated = false; + + + public boolean injectLWJGLPatch(ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, + "Injecting " + "getKeyName" + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC + ACC_SYNCHRONIZED, "getKeyName", "(I)Ljava/lang/String;", null, + null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(49, l0); + mv.visitVarInsn(ILOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard", + "getKeyName", "(I)Ljava/lang/String;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("key", "I", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Method injection complete."); + return didInject; + } + + + public boolean injectClientSettingPatch(ClassWriter cw) { + MethodVisitor mv; + boolean didInject = false; + String aMethodName = this.isClientSettingsObfuscated ? "func_74298_c" : "getKeyDisplayString"; + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Injecting " + aMethodName + "."); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, aMethodName, "(I)Ljava/lang/String;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(130, l0); + mv.visitVarInsn(ILOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/keyboard/BetterKeyboard", "getKeyDisplayString", "(I)Ljava/lang/String;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("p_74298_0_", "I", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Method injection complete."); + return didInject; + } + + + + public class PatchClientSettings extends ClassVisitor { + + public PatchClientSettings(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + private final String[] aMethodsToStrip = new String[] { "func_74298_c", "getKeyDisplayString" }; + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + boolean found = false; + + for (String s : aMethodsToStrip) { + if (name.equals(s)) { + if (name.equals(aMethodsToStrip[0])) { + isClientSettingsObfuscated = true; + } + else { + isClientSettingsObfuscated = false; + } + found = true; + break; + } + } + if (!found) { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } else { + methodVisitor = null; + } + if (found) { + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Found method " + name + ", removing."); + } + return methodVisitor; + } + + } + + public class PatchLWJGL extends ClassVisitor { + + public PatchLWJGL(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + private final String[] aMethodsToStrip = new String[] { "getKeyName" }; + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor; + boolean found = false; + + for (String s : aMethodsToStrip) { + if (name.equals(s)) { + found = true; + break; + } + } + if (!found) { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } else { + methodVisitor = null; + } + if (found) { + FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, + "Found method " + name + ", removing."); + } + return methodVisitor; + } + + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidCartHandling.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidCartHandling.java new file mode 100644 index 0000000000..bf71582ae7 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidCartHandling.java @@ -0,0 +1,117 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.ACC_FINAL; +import static org.objectweb.asm.Opcodes.ACC_PRIVATE; +import static org.objectweb.asm.Opcodes.ACC_STATIC; +import static org.objectweb.asm.Opcodes.ASM5; + +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.FieldVisitor; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gtPlusPlus.preloader.asm.AsmConfig; + +public class ClassTransformer_Railcraft_FluidCartHandling { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + //mods.railcraft.common.blocks.machine.gamma.TileFluidLoader + //mods.railcraft.common.blocks.machine.gamma.TileFluidLoader.TRANSFER_RATE + + //mods.railcraft.common.blocks.machine.gamma.TileFluidUnloader + //mods.railcraft.common.blocks.machine.gamma.TileFluidUnloader.TRANSFER_RATE + + public static final int TileFluidLoader_RATE = 20; + public static final int TileFluidUnloader_RATE = 80; + + private static final int TYPE_LOADER = 0; + private static final int TYPE_UNLOADER = 1; + + public ClassTransformer_Railcraft_FluidCartHandling(byte[] basicClass, boolean obfuscated, String aClassName) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + boolean aLoader = aClassName.equals("mods.railcraft.common.blocks.machine.gamma.TileFluidLoader"); + + FMLRelaunchLog.log("[GT++ ASM] Railcraft TRANSFER_RATE Patch", Level.INFO, "Attempting to patch field TRANSFER_RATE in "+aClassName+", default value is "+(aLoader ? 20 : 80)); + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + + if (aLoader) { + aTempReader.accept(new AddFieldAdapter(aTempWriter), 0); + addField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "TRANSFER_RATE", aTempWriter, TYPE_LOADER); + } + else { + aTempReader.accept(new AddFieldAdapter(aTempWriter), 0); + addField(ACC_PRIVATE + ACC_FINAL + ACC_STATIC, "TRANSFER_RATE", aTempWriter, TYPE_UNLOADER); + } + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + FMLRelaunchLog.log("[GT++ ASM] Railcraft TRANSFER_RATE Patch", Level.INFO, "Valid? "+isValid+"."); + } + else { + isValid = false; + } + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean addField(int access, String fieldName, ClassWriter cv, int aType) { + int aValue = (aType == TYPE_LOADER ? AsmConfig.maxRailcraftFluidLoaderFlow : AsmConfig.maxRailcraftFluidUnloaderFlow); + FMLRelaunchLog.log("[GT++ ASM] Railcraft TRANSFER_RATE Patch", Level.INFO, "Injecting " + fieldName + " with new value: "+aValue); + FieldVisitor fv = cv.visitField(access, fieldName, "I", null, new Integer(aValue)); + if (fv != null) { + fv.visitEnd(); + return true; + } + return false; + } + + + + + public class AddFieldAdapter extends ClassVisitor { + + public AddFieldAdapter(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + @Override + public FieldVisitor visitField( + int access, String name, String desc, String signature, Object value) { + if (name.equals("TRANSFER_RATE") && desc.equals("I")) { + FMLRelaunchLog.log("[GT++ ASM] Railcraft TRANSFER_RATE Patch", Level.INFO, "Removing "+"TRANSFER_RATE"+"."); + return null; + } + else { + FMLRelaunchLog.log("[GT++ ASM] Railcraft TRANSFER_RATE Patch", Level.INFO, "Found Field "+name+" | "+desc); + } + return cv.visitField(access, name, desc, signature, value); + } + + } + + + + + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidHelper.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidHelper.java new file mode 100644 index 0000000000..1249df0777 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_FluidHelper.java @@ -0,0 +1,695 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import java.lang.reflect.Method; + +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.FieldVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; +import gtPlusPlus.preloader.asm.AsmConfig; +import net.minecraft.inventory.IInventory; + +public class ClassTransformer_Railcraft_FluidHelper { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public static int PROCESS_VOLUME; + + public ClassTransformer_Railcraft_FluidHelper(byte[] basicClass, boolean obfuscated2) { + + PROCESS_VOLUME = AsmConfig.maxRailcraftTankProcessVolume; + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + FMLRelaunchLog.log("[GT++ ASM] Railcraft PROCESS_VOLUME Patch", Level.INFO, "Attempting to patch field PROCESS_VOLUME in mods.railcraft.common.fluids.FluidHelper with new value: "+PROCESS_VOLUME); + + boolean obfuscated = false; + boolean a1 = false; + boolean a2 = false; + + //Find Non-Obf method + try { + Method aGetStackInSlot = IInventory.class.getDeclaredMethod("getStackInSlot", int.class); + if (aGetStackInSlot != null) { + a1 = true; + } + } catch (NoSuchMethodException | SecurityException e) {} + + //Find Obf method + try { + Method aGetStackInSlotObf = IInventory.class.getDeclaredMethod("func_70301_a", int.class); + if (aGetStackInSlotObf != null) { + a2 = true; + } + } catch (NoSuchMethodException | SecurityException e) {} + + + if (a1) { + obfuscated = false; + } + else if (a2) { + obfuscated = true; + } + else { + //Fallback + obfuscated = false; + } + FMLRelaunchLog.log("[GT++ ASM] Railcraft PROCESS_VOLUME Patch", Level.INFO, "Are we patching obfuscated methods? "+obfuscated); + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new AddFieldAdapter(aTempWriter), 0); + + addField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "PROCESS_VOLUME", aTempWriter); + injectMethod("fillContainers", aTempWriter, obfuscated); + injectMethod("drainContainers", aTempWriter, obfuscated); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + + FMLRelaunchLog.log("[GT++ ASM] Railcraft PROCESS_VOLUME Patch", Level.INFO, "Valid? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean addField(int access, String fieldName, ClassWriter cv) { + FMLRelaunchLog.log( + "[GT++ ASM] Railcraft PROCESS_VOLUME Patch", + Level.INFO, + "Injecting " + fieldName + " with new value."); + FieldVisitor fv = cv.visitField(access, fieldName, "I", null, PROCESS_VOLUME); + if (fv != null) { + fv.visitEnd(); + return true; + } + return false; + } + + public boolean injectMethod(String aMethodName, ClassWriter cw, boolean obfuscated) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Railcraft PROCESS_VOLUME Patch", Level.INFO, "Injecting " + aMethodName + "."); + + if (aMethodName.equals("fillContainers") && !obfuscated) { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "fillContainers", "(Lnet/minecraftforge/fluids/IFluidHandler;Lnet/minecraft/inventory/IInventory;IILnet/minecraftforge/fluids/Fluid;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(126, l0); + mv.visitVarInsn(ALOAD, 4); + Label l1 = new Label(); + mv.visitJumpInsn(IFNONNULL, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(127, l2); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + mv.visitLabel(l1); + mv.visitLineNumber(128, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "getStackInSlot", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 5); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(129, l3); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 3); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "getStackInSlot", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 6); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(130, l4); + mv.visitVarInsn(ALOAD, 5); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 4); + mv.visitIntInsn(SIPUSH, PROCESS_VOLUME); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/Fluid;I)V", false); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidItemHelper", "fillContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraftforge/fluids/FluidStack;)Lmods/railcraft/common/fluids/FluidItemHelper$FillReturn;", false); + mv.visitVarInsn(ASTORE, 7); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(131, l5); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + mv.visitVarInsn(ALOAD, 6); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "hasPlaceToPutContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z", false); + mv.visitJumpInsn(IFEQ, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(132, l7); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "drain", "(Lnet/minecraftforge/common/util/ForgeDirection;IZ)Lnet/minecraftforge/fluids/FluidStack;", true); + mv.visitVarInsn(ASTORE, 8); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(133, l8); + mv.visitVarInsn(ALOAD, 8); + mv.visitJumpInsn(IFNULL, l6); + mv.visitVarInsn(ALOAD, 8); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitJumpInsn(IF_ICMPNE, l6); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(134, l9); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 8); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidItemHelper", "fillContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraftforge/fluids/FluidStack;)Lmods/railcraft/common/fluids/FluidItemHelper$FillReturn;", false); + mv.visitVarInsn(ASTORE, 7); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(135, l10); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + Label l11 = new Label(); + mv.visitJumpInsn(IFNULL, l11); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitVarInsn(ALOAD, 8); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitJumpInsn(IF_ICMPNE, l11); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(136, l12); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "drain", "(Lnet/minecraftforge/common/util/ForgeDirection;IZ)Lnet/minecraftforge/fluids/FluidStack;", true); + mv.visitInsn(POP); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(137, l13); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "storeContainer", "(Lnet/minecraft/inventory/IInventory;IILnet/minecraft/item/ItemStack;)V", false); + mv.visitLabel(l11); + mv.visitLineNumber(139, l11); + mv.visitFrame(F_FULL, 9, new Object[] {"net/minecraftforge/fluids/IFluidHandler", "net/minecraft/inventory/IInventory", INTEGER, INTEGER, "net/minecraftforge/fluids/Fluid", "net/minecraft/item/ItemStack", "net/minecraft/item/ItemStack", "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "net/minecraftforge/fluids/FluidStack"}, 0, new Object[] {}); + mv.visitInsn(ICONST_1); + mv.visitInsn(IRETURN); + mv.visitLabel(l6); + mv.visitLineNumber(142, l6); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLocalVariable("drain", "Lnet/minecraftforge/fluids/FluidStack;", null, l8, l6, 8); + mv.visitLocalVariable("fluidHandler", "Lnet/minecraftforge/fluids/IFluidHandler;", null, l0, l14, 0); + mv.visitLocalVariable("inv", "Lnet/minecraft/inventory/IInventory;", null, l0, l14, 1); + mv.visitLocalVariable("inputSlot", "I", null, l0, l14, 2); + mv.visitLocalVariable("outputSlot", "I", null, l0, l14, 3); + mv.visitLocalVariable("fluidToFill", "Lnet/minecraftforge/fluids/Fluid;", null, l0, l14, 4); + mv.visitLocalVariable("input", "Lnet/minecraft/item/ItemStack;", null, l3, l14, 5); + mv.visitLocalVariable("output", "Lnet/minecraft/item/ItemStack;", null, l4, l14, 6); + mv.visitLocalVariable("fill", "Lmods/railcraft/common/fluids/FluidItemHelper$FillReturn;", null, l5, l14, 7); + mv.visitMaxs(5, 9); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals("fillContainers") && obfuscated) { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "fillContainers", "(Lnet/minecraftforge/fluids/IFluidHandler;Lnet/minecraft/inventory/IInventory;IILnet/minecraftforge/fluids/Fluid;)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(126, l0); + mv.visitVarInsn(ALOAD, 4); + Label l1 = new Label(); + mv.visitJumpInsn(IFNONNULL, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(127, l2); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + mv.visitLabel(l1); + mv.visitLineNumber(128, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "func_70301_a", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 5); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(129, l3); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 3); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "func_70301_a", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 6); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(130, l4); + mv.visitVarInsn(ALOAD, 5); + mv.visitTypeInsn(NEW, "net/minecraftforge/fluids/FluidStack"); + mv.visitInsn(DUP); + mv.visitVarInsn(ALOAD, 4); + mv.visitIntInsn(SIPUSH, PROCESS_VOLUME); + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/FluidStack", "<init>", "(Lnet/minecraftforge/fluids/Fluid;I)V", false); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidItemHelper", "fillContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraftforge/fluids/FluidStack;)Lmods/railcraft/common/fluids/FluidItemHelper$FillReturn;", false); + mv.visitVarInsn(ASTORE, 7); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(131, l5); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + mv.visitVarInsn(ALOAD, 6); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "hasPlaceToPutContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z", false); + mv.visitJumpInsn(IFEQ, l6); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(132, l7); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "drain", "(Lnet/minecraftforge/common/util/ForgeDirection;IZ)Lnet/minecraftforge/fluids/FluidStack;", true); + mv.visitVarInsn(ASTORE, 8); + Label l8 = new Label(); + mv.visitLabel(l8); + mv.visitLineNumber(133, l8); + mv.visitVarInsn(ALOAD, 8); + mv.visitJumpInsn(IFNULL, l6); + mv.visitVarInsn(ALOAD, 8); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitJumpInsn(IF_ICMPNE, l6); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(134, l9); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 8); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidItemHelper", "fillContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraftforge/fluids/FluidStack;)Lmods/railcraft/common/fluids/FluidItemHelper$FillReturn;", false); + mv.visitVarInsn(ASTORE, 7); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(135, l10); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + Label l11 = new Label(); + mv.visitJumpInsn(IFNULL, l11); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitVarInsn(ALOAD, 8); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitJumpInsn(IF_ICMPNE, l11); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(136, l12); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "amount", "I"); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "drain", "(Lnet/minecraftforge/common/util/ForgeDirection;IZ)Lnet/minecraftforge/fluids/FluidStack;", true); + mv.visitInsn(POP); + Label l13 = new Label(); + mv.visitLabel(l13); + mv.visitLineNumber(137, l13); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 7); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "storeContainer", "(Lnet/minecraft/inventory/IInventory;IILnet/minecraft/item/ItemStack;)V", false); + mv.visitLabel(l11); + mv.visitLineNumber(139, l11); + mv.visitFrame(F_FULL, 9, new Object[] {"net/minecraftforge/fluids/IFluidHandler", "net/minecraft/inventory/IInventory", INTEGER, INTEGER, "net/minecraftforge/fluids/Fluid", "net/minecraft/item/ItemStack", "net/minecraft/item/ItemStack", "mods/railcraft/common/fluids/FluidItemHelper$FillReturn", "net/minecraftforge/fluids/FluidStack"}, 0, new Object[] {}); + mv.visitInsn(ICONST_1); + mv.visitInsn(IRETURN); + mv.visitLabel(l6); + mv.visitLineNumber(142, l6); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLocalVariable("drain", "Lnet/minecraftforge/fluids/FluidStack;", null, l8, l6, 8); + mv.visitLocalVariable("fluidHandler", "Lnet/minecraftforge/fluids/IFluidHandler;", null, l0, l14, 0); + mv.visitLocalVariable("inv", "Lnet/minecraft/inventory/IInventory;", null, l0, l14, 1); + mv.visitLocalVariable("inputSlot", "I", null, l0, l14, 2); + mv.visitLocalVariable("outputSlot", "I", null, l0, l14, 3); + mv.visitLocalVariable("fluidToFill", "Lnet/minecraftforge/fluids/Fluid;", null, l0, l14, 4); + mv.visitLocalVariable("input", "Lnet/minecraft/item/ItemStack;", null, l3, l14, 5); + mv.visitLocalVariable("output", "Lnet/minecraft/item/ItemStack;", null, l4, l14, 6); + mv.visitLocalVariable("fill", "Lmods/railcraft/common/fluids/FluidItemHelper$FillReturn;", null, l5, l14, 7); + mv.visitMaxs(5, 9); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals("drainContainers") && !obfuscated) { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "drainContainers", "(Lnet/minecraftforge/fluids/IFluidHandler;Lnet/minecraft/inventory/IInventory;II)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(146, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "getStackInSlot", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 4); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(147, l1); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 3); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "getStackInSlot", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 5); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(148, l2); + mv.visitVarInsn(ALOAD, 4); + Label l3 = new Label(); + mv.visitJumpInsn(IFNULL, l3); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(149, l4); + mv.visitVarInsn(ALOAD, 4); + mv.visitIntInsn(SIPUSH, PROCESS_VOLUME); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidItemHelper", "drainContainer", "(Lnet/minecraft/item/ItemStack;I)Lmods/railcraft/common/fluids/FluidItemHelper$DrainReturn;", false); + mv.visitVarInsn(ASTORE, 6); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(150, l5); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitJumpInsn(IFNULL, l3); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "container", "Lnet/minecraft/item/ItemStack;"); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "hasPlaceToPutContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z", false); + mv.visitJumpInsn(IFEQ, l3); + mv.visitLabel(l6); + mv.visitLineNumber(151, l6); + mv.visitFrame(F_APPEND,3, new Object[] {"net/minecraft/item/ItemStack", "net/minecraft/item/ItemStack", "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn"}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "fill", "(Lnet/minecraftforge/common/util/ForgeDirection;Lnet/minecraftforge/fluids/FluidStack;Z)I", true); + mv.visitVarInsn(ISTORE, 7); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(152, l7); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "isAtomic", "Z"); + Label l8 = new Label(); + mv.visitJumpInsn(IFEQ, l8); + mv.visitVarInsn(ILOAD, 7); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + Label l9 = new Label(); + mv.visitJumpInsn(IF_ICMPEQ, l9); + mv.visitLabel(l8); + mv.visitFrame(F_APPEND,1, new Object[] {INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "isAtomic", "Z"); + mv.visitJumpInsn(IFNE, l3); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitJumpInsn(IFLE, l3); + mv.visitLabel(l9); + mv.visitLineNumber(153, l9); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "fill", "(Lnet/minecraftforge/common/util/ForgeDirection;Lnet/minecraftforge/fluids/FluidStack;Z)I", true); + mv.visitInsn(POP); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(154, l10); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "storeContainer", "(Lnet/minecraft/inventory/IInventory;IILnet/minecraft/item/ItemStack;)V", false); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(155, l11); + mv.visitInsn(ICONST_1); + mv.visitInsn(IRETURN); + mv.visitLabel(l3); + mv.visitLineNumber(159, l3); + mv.visitFrame(F_CHOP,2, null, 0, null); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLocalVariable("used", "I", null, l7, l3, 7); + mv.visitLocalVariable("drain", "Lmods/railcraft/common/fluids/FluidItemHelper$DrainReturn;", null, l5, l3, 6); + mv.visitLocalVariable("fluidHandler", "Lnet/minecraftforge/fluids/IFluidHandler;", null, l0, l12, 0); + mv.visitLocalVariable("inv", "Lnet/minecraft/inventory/IInventory;", null, l0, l12, 1); + mv.visitLocalVariable("inputSlot", "I", null, l0, l12, 2); + mv.visitLocalVariable("outputSlot", "I", null, l0, l12, 3); + mv.visitLocalVariable("input", "Lnet/minecraft/item/ItemStack;", null, l1, l12, 4); + mv.visitLocalVariable("output", "Lnet/minecraft/item/ItemStack;", null, l2, l12, 5); + mv.visitMaxs(4, 8); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals("drainContainers") && obfuscated) { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "drainContainers", "(Lnet/minecraftforge/fluids/IFluidHandler;Lnet/minecraft/inventory/IInventory;II)Z", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(146, l0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "func_70301_a", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 4); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(147, l1); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 3); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraft/inventory/IInventory", "func_70301_a", "(I)Lnet/minecraft/item/ItemStack;", true); + mv.visitVarInsn(ASTORE, 5); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(148, l2); + mv.visitVarInsn(ALOAD, 4); + Label l3 = new Label(); + mv.visitJumpInsn(IFNULL, l3); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(149, l4); + mv.visitVarInsn(ALOAD, 4); + mv.visitIntInsn(SIPUSH, PROCESS_VOLUME); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidItemHelper", "drainContainer", "(Lnet/minecraft/item/ItemStack;I)Lmods/railcraft/common/fluids/FluidItemHelper$DrainReturn;", false); + mv.visitVarInsn(ASTORE, 6); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(150, l5); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitJumpInsn(IFNULL, l3); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "container", "Lnet/minecraft/item/ItemStack;"); + Label l6 = new Label(); + mv.visitJumpInsn(IFNULL, l6); + mv.visitVarInsn(ALOAD, 5); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "hasPlaceToPutContainer", "(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Z", false); + mv.visitJumpInsn(IFEQ, l3); + mv.visitLabel(l6); + mv.visitLineNumber(151, l6); + mv.visitFrame(F_APPEND,3, new Object[] {"net/minecraft/item/ItemStack", "net/minecraft/item/ItemStack", "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn"}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "fill", "(Lnet/minecraftforge/common/util/ForgeDirection;Lnet/minecraftforge/fluids/FluidStack;Z)I", true); + mv.visitVarInsn(ISTORE, 7); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(152, l7); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "isAtomic", "Z"); + Label l8 = new Label(); + mv.visitJumpInsn(IFEQ, l8); + mv.visitVarInsn(ILOAD, 7); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + Label l9 = new Label(); + mv.visitJumpInsn(IF_ICMPEQ, l9); + mv.visitLabel(l8); + mv.visitFrame(F_APPEND,1, new Object[] {INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "isAtomic", "Z"); + mv.visitJumpInsn(IFNE, l3); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitFieldInsn(GETFIELD, "net/minecraftforge/fluids/FluidStack", "amount", "I"); + mv.visitJumpInsn(IFLE, l3); + mv.visitLabel(l9); + mv.visitLineNumber(153, l9); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETSTATIC, "net/minecraftforge/common/util/ForgeDirection", "UNKNOWN", "Lnet/minecraftforge/common/util/ForgeDirection;"); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "fluidDrained", "Lnet/minecraftforge/fluids/FluidStack;"); + mv.visitInsn(ICONST_1); + mv.visitMethodInsn(INVOKEINTERFACE, "net/minecraftforge/fluids/IFluidHandler", "fill", "(Lnet/minecraftforge/common/util/ForgeDirection;Lnet/minecraftforge/fluids/FluidStack;Z)I", true); + mv.visitInsn(POP); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(154, l10); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ALOAD, 6); + mv.visitFieldInsn(GETFIELD, "mods/railcraft/common/fluids/FluidItemHelper$DrainReturn", "container", "Lnet/minecraft/item/ItemStack;"); + mv.visitMethodInsn(INVOKESTATIC, "mods/railcraft/common/fluids/FluidHelper", "storeContainer", "(Lnet/minecraft/inventory/IInventory;IILnet/minecraft/item/ItemStack;)V", false); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(155, l11); + mv.visitInsn(ICONST_1); + mv.visitInsn(IRETURN); + mv.visitLabel(l3); + mv.visitLineNumber(159, l3); + mv.visitFrame(F_CHOP,2, null, 0, null); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLocalVariable("used", "I", null, l7, l3, 7); + mv.visitLocalVariable("drain", "Lmods/railcraft/common/fluids/FluidItemHelper$DrainReturn;", null, l5, l3, 6); + mv.visitLocalVariable("fluidHandler", "Lnet/minecraftforge/fluids/IFluidHandler;", null, l0, l12, 0); + mv.visitLocalVariable("inv", "Lnet/minecraft/inventory/IInventory;", null, l0, l12, 1); + mv.visitLocalVariable("inputSlot", "I", null, l0, l12, 2); + mv.visitLocalVariable("outputSlot", "I", null, l0, l12, 3); + mv.visitLocalVariable("input", "Lnet/minecraft/item/ItemStack;", null, l1, l12, 4); + mv.visitLocalVariable("output", "Lnet/minecraft/item/ItemStack;", null, l2, l12, 5); + mv.visitMaxs(4, 8); + mv.visitEnd(); + didInject = true; + } + + FMLRelaunchLog.log("[GT++ ASM] Railcraft PROCESS_VOLUME Patch", Level.INFO, "Method injection complete. "+(obfuscated ? "Obfuscated" : "Non-Obfuscated")); + return didInject; + } + + + + + + + + + + public class AddFieldAdapter extends ClassVisitor { + + public AddFieldAdapter(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + @Override + public FieldVisitor visitField( + int access, String name, String desc, String signature, Object value) { + if (name.equals("PROCESS_VOLUME") && desc.equals("I")) { + FMLRelaunchLog.log("[GT++ ASM] Railcraft PROCESS_VOLUME Patch", Level.INFO, "Removing "+"PROCESS_VOLUME"+"."); + return null; + } + return cv.visitField(access, name, desc, signature, value); + } + + + private final String[] aMethodsToStrip = new String[] {"fillContainers", "drainContainers"}; + + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + + MethodVisitor methodVisitor; + boolean found = false; + + for (String s : aMethodsToStrip) { + if (name.equals(s)) { + found = true; + break; + } + } + if (!found) { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + else { + methodVisitor = null; + } + + if (found) { + FMLRelaunchLog.log("[GT++ ASM] Railcraft PROCESS_VOLUME Patch", Level.INFO, + "Found method " + name + ", removing."); + } + return methodVisitor; + } + + + } + + + + + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_InvTools.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_InvTools.java new file mode 100644 index 0000000000..75896c1c0f --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_InvTools.java @@ -0,0 +1,235 @@ +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.ARETURN; +import static org.objectweb.asm.Opcodes.ASM5; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; + +import java.lang.reflect.Method; + +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 gregtech.api.enums.GT_Values; +import gtPlusPlus.core.util.minecraft.ItemUtils; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +public class ClassTransformer_Railcraft_InvTools { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + private boolean obfuscated = true; + + + public static ItemStack depleteItem(ItemStack stack) { + if (stack == null) { + return GT_Values.NI; + } else { + if (stack.stackSize == 0) { + return GT_Values.NI; + } + else if (stack.stackSize == 1) { + ItemStack container = stack.getItem().getContainerItem(stack); + if (container != null) { + return container; + } else { + return GT_Values.NI; + } + } + else { + return ItemUtils.depleteStack(stack); + } + } + } + + public ClassTransformer_Railcraft_InvTools(byte[] basicClass, boolean obfuscated2) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + boolean devEnv = false; + boolean a1 = false; + boolean a2 = false; + + //Find Non-Obf method + try { + Method aGetStackInSlot = IInventory.class.getDeclaredMethod("getStackInSlot", int.class); + if (aGetStackInSlot != null) { + a1 = true; + } + } catch (NoSuchMethodException | SecurityException e) {} + + //Find Obf method + try { + Method aGetStackInSlotObf = IInventory.class.getDeclaredMethod("func_70301_a", int.class); + if (aGetStackInSlotObf != null) { + a2 = true; + } + } catch (NoSuchMethodException | SecurityException e) {} + + + if (a1) { + devEnv = false; + } + else if (a2) { + devEnv = true; + } + else { + //Fallback + devEnv = false; + } + + if (obfuscated && devEnv) { + + } + else { + + + } + + + + FMLRelaunchLog.log("[GT++ ASM] Railcraft negative ItemStack Fix", Level.INFO, "Are we patching obfuscated method? "+obfuscated); + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new AddFieldAdapter(aTempWriter), 0); + + injectMethod("depleteItem", aTempWriter, obfuscated); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + + FMLRelaunchLog.log("[GT++ ASM] Railcraft negative ItemStack Fix", Level.INFO, "Valid? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(String aMethodName, ClassWriter cw, boolean obfuscated) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Railcraft negative ItemStack Fix", Level.INFO, "Injecting " + aMethodName + "."); + if (aMethodName.equals("depleteItem") && !obfuscated) { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "depleteItem", "(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(36, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_InvTools", "depleteItem", "(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("stack", "Lnet/minecraft/item/ItemStack;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals("depleteItem") && obfuscated) { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "depleteItem", "(Ladd;)Ladd;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(36, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_Railcraft_InvTools", "depleteItem", "(Ladd;)Ladd;", false); + mv.visitInsn(ARETURN); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLocalVariable("stack", "Ladd;", null, l0, l1, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + } + FMLRelaunchLog.log("[GT++ ASM] Railcraft negative ItemStack Fix", Level.INFO, "Method injection complete. "+(obfuscated ? "Obfuscated" : "Non-Obfuscated")); + return didInject; + } + + + + + + + + + + public class AddFieldAdapter extends ClassVisitor { + + public AddFieldAdapter(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + private final String[] aMethodsToStrip = new String[] {"depleteItem"}; + + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + + MethodVisitor methodVisitor; + boolean found = false; + + for (String s : aMethodsToStrip) { + if (name.equals(s)) { + found = true; + break; + } + } + if (!found) { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + else { + if (desc.equals("(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;")) { + obfuscated = false; + } + else if (desc.equals("(Ladd;)Ladd;")) { + obfuscated = true; + } + else { + obfuscated = false; + } + FMLRelaunchLog.log("[GT++ ASM] Railcraft negative ItemStack Fix", Level.INFO, + "Method desc " + desc + ", using "+(obfuscated ? "obfuscated method handler" : "deobfuscated method handler")); + methodVisitor = null; + } + + if (found) { + FMLRelaunchLog.log("[GT++ ASM] Railcraft negative ItemStack Fix", Level.INFO, + "Found method " + name + ", removing."); + } + return methodVisitor; + } + + + } + + + + + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ItemWispEssence.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ItemWispEssence.java new file mode 100644 index 0000000000..8f65709478 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ItemWispEssence.java @@ -0,0 +1,278 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.AALOAD; +import static org.objectweb.asm.Opcodes.ACC_PUBLIC; +import static org.objectweb.asm.Opcodes.ACONST_NULL; +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ARETURN; +import static org.objectweb.asm.Opcodes.ARRAYLENGTH; +import static org.objectweb.asm.Opcodes.ASM5; +import static org.objectweb.asm.Opcodes.ASTORE; +import static org.objectweb.asm.Opcodes.DUP; +import static org.objectweb.asm.Opcodes.F_APPEND; +import static org.objectweb.asm.Opcodes.F_CHOP; +import static org.objectweb.asm.Opcodes.F_SAME; +import static org.objectweb.asm.Opcodes.F_SAME1; +import static org.objectweb.asm.Opcodes.GETSTATIC; +import static org.objectweb.asm.Opcodes.GOTO; +import static org.objectweb.asm.Opcodes.I2L; +import static org.objectweb.asm.Opcodes.ICONST_0; +import static org.objectweb.asm.Opcodes.IFEQ; +import static org.objectweb.asm.Opcodes.IFLE; +import static org.objectweb.asm.Opcodes.IFNONNULL; +import static org.objectweb.asm.Opcodes.IFNULL; +import static org.objectweb.asm.Opcodes.ILOAD; +import static org.objectweb.asm.Opcodes.INVOKESPECIAL; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; +import static org.objectweb.asm.Opcodes.IRETURN; +import static org.objectweb.asm.Opcodes.ISTORE; +import static org.objectweb.asm.Opcodes.L2I; +import static org.objectweb.asm.Opcodes.LDIV; +import static org.objectweb.asm.Opcodes.LREM; +import static org.objectweb.asm.Opcodes.NEW; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.AnnotationVisitor; +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_TC_ItemWispEssence { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + public ClassTransformer_TC_ItemWispEssence(byte[] basicClass, boolean obfuscated2) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + boolean obfuscated = obfuscated2; + FMLRelaunchLog.log("[GT++ ASM] Thaumcraft WispEssence_Patch", Level.INFO, "Are we patching obfuscated methods? "+obfuscated); + String aGetColour = obfuscated ? DevHelper.getSRG("getColorFromItemStack") : "getColorFromItemStack"; + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new AddAdapter(aTempWriter, new String[] {"getAspects", aGetColour}), 0); + injectMethod("getAspects", aTempWriter, obfuscated); + injectMethod(aGetColour, aTempWriter, obfuscated); + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + FMLRelaunchLog.log("[GT++ ASM] Thaumcraft WispEssence_Patch", Level.INFO, "Valid? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethod(String aMethodName, ClassWriter cw, boolean obfuscated) { + MethodVisitor mv; + boolean didInject = false; + FMLRelaunchLog.log("[GT++ ASM] Thaumcraft WispEssence_Patch", Level.INFO, "Injecting " + aMethodName + "."); + + String aGetColour = obfuscated ? "func_82790_a" : "getColorFromItemStack"; + String aHasTagCompound = obfuscated ? "func_77942_o" : "hasTagCompound"; + String aGetTagCompound = obfuscated ? "func_77978_p" : "getTagCompound"; + + if (aMethodName.equals("getAspects")) { + mv = cw.visitMethod(ACC_PUBLIC, "getAspects", "(Lnet/minecraft/item/ItemStack;)Lthaumcraft/api/aspects/AspectList;", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(141, l0); + mv.visitVarInsn(ALOAD, 1); + Label l1 = new Label(); + mv.visitJumpInsn(IFNONNULL, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(142, l2); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + mv.visitLabel(l1); + mv.visitLineNumber(144, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", aHasTagCompound, "()Z", false); + Label l3 = new Label(); + mv.visitJumpInsn(IFEQ, l3); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(145, l4); + mv.visitTypeInsn(NEW, "thaumcraft/api/aspects/AspectList"); + mv.visitInsn(DUP); + mv.visitMethodInsn(INVOKESPECIAL, "thaumcraft/api/aspects/AspectList", "<init>", "()V", false); + mv.visitVarInsn(ASTORE, 2); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(146, l5); + mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "net/minecraft/item/ItemStack", aGetTagCompound, "()Lnet/minecraft/nbt/NBTTagCompound;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/api/aspects/AspectList", "readFromNBT", "(Lnet/minecraft/nbt/NBTTagCompound;)V", false); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(147, l6); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/api/aspects/AspectList", "size", "()I", false); + Label l7 = new Label(); + mv.visitJumpInsn(IFLE, l7); + mv.visitVarInsn(ALOAD, 2); + Label l8 = new Label(); + mv.visitJumpInsn(GOTO, l8); + mv.visitLabel(l7); + mv.visitFrame(F_APPEND,1, new Object[] {"thaumcraft/api/aspects/AspectList"}, 0, null); + mv.visitInsn(ACONST_NULL); + mv.visitLabel(l8); + mv.visitFrame(F_SAME1, 0, null, 1, new Object[] {"thaumcraft/api/aspects/AspectList"}); + mv.visitInsn(ARETURN); + mv.visitLabel(l3); + mv.visitLineNumber(149, l3); + mv.visitFrame(F_CHOP,1, null, 0, null); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ARETURN); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLocalVariable("this", "LgtPlusPlus/preloader/asm/transformers/ClassTransformer_TC_ItemWispEssence;", null, l0, l9, 0); + mv.visitLocalVariable("itemstack", "Lnet/minecraft/item/ItemStack;", null, l0, l9, 1); + mv.visitLocalVariable("aspects", "Lthaumcraft/api/aspects/AspectList;", null, l5, l3, 2); + mv.visitMaxs(2, 3); + mv.visitEnd(); + didInject = true; + } + else if (aMethodName.equals(aGetColour)) { + + //thaumcraft/common/items/ItemWispEssence + mv = cw.visitMethod(ACC_PUBLIC, aGetColour, "(Lnet/minecraft/item/ItemStack;I)I", null, null); + AnnotationVisitor av0; + { + av0 = mv.visitAnnotation("Lcpw/mods/fml/relauncher/SideOnly;", true); + av0.visitEnum("value", "Lcpw/mods/fml/relauncher/Side;", "CLIENT"); + av0.visitEnd(); + } + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(197, l0); + mv.visitVarInsn(ALOAD, 1); + Label l1 = new Label(); + mv.visitJumpInsn(IFNONNULL, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(198, l2); + mv.visitInsn(ICONST_0); + mv.visitInsn(IRETURN); + mv.visitLabel(l1); + mv.visitLineNumber(200, l1); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/common/items/ItemWispEssence", "getAspects", "(Lnet/minecraft/item/ItemStack;)Lthaumcraft/api/aspects/AspectList;", false); + Label l3 = new Label(); + mv.visitJumpInsn(IFNULL, l3); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(201, l4); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/common/items/ItemWispEssence", "getAspects", "(Lnet/minecraft/item/ItemStack;)Lthaumcraft/api/aspects/AspectList;", false); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/api/aspects/AspectList", "getAspects", "()[Lthaumcraft/api/aspects/Aspect;", false); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/api/aspects/Aspect", "getColor", "()I", false); + mv.visitInsn(IRETURN); + mv.visitLabel(l3); + mv.visitLineNumber(203, l3); + mv.visitFrame(F_SAME, 0, null, 0, null); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false); + mv.visitLdcInsn(new Long(500L)); + mv.visitInsn(LDIV); + mv.visitFieldInsn(GETSTATIC, "thaumcraft/common/items/ItemWispEssence", "displayAspects", "[Lthaumcraft/api/aspects/Aspect;"); + mv.visitInsn(ARRAYLENGTH); + mv.visitInsn(I2L); + mv.visitInsn(LREM); + mv.visitInsn(L2I); + mv.visitVarInsn(ISTORE, 3); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(204, l5); + mv.visitFieldInsn(GETSTATIC, "thaumcraft/common/items/ItemWispEssence", "displayAspects", "[Lthaumcraft/api/aspects/Aspect;"); + mv.visitVarInsn(ILOAD, 3); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/api/aspects/Aspect", "getColor", "()I", false); + mv.visitInsn(IRETURN); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLocalVariable("this", "Lthaumcraft/common/items/ItemWispEssence;", null, l0, l6, 0); + mv.visitLocalVariable("stack", "Lnet/minecraft/item/ItemStack;", null, l0, l6, 1); + mv.visitLocalVariable("par2", "I", null, l0, l6, 2); + mv.visitLocalVariable("idx", "I", null, l5, l6, 3); + mv.visitMaxs(4, 4); + mv.visitEnd(); + didInject = true; + } + + FMLRelaunchLog.log("[GT++ ASM] Thaumcraft WispEssence_Patch", Level.INFO, "Method injection complete. "+(obfuscated ? "Obfuscated" : "Non-Obfuscated")); + return didInject; + } + + public class AddAdapter extends ClassVisitor { + + public AddAdapter(ClassVisitor cv, String[] aMethods) { + super(ASM5, cv); + this.cv = cv; + this.aMethodsToStrip = aMethods; + } + + private final String[] aMethodsToStrip; + + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + + MethodVisitor methodVisitor; + boolean found = false; + + for (String s : aMethodsToStrip) { + if (name.equals(s)) { + found = true; + break; + } + } + if (!found) { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + else { + methodVisitor = null; + } + + if (found) { + FMLRelaunchLog.log("[GT++ ASM] Thaumcraft WispEssence_Patch", Level.INFO, + "Found method " + name + ", removing."); + } + return methodVisitor; + } + + } + + + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TT_ThaumicRestorer.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TT_ThaumicRestorer.java new file mode 100644 index 0000000000..86a22ce4b9 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TT_ThaumicRestorer.java @@ -0,0 +1,611 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.*; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.*; + +import cpw.mods.fml.common.Loader; +import gtPlusPlus.core.util.reflect.ReflectionUtils; +import gtPlusPlus.preloader.Preloader_Logger; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; + +public class ClassTransformer_TT_ThaumicRestorer { + + private final boolean isValid; + private final ClassReader reader; + private final ClassWriter writer; + + private static boolean mInit = false; + + private static Class mTileRepairerClass; + private static Class mTTConfigHandler; + private static Class mTinkersConstructCompat; + private static Class mThaumicTinkerer; + private static Class mTCProxy; + + private static Method mIsTcTool; + private static Method mGetTcDamage; + private static Method mFixTcDamage; + private static Method mSparkle; + private static Method mDrawEssentia; + + private static Field mRepairTiconTools; + private static Field mTicksExisted; + private static Field mInventory; + private static Field mTookLastTick; + private static Field mDamageLastTick; + private static Field mProxyTC; + + private static boolean repairTConTools = false; + + // thaumic.tinkerer.common.block.tile.TileRepairer + + private static final boolean isTConstructTool(ItemStack aStack) { + return ReflectionUtils.invoke(null, mIsTcTool, new Object[] {aStack}); + } + private static final int getDamage(ItemStack aStack) { + return (int) ReflectionUtils.invokeNonBool(null, mGetTcDamage, new Object[] {aStack}); + } + private static final boolean fixDamage(ItemStack aStack, int aAmount) { + return ReflectionUtils.invoke(null, mFixTcDamage, new Object[] {aStack, aAmount}); + } + private static final int drawEssentia(TileEntity aTile) { + return (int) ReflectionUtils.invokeNonBool(aTile, mDrawEssentia, new Object[] {}); + } + private static final void sparkle(float a, float b, float c, int d) { + ReflectionUtils.invokeVoid(ReflectionUtils.getFieldValue(mProxyTC), mSparkle, new Object[] {a, b, c, d}); + } + + public static void updateEntity(TileEntity aTile) { + if (!mInit) { + // Set the classes we need + mTileRepairerClass = ReflectionUtils.getClass("thaumic.tinkerer.common.block.tile.TileRepairer"); + mTTConfigHandler = ReflectionUtils.getClass("thaumic.tinkerer.common.core.handler.ConfigHandler"); + mTinkersConstructCompat = ReflectionUtils.getClass("thaumic.tinkerer.common.compat.TinkersConstructCompat"); + mThaumicTinkerer = ReflectionUtils.getClass("thaumic.tinkerer.common.ThaumicTinkerer"); + mTCProxy = ReflectionUtils.getClass("thaumcraft.common.CommonProxy"); + // Set the methods we need + mIsTcTool = ReflectionUtils.getMethod(mTinkersConstructCompat, "isTConstructTool", new Class[] {ItemStack.class}); + mGetTcDamage = ReflectionUtils.getMethod(mTinkersConstructCompat, "getDamage", new Class[] {ItemStack.class}); + mFixTcDamage = ReflectionUtils.getMethod(mTinkersConstructCompat, "fixDamage", new Class[] {ItemStack.class, int.class}); + mSparkle = ReflectionUtils.getMethod(mTCProxy, "sparkle", new Class[] {float.class, float.class, float.class, int.class}); + mDrawEssentia = ReflectionUtils.getMethod(mTileRepairerClass, "drawEssentia", new Class[] {}); + // Set the fields we need + mRepairTiconTools = ReflectionUtils.getField(mTTConfigHandler, "repairTConTools"); + mTicksExisted = ReflectionUtils.getField(mTileRepairerClass, "ticksExisted"); + mInventory = ReflectionUtils.getField(mTileRepairerClass, "inventorySlots"); + mTookLastTick = ReflectionUtils.getField(mTileRepairerClass, "tookLastTick"); + mDamageLastTick = ReflectionUtils.getField(mTileRepairerClass, "dmgLastTick"); + mProxyTC = ReflectionUtils.getField(mThaumicTinkerer, "tcProxy"); + repairTConTools = ReflectionUtils.getFieldValue(mRepairTiconTools); + mInit = true; + } + if (mInit) { + if (mTileRepairerClass.isInstance(aTile)) { + int ticksExisted = (int) ReflectionUtils.getFieldValue(mTicksExisted, aTile); + ItemStack[] inventorySlots = (ItemStack[]) ReflectionUtils.getFieldValue(mInventory, aTile); + boolean tookLastTick = (boolean) ReflectionUtils.getFieldValue(mTookLastTick, aTile); + int dmgLastTick = (int) ReflectionUtils.getFieldValue(mDamageLastTick, aTile); + ticksExisted++; + ReflectionUtils.setField(aTile, mTicksExisted, ticksExisted); + boolean aDidRun = false; + if (ticksExisted % 10 == 0) { + if (Loader.isModLoaded("TConstruct") && repairTConTools && inventorySlots[0] != null && isTConstructTool(inventorySlots[0])) { + final int dmg = getDamage(inventorySlots[0]); + if (dmg > 0) { + final int essentia = drawEssentia(aTile); + fixDamage(inventorySlots[0], essentia); + aTile.markDirty(); + if (dmgLastTick != 0 && dmgLastTick != dmg) { + sparkle((float)(aTile.xCoord + 0.25 + Math.random() / 2.0), (float)(aTile.yCoord + 1 + Math.random() / 2.0), (float)(aTile.zCoord + 0.25 + Math.random() / 2.0), 0); + tookLastTick = true; + } + else { + tookLastTick = false; + } + } + else { + tookLastTick = false; + } + dmgLastTick = ((inventorySlots[0] == null) ? 0 : getDamage(inventorySlots[0])); + aDidRun = true; + } + if (inventorySlots[0] != null && inventorySlots[0].getItemDamage() > 0 && inventorySlots[0].getItem().isRepairable()) { + final int essentia2 = drawEssentia(aTile); + final int dmg2 = inventorySlots[0].getItemDamage(); + inventorySlots[0].setItemDamage(Math.max(0, dmg2 - essentia2)); + aTile.markDirty(); + if (dmgLastTick != 0 && dmgLastTick != dmg2) { + sparkle((float)(aTile.xCoord + 0.25 + Math.random() / 2.0), (float)(aTile.yCoord + 1 + Math.random() / 2.0), (float)(aTile.zCoord + 0.25 + Math.random() / 2.0), 0); + tookLastTick = true; + } + else { + tookLastTick = false; + } + } + else { + tookLastTick = false; + } + dmgLastTick = ((inventorySlots[0] == null) ? 0 : inventorySlots[0].getItemDamage()); + aDidRun = true; + } + if (aDidRun) { + ReflectionUtils.setField(aTile, mInventory, inventorySlots); + ReflectionUtils.setField(aTile, mTookLastTick, tookLastTick); + ReflectionUtils.setField(aTile, mDamageLastTick, dmgLastTick); + } + } + } + } + + public ClassTransformer_TT_ThaumicRestorer(byte[] basicClass) { + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + boolean obfuscated = false; + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + AddAdapter aMethodStripper = new AddAdapter(aTempWriter); + aTempReader.accept(aMethodStripper, 0); + obfuscated = aMethodStripper.isObfuscated; + String aUpdateEntity = obfuscated ? "func_145845_h" : "updateEntity"; + Preloader_Logger.LOG("Thaumic Tinkerer RepairItem Patch", Level.INFO, "Patching: "+aUpdateEntity+", Are we patching obfuscated methods? "+obfuscated); + //injectMethod(aUpdateEntity, aTempWriter, obfuscated); + injectMethodNew(aTempWriter, obfuscated); + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + Preloader_Logger.LOG("Thaumic Tinkerer RepairItem Patch", Level.INFO, "Valid? "+isValid+"."); + reader = aTempReader; + writer = aTempWriter; + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public boolean injectMethodNew(ClassWriter cw, boolean obfuscated) { + MethodVisitor mv; + boolean didInject = false; + String aUpdateEntity = obfuscated ? "func_145845_h" : "updateEntity"; + String aTileEntity = obfuscated ? "aor" : "net/minecraft/tileentity/TileEntity"; + Preloader_Logger.LOG("Thaumic Tinkerer RepairItem Patch", Level.INFO, "Injecting " + aUpdateEntity + "."); + mv = cw.visitMethod(ACC_PUBLIC, aUpdateEntity, "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(60, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_TT_ThaumicRestorer", "updateEntity", "(L"+aTileEntity+";)V", false); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(61, l1); + mv.visitInsn(RETURN); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLocalVariable("this", "Lthaumic/tinkerer/common/block/tile/TileRepairer;", null, l0, l2, 0); + mv.visitMaxs(1, 1); + mv.visitEnd(); + didInject = true; + Preloader_Logger.LOG("Thaumic Tinkerer RepairItem Patch", Level.INFO, "Method injection complete. "+(obfuscated ? "Obfuscated" : "Non-Obfuscated")); + return didInject; + } + + public boolean injectMethod(String aMethodName, ClassWriter cw, boolean obfuscated) { + MethodVisitor mv; + boolean didInject = false; + Preloader_Logger.LOG("Thaumic Tinkerer RepairItem Patch", Level.INFO, "Injecting " + aMethodName + "."); + + String aItemStack = obfuscated ? "add" : "net/minecraft/item/ItemStack"; + String aItem = obfuscated ? "adb" : "net/minecraft/item/Item"; + String aGetItemDamage = obfuscated ? "func_150976_a" : "getItemDamage"; + String aGetItem = obfuscated ? "func_77973_b" : "getItem"; + String aSetItemDamage = obfuscated ? "func_77964_b" : "setItemDamage"; + String aIsRepairable = obfuscated ? "func_82789_a" : "isRepairable"; + + mv = cw.visitMethod(ACC_PUBLIC, aMethodName, "()V", null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(59, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(DUP); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "ticksExisted", "I"); + mv.visitInsn(ICONST_1); + mv.visitInsn(IADD); + mv.visitInsn(DUP_X1); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "ticksExisted", "I"); + mv.visitIntInsn(BIPUSH, 10); + mv.visitInsn(IREM); + Label l1 = new Label(); + mv.visitJumpInsn(IFNE, l1); + Label l2 = new Label(); + mv.visitLabel(l2); + mv.visitLineNumber(60, l2); + mv.visitLdcInsn("TConstruct"); + mv.visitMethodInsn(INVOKESTATIC, "cpw/mods/fml/common/Loader", "isModLoaded", "(Ljava/lang/String;)Z", false); + Label l3 = new Label(); + mv.visitJumpInsn(IFEQ, l3); + mv.visitFieldInsn(GETSTATIC, "thaumic/tinkerer/common/core/handler/ConfigHandler", "repairTConTools", "Z"); + mv.visitJumpInsn(IFEQ, l3); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLineNumber(61, l4); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitJumpInsn(IFNULL, l3); + Label l5 = new Label(); + mv.visitLabel(l5); + mv.visitLineNumber(62, l5); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKESTATIC, "thaumic/tinkerer/common/compat/TinkersConstructCompat", "isTConstructTool", "(L"+aItemStack+";)Z", false); + mv.visitJumpInsn(IFEQ, l3); + Label l6 = new Label(); + mv.visitLabel(l6); + mv.visitLineNumber(63, l6); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKESTATIC, "thaumic/tinkerer/common/compat/TinkersConstructCompat", "getDamage", "(L"+aItemStack+";)I", false); + mv.visitVarInsn(ISTORE, 1); + Label l7 = new Label(); + mv.visitLabel(l7); + mv.visitLineNumber(64, l7); + mv.visitVarInsn(ILOAD, 1); + Label l8 = new Label(); + mv.visitJumpInsn(IFLE, l8); + Label l9 = new Label(); + mv.visitLabel(l9); + mv.visitLineNumber(65, l9); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumic/tinkerer/common/block/tile/TileRepairer", "drawEssentia", "()I", false); + mv.visitVarInsn(ISTORE, 2); + Label l10 = new Label(); + mv.visitLabel(l10); + mv.visitLineNumber(66, l10); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitVarInsn(ILOAD, 2); + mv.visitMethodInsn(INVOKESTATIC, "thaumic/tinkerer/common/compat/TinkersConstructCompat", "fixDamage", "(L"+aItemStack+";I)Z", false); + mv.visitInsn(POP); + Label l11 = new Label(); + mv.visitLabel(l11); + mv.visitLineNumber(67, l11); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumic/tinkerer/common/block/tile/TileRepairer", "markDirty", "()V", false); + Label l12 = new Label(); + mv.visitLabel(l12); + mv.visitLineNumber(68, l12); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "dmgLastTick", "I"); + Label l13 = new Label(); + mv.visitJumpInsn(IFEQ, l13); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "dmgLastTick", "I"); + mv.visitVarInsn(ILOAD, 1); + mv.visitJumpInsn(IF_ICMPEQ, l13); + Label l14 = new Label(); + mv.visitLabel(l14); + mv.visitLineNumber(69, l14); + mv.visitFieldInsn(GETSTATIC, "thaumic/tinkerer/common/ThaumicTinkerer", "tcProxy", "Lthaumcraft/common/CommonProxy;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "xCoord", "I"); + mv.visitInsn(I2D); + mv.visitLdcInsn(new Double("0.25")); + mv.visitInsn(DADD); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "random", "()D", false); + mv.visitLdcInsn(new Double("2.0")); + mv.visitInsn(DDIV); + mv.visitInsn(DADD); + mv.visitInsn(D2F); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "yCoord", "I"); + mv.visitInsn(ICONST_1); + mv.visitInsn(IADD); + mv.visitInsn(I2D); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "random", "()D", false); + mv.visitLdcInsn(new Double("2.0")); + mv.visitInsn(DDIV); + mv.visitInsn(DADD); + mv.visitInsn(D2F); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "zCoord", "I"); + mv.visitInsn(I2D); + mv.visitLdcInsn(new Double("0.25")); + mv.visitInsn(DADD); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "random", "()D", false); + mv.visitLdcInsn(new Double("2.0")); + mv.visitInsn(DDIV); + mv.visitInsn(DADD); + mv.visitInsn(D2F); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/common/CommonProxy", "sparkle", "(FFFI)V", false); + Label l15 = new Label(); + mv.visitLabel(l15); + mv.visitLineNumber(70, l15); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ICONST_1); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "tookLastTick", "Z"); + Label l16 = new Label(); + mv.visitLabel(l16); + mv.visitLineNumber(71, l16); + Label l17 = new Label(); + mv.visitJumpInsn(GOTO, l17); + mv.visitLabel(l13); + mv.visitFrame(Opcodes.F_APPEND,2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ICONST_0); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "tookLastTick", "Z"); + Label l18 = new Label(); + mv.visitLabel(l18); + mv.visitLineNumber(72, l18); + mv.visitJumpInsn(GOTO, l17); + mv.visitLabel(l8); + mv.visitFrame(Opcodes.F_CHOP,1, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ICONST_0); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "tookLastTick", "Z"); + mv.visitLabel(l17); + mv.visitLineNumber(73, l17); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + Label l19 = new Label(); + mv.visitJumpInsn(IFNONNULL, l19); + mv.visitInsn(ICONST_0); + Label l20 = new Label(); + mv.visitJumpInsn(GOTO, l20); + mv.visitLabel(l19); + mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"thaumic/tinkerer/common/block/tile/TileRepairer"}); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKESTATIC, "thaumic/tinkerer/common/compat/TinkersConstructCompat", "getDamage", "(L"+aItemStack+";)I", false); + mv.visitLabel(l20); + mv.visitFrame(Opcodes.F_FULL, 2, new Object[] {"thaumic/tinkerer/common/block/tile/TileRepairer", Opcodes.INTEGER}, 2, new Object[] {"thaumic/tinkerer/common/block/tile/TileRepairer", Opcodes.INTEGER}); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "dmgLastTick", "I"); + Label l21 = new Label(); + mv.visitLabel(l21); + mv.visitLineNumber(74, l21); + mv.visitInsn(RETURN); + mv.visitLabel(l3); + mv.visitLineNumber(78, l3); + mv.visitFrame(Opcodes.F_CHOP,1, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + Label l22 = new Label(); + mv.visitJumpInsn(IFNULL, l22); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItemStack+"", ""+aGetItemDamage+"", "()I", false); + mv.visitJumpInsn(IFLE, l22); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItemStack+"", ""+aGetItem+"", "()L"+aItem+";", false); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItem+"", ""+aIsRepairable+"", "()Z", false); + mv.visitJumpInsn(IFEQ, l22); + Label l23 = new Label(); + mv.visitLabel(l23); + mv.visitLineNumber(79, l23); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumic/tinkerer/common/block/tile/TileRepairer", "drawEssentia", "()I", false); + mv.visitVarInsn(ISTORE, 1); + Label l24 = new Label(); + mv.visitLabel(l24); + mv.visitLineNumber(80, l24); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItemStack+"", ""+aGetItemDamage+"", "()I", false); + mv.visitVarInsn(ISTORE, 2); + Label l25 = new Label(); + mv.visitLabel(l25); + mv.visitLineNumber(81, l25); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitInsn(ICONST_0); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 1); + mv.visitInsn(ISUB); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "max", "(II)I", false); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItemStack+"", ""+aSetItemDamage+"", "(I)V", false); + Label l26 = new Label(); + mv.visitLabel(l26); + mv.visitLineNumber(82, l26); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumic/tinkerer/common/block/tile/TileRepairer", "markDirty", "()V", false); + Label l27 = new Label(); + mv.visitLabel(l27); + mv.visitLineNumber(84, l27); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "dmgLastTick", "I"); + Label l28 = new Label(); + mv.visitJumpInsn(IFEQ, l28); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "dmgLastTick", "I"); + mv.visitVarInsn(ILOAD, 2); + mv.visitJumpInsn(IF_ICMPEQ, l28); + Label l29 = new Label(); + mv.visitLabel(l29); + mv.visitLineNumber(85, l29); + mv.visitFieldInsn(GETSTATIC, "thaumic/tinkerer/common/ThaumicTinkerer", "tcProxy", "Lthaumcraft/common/CommonProxy;"); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "xCoord", "I"); + mv.visitInsn(I2D); + mv.visitLdcInsn(new Double("0.25")); + mv.visitInsn(DADD); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "random", "()D", false); + mv.visitLdcInsn(new Double("2.0")); + mv.visitInsn(DDIV); + mv.visitInsn(DADD); + mv.visitInsn(D2F); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "yCoord", "I"); + mv.visitInsn(ICONST_1); + mv.visitInsn(IADD); + mv.visitInsn(I2D); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "random", "()D", false); + mv.visitLdcInsn(new Double("2.0")); + mv.visitInsn(DDIV); + mv.visitInsn(DADD); + mv.visitInsn(D2F); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "zCoord", "I"); + mv.visitInsn(I2D); + mv.visitLdcInsn(new Double("0.25")); + mv.visitInsn(DADD); + mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "random", "()D", false); + mv.visitLdcInsn(new Double("2.0")); + mv.visitInsn(DDIV); + mv.visitInsn(DADD); + mv.visitInsn(D2F); + mv.visitInsn(ICONST_0); + mv.visitMethodInsn(INVOKEVIRTUAL, "thaumcraft/common/CommonProxy", "sparkle", "(FFFI)V", false); + Label l30 = new Label(); + mv.visitLabel(l30); + mv.visitLineNumber(86, l30); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ICONST_1); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "tookLastTick", "Z"); + Label l31 = new Label(); + mv.visitLabel(l31); + mv.visitLineNumber(87, l31); + Label l32 = new Label(); + mv.visitJumpInsn(GOTO, l32); + mv.visitLabel(l28); + mv.visitFrame(Opcodes.F_APPEND,2, new Object[] {Opcodes.INTEGER, Opcodes.INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ICONST_0); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "tookLastTick", "Z"); + Label l33 = new Label(); + mv.visitLabel(l33); + mv.visitLineNumber(88, l33); + mv.visitJumpInsn(GOTO, l32); + mv.visitLabel(l22); + mv.visitFrame(Opcodes.F_CHOP,2, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ICONST_0); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "tookLastTick", "Z"); + mv.visitLabel(l32); + mv.visitLineNumber(90, l32); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + Label l34 = new Label(); + mv.visitJumpInsn(IFNONNULL, l34); + mv.visitInsn(ICONST_0); + Label l35 = new Label(); + mv.visitJumpInsn(GOTO, l35); + mv.visitLabel(l34); + mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"thaumic/tinkerer/common/block/tile/TileRepairer"}); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "inventorySlots", "[L"+aItemStack+";"); + mv.visitInsn(ICONST_0); + mv.visitInsn(AALOAD); + mv.visitMethodInsn(INVOKEVIRTUAL, ""+aItemStack+"", ""+aGetItemDamage+"", "()I", false); + mv.visitLabel(l35); + mv.visitFrame(Opcodes.F_FULL, 1, new Object[] {"thaumic/tinkerer/common/block/tile/TileRepairer"}, 2, new Object[] {"thaumic/tinkerer/common/block/tile/TileRepairer", Opcodes.INTEGER}); + mv.visitFieldInsn(PUTFIELD, "thaumic/tinkerer/common/block/tile/TileRepairer", "dmgLastTick", "I"); + mv.visitLabel(l1); + mv.visitLineNumber(92, l1); + mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); + mv.visitInsn(RETURN); + Label l36 = new Label(); + mv.visitLabel(l36); + mv.visitLocalVariable("this", "Lthaumic/tinkerer/common/block/tile/TileRepairer;", null, l0, l36, 0); + mv.visitLocalVariable("dmg", "I", null, l7, l3, 1); + mv.visitLocalVariable("essentia", "I", null, l10, l18, 2); + mv.visitLocalVariable("essentia", "I", null, l24, l33, 1); + mv.visitLocalVariable("dmg", "I", null, l25, l33, 2); + mv.visitMaxs(9, 3); + mv.visitEnd(); + didInject = true; + Preloader_Logger.LOG("Thaumic Tinkerer RepairItem Patch", Level.INFO, "Method injection complete. "+(obfuscated ? "Obfuscated" : "Non-Obfuscated")); + return didInject; + } + + public class AddAdapter extends ClassVisitor { + + public AddAdapter(ClassVisitor cv) { + super(ASM5, cv); + this.cv = cv; + } + + private final String[] aMethodsToStrip = new String[] {"updateEntity", "func_145845_h"}; + public boolean isObfuscated = false; + + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + + MethodVisitor methodVisitor; + boolean found = false; + + for (String s : aMethodsToStrip) { + if (name.equals(s)) { + found = true; + if (s.equals(aMethodsToStrip[1])) { + isObfuscated = true; + } + break; + } + } + if (!found) { + methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + } + else { + methodVisitor = null; + } + + if (found) { + Preloader_Logger.LOG("Thaumic Tinkerer RepairItem Patch", Level.INFO, + "Found method " + name + ", removing."); + } + return methodVisitor; + } + + } + + + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TiConFluids.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TiConFluids.java new file mode 100644 index 0000000000..083041050d --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_TiConFluids.java @@ -0,0 +1,164 @@ +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_TiConFluids { + + + //Leftover Code, in case I ever want to inject interfaces. + //private static final String cloneableInterface = "java/lang/Cloneable"; + + //The qualified name of the class we plan to transform. + private static final String className = "tconstruct.smeltery.blocks.TConstructFluid"; + + private final boolean isValid; + private final boolean isObfuscated; + private final String methodName; + private final ClassReader reader; + private final ClassWriter writer; + + public ClassTransformer_TiConFluids(String aMethodName, boolean obfuscated, byte[] basicClass) { + isObfuscated = obfuscated; + + methodName = obfuscated ? DevHelper.getSRG(aMethodName) : aMethodName; + + ClassReader aTempReader = null; + ClassWriter aTempWriter = null; + + aTempReader = new ClassReader(basicClass); + aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES); + aTempReader.accept(new localClassVisitir(aTempWriter, isObfuscated), 0); + + if (aTempReader != null && aTempWriter != null) { + isValid = true; + } + else { + isValid = false; + } + reader = aTempReader; + writer = aTempWriter; + + if (reader != null && writer != null) { + injectMethod(); + } + + } + + public boolean isValidTransformer() { + return isValid; + } + + public ClassReader getReader() { + return reader; + } + + public ClassWriter getWriter() { + return writer; + } + + public void injectMethod() { + if (isValidTransformer()) { + FMLRelaunchLog.log("[GT++ ASM] Bright Fluids", Level.INFO, "Injecting "+methodName+" into "+className+". ["+(isObfuscated ? "Obfuscated" : "Unobfuscated")+"]"); + //Account for Obfuscated constructor args. + String IBlockAccessName = isObfuscated ? "ahl" : "net/minecraft/world/IBlockAccess"; + String aConstructorTypes = "(L"+IBlockAccessName+";III)I"; + + MethodVisitor mv = getWriter().visitMethod(ACC_PUBLIC, methodName, aConstructorTypes, null, null); + mv.visitCode(); + Label l0 = new Label(); + mv.visitLabel(l0); + mv.visitLineNumber(17, l0); + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, "tconstruct/smeltery/blocks/TConstructFluid", "maxScaledLight", "I"); + mv.visitVarInsn(ISTORE, 5); + Label l1 = new Label(); + mv.visitLabel(l1); + mv.visitLineNumber(18, l1); + mv.visitVarInsn(ILOAD, 5); + Label l2 = new Label(); + mv.visitJumpInsn(IFLE, l2); + Label l3 = new Label(); + mv.visitLabel(l3); + mv.visitLineNumber(19, l3); + mv.visitVarInsn(ILOAD, 5); + mv.visitInsn(IRETURN); + mv.visitLabel(l2); + mv.visitLineNumber(21, l2); + mv.visitFrame(F_APPEND,1, new Object[] {INTEGER}, 0, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ILOAD, 4); + //net.minecraftforge.fluids.BlockFluidClassic.getLightValue(IBlockAccess, int, int, int) + mv.visitMethodInsn(INVOKESPECIAL, "net/minecraftforge/fluids/BlockFluidClassic", methodName, aConstructorTypes, false); + mv.visitInsn(IRETURN); + Label l4 = new Label(); + mv.visitLabel(l4); + mv.visitLocalVariable("this", "Ltconstruct/smeltery/blocks/TConstructFluid;", null, l0, l4, 0); + mv.visitLocalVariable("world", "L"+IBlockAccessName+";", null, l0, l4, 1); + mv.visitLocalVariable("x", "I", null, l0, l4, 2); + mv.visitLocalVariable("y", "I", null, l0, l4, 3); + mv.visitLocalVariable("z", "I", null, l0, l4, 4); + mv.visitLocalVariable("maxLight", "I", null, l1, l4, 5); + mv.visitMaxs(5, 6); + mv.visitEnd(); + FMLRelaunchLog.log("[GT++ ASM] Bright Fluids", Level.INFO, "Method injection complete."); + + } + } + + public final class localClassVisitir extends ClassVisitor { + + private final boolean mIsObfuscated; + + public localClassVisitir(ClassVisitor cv, boolean obfuscated) { + super(ASM5, cv); + mIsObfuscated = obfuscated; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + String IBlockAccessName = isObfuscated ? "ahl" : "net/minecraft/world/IBlockAccess"; + String aConstructorTypes = "(L"+IBlockAccessName+";III)I"; + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + if(name.equals(methodName) && desc.equals(aConstructorTypes)) { + FMLRelaunchLog.log("[GT++ ASM] OreDictTransformer", Level.INFO, "Found target method. ["+mIsObfuscated+"]"); + return new localMethodVisitor(methodVisitor, mIsObfuscated); + } + return methodVisitor; + } + + } + + private final class localMethodVisitor extends MethodVisitor { + + private final boolean mObfuscated; + + public localMethodVisitor(MethodVisitor mv, boolean obfuscated) { + super(ASM5, mv); + this.mObfuscated = obfuscated; + } + + @Override + public void visitCode() { + + } + + } + + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer.java new file mode 100644 index 0000000000..05a476c1c8 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer.java @@ -0,0 +1,79 @@ +package gtPlusPlus.preloader.asm.transformers; + +import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ASM5; +import static org.objectweb.asm.Opcodes.IFEQ; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.objectweb.asm.Opcodes.RETURN; + +import org.apache.logging.log4j.Level; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; + +public class Preloader_ClassTransformer { + + public static final class OreDictionaryVisitor extends ClassVisitor { + + public OreDictionaryVisitor(ClassVisitor cv) { + super(ASM5, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); + if(name.equals("registerOreImpl") && desc.equals("(Ljava/lang/String;Lnet/minecraft/item/ItemStack;)V")) { + FMLRelaunchLog.log("[GT++ ASM] OreDictTransformer", Level.INFO, "Found target method. [Unobfuscated]"); + return new RegisterOreImplVisitor(methodVisitor, false); + } + else if(name.equals("registerOreImpl") && desc.equals("(Ljava/lang/String;Ladd;)V")) { + FMLRelaunchLog.log("[GT++ ASM] OreDictTransformer", Level.INFO, "Found target method. [Obfuscated]"); + return new RegisterOreImplVisitor(methodVisitor, true); + } + return methodVisitor; + } + + } + + private static final class RegisterOreImplVisitor extends MethodVisitor { + + private final boolean mObfuscated; + + public RegisterOreImplVisitor(MethodVisitor mv, boolean obfuscated) { + super(ASM5, mv); + this.mObfuscated = obfuscated; + } + + @Override + public void visitCode() { + FMLRelaunchLog.log("[GT++ ASM] OreDictTransformer", Level.INFO, "Fixing Forge's poor attempt at an oreDictionary."); + super.visitCode(); + super.visitVarInsn(ALOAD, 0); + super.visitVarInsn(ALOAD, 1); + if (!mObfuscated){ + FMLRelaunchLog.log("[GT++ ASM] OreDictTransformer", Level.INFO, "Injecting target method. [Unobfuscated]"); + super.visitMethodInsn(INVOKESTATIC, + "gtPlusPlus/preloader/Preloader_GT_OreDict", + "shouldPreventRegistration", + "(Ljava/lang/String;Lnet/minecraft/item/ItemStack;)Z", + false); + } + else { + FMLRelaunchLog.log("[GT++ ASM] OreDictTransformer", Level.INFO, "Injecting target method. [Obfuscated]"); + super.visitMethodInsn(INVOKESTATIC, + "gtPlusPlus/preloader/Preloader_GT_OreDict", + "shouldPreventRegistration", + "(Ljava/lang/String;Ladd;)Z", + false); + } + Label endLabel = new Label(); + super.visitJumpInsn(IFEQ, endLabel); + super.visitInsn(RETURN); + super.visitLabel(endLabel); + } + + } + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer2.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer2.java new file mode 100644 index 0000000000..443337bd35 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_ClassTransformer2.java @@ -0,0 +1,16 @@ +package gtPlusPlus.preloader.asm.transformers; + +public class Preloader_ClassTransformer2 { + + /** + * + * So what I'd try is something like patch a new field into BaseMetaTileEntity to hold the ItemNBT, + * then patch GT_Block_Machines.breakBlock to store the ItemNBT into that field by calling setItemNBT, + * and then patch BaseMetaTileEntity.getDrops to retrieve that field instead of calling setItemNBT + * But there's probably a simpler solution if all you want to do is fix this + * for your super tanks rather than for all GT machines + * (which would only include saving the output count for chest buffers and item distributors...) + * + */ + +} diff --git a/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java b/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java new file mode 100644 index 0000000000..5cb2eef066 --- /dev/null +++ b/src/main/java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java @@ -0,0 +1,286 @@ +package gtPlusPlus.preloader.asm.transformers; + +import cpw.mods.fml.relauncher.CoreModManager; +import cpw.mods.fml.relauncher.ReflectionHelper; +import gtPlusPlus.api.objects.data.AutoMap; +import gtPlusPlus.preloader.CORE_Preloader; +import gtPlusPlus.preloader.DevHelper; +import gtPlusPlus.preloader.Preloader_Logger; +import gtPlusPlus.preloader.asm.AsmConfig; +import gtPlusPlus.preloader.asm.transformers.Preloader_ClassTransformer.OreDictionaryVisitor; +import net.minecraft.launchwrapper.IClassTransformer; +import net.minecraft.launchwrapper.Launch; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; + +import java.io.File; +import java.io.IOException; + +import static gtPlusPlus.preloader.asm.ClassesToTransform.*; + +public class Preloader_Transformer_Handler implements IClassTransformer { + + public static final AsmConfig mConfig; + public static final AutoMap<String> IC2_WRENCH_PATCH_CLASS_NAMES = new AutoMap<String>(); + + static { + mConfig = new AsmConfig(new File("config/GTplusplus/asm.cfg")); + Preloader_Logger.INFO("Config Location: "+AsmConfig.config.getConfigFile().getAbsolutePath()); + Preloader_Logger.INFO("Is DevHelper Valid? "+DevHelper.mIsValidHelper); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_BASE_TILE_ENTITY); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_MACHINE1); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_MACHINE2); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_MACHINE3); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_KINETIC_GENERATOR); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_HEAT_GENERATOR); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_GENERATOR); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_REACTOR_ACCESS_HATCH); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_REACTOR_CHAMBER); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_REACTOR_FLUID_PORT); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_REACTOR_REDSTONE_PORT); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_REACTOR_VESSEL); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_PERSONAL); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_CHARGEPAD); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_ELECTRIC); + IC2_WRENCH_PATCH_CLASS_NAMES.add(IC2_BLOCK_LUMINATOR); + } + + private static Boolean mObf = null; + + public boolean checkObfuscated() { + if (mObf != null) { + return mObf; + } + boolean obfuscated = false; + try { + obfuscated = !(boolean) ReflectionHelper.findField(CoreModManager.class, "deobfuscatedEnvironment").get(null); + } catch (IllegalArgumentException | IllegalAccessException e) { + e.printStackTrace(); + byte[] bs; + try { + bs = Launch.classLoader.getClassBytes("net.minecraft.world.World"); + if (bs != null) { + obfuscated = false; + } else { + obfuscated = true; + } + } catch (IOException e1) { + e1.printStackTrace(); + obfuscated = false; + } + } + mObf = obfuscated; + return obfuscated; + } + + public byte[] transform(String name, String transformedName, byte[] basicClass) { + /* + * Here we patch all instances of entity.setHealth and replace them with a static function. + * Only EntityLivingBase is left untouched, as nothing else truly needs to be calling this method and avoiding forge hooks. + * May exclude all vanilla/forge class if this causes issues though. + */ + /* PatchForge : if (AsmConfig.enabledFixEntitySetHealth && !transformedName.contains("gtPlusPlus.preloader")) { + + //Skip Vanilla/Forge Classes + if (transformedName.contains("net.minecraft.") || transformedName.contains("cpw.")) { + //break PatchForge; + } + + ClassTransformer_Forge_EntityLivingBase_SetHealth aForgeHealthFix = new ClassTransformer_Forge_EntityLivingBase_SetHealth(transformedName, basicClass); + if (aForgeHealthFix.isValidTransformer() && aForgeHealthFix.didPatchClass()) { + Preloader_Logger.INFO("Fix EntityLivingBase.setHealth misuse", "Transforming "+transformedName); + basicClass = aForgeHealthFix.getWriter().toByteArray(); + } + }*/ + + // Is this environment obfuscated? (Extra checks just in case some weird shit happens during the check) + final boolean obfuscated = checkObfuscated(); + + // Fix LWJGL index array out of bounds on keybinding IDs + if ((transformedName.equals(LWJGL_KEYBOARD) || transformedName.equals(MINECRAFT_GAMESETTINGS_OBF) || transformedName.equals(MINECRAFT_GAMESETTINGS)) && AsmConfig.enabledLwjglKeybindingFix) { + boolean isClientSettingsClass = false; + if (!transformedName.equals("org.lwjgl.input.Keyboard")) { + isClientSettingsClass = true; + } + Preloader_Logger.INFO("LWJGL Keybinding index out of bounds fix", "Transforming "+transformedName); + return new ClassTransformer_LWJGL_Keyboard(basicClass, isClientSettingsClass).getWriter().toByteArray(); + } + + //Enable mapping of Tickets and loaded chunks. - Forge + if (transformedName.equals(FORGE_CHUNK_MANAGER) && AsmConfig.enableChunkDebugging) { + Preloader_Logger.INFO("Chunkloading Patch", "Transforming "+transformedName); + return new ClassTransformer_Forge_ChunkLoading(basicClass, false).getWriter().toByteArray(); + } + + // Fix the OreDictionary - Forge + if (transformedName.equals(FORGE_ORE_DICTIONARY) && AsmConfig.enableOreDictPatch) { + Preloader_Logger.INFO("OreDictTransformer", "Transforming "+transformedName); + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + new ClassReader(basicClass).accept(new OreDictionaryVisitor(classWriter), 0); + return classWriter.toByteArray(); + } + + // Log Handling of CodeChicken + if (transformedName.equals("codechicken.nei.guihook.GuiContainerManager")) { + //Preloader_Logger.INFO("CodeChicken GuiContainerManager Patch", "Transforming "+transformedName); + //return new ClassTransformer_CC_GuiContainerManager(basicClass).getWriter().toByteArray(); + } + // Fix the OreDictionary COFH + if (transformedName.equals(COFH_ORE_DICTIONARY_ARBITER) && (AsmConfig.enableCofhPatch || !obfuscated)) { + Preloader_Logger.INFO("COFH", "Transforming "+transformedName); + return new ClassTransformer_COFH_OreDictionaryArbiter(basicClass).getWriter().toByteArray(); + } + + // Fix Tinkers Fluids + if (transformedName.equals(TINKERS_FLUID_BLOCK) && AsmConfig.enableTiConFluidLighting) { + Preloader_Logger.INFO("Bright Fluids", "Transforming "+transformedName); + return new ClassTransformer_TiConFluids("getLightValue", obfuscated, basicClass).getWriter().toByteArray(); + } + + //Fix RC stuff + //Patching PROCESS_VOLUME to allow more transfer limits + if (transformedName.equals(RAILCRAFT_FLUID_HELPER) && (AsmConfig.enableRcFlowFix && AsmConfig.maxRailcraftTankProcessVolume != 4000)) { + Preloader_Logger.INFO("Railcraft PROCESS_VOLUME Patch", "Transforming "+transformedName); + return new ClassTransformer_Railcraft_FluidHelper(basicClass, obfuscated).getWriter().toByteArray(); + } + //Patching TRANSFER_RATE in Fluid Loaders/Unloaders + if ((transformedName.equals(RAILCRAFT_TILE_FLUID_LOADER) && AsmConfig.maxRailcraftFluidLoaderFlow != 20) || (transformedName.equals("mods.railcraft.common.blocks.machine.gamma.TileFluidUnloader") && AsmConfig.maxRailcraftFluidUnloaderFlow != 80)) { + Preloader_Logger.INFO("Railcraft TRANSFER_RATE Patch", "Transforming "+transformedName); + return new ClassTransformer_Railcraft_FluidCartHandling(basicClass, obfuscated, transformedName).getWriter().toByteArray(); + } + //Fix Weird glitch involving negative itemstacks. + if (transformedName.equals(RAILCRAFT_INVENTORY_TOOLS) && AsmConfig.enableRcItemDupeFix) { + Preloader_Logger.INFO("Railcraft negative ItemStack Fix", "Transforming "+transformedName); + return new ClassTransformer_Railcraft_InvTools(basicClass, obfuscated).getWriter().toByteArray(); + } + + //Fix GC stuff + if (AsmConfig.enableGcFuelChanges) { + if (transformedName.equals(GALACTICRAFT_FLUID_UTILS)) { + Preloader_Logger.INFO("Galacticraft FluidUtils Patch", "Transforming "+transformedName); + return new ClassTransformer_GC_FluidUtil(basicClass, false).getWriter().toByteArray(); + } + if (transformedName.equals(GALACTICRAFT_TILE_ENTITY_FUEL_LOADER)) { + Preloader_Logger.INFO("Galacticraft Fuel_Loader Patch", "Transforming "+transformedName); + return new ClassTransformer_GC_FuelLoader(basicClass, false).getWriter().toByteArray(); + } + if (transformedName.equals(GALACTICRAFT_ENTITY_AUTO_ROCKET)) { + Preloader_Logger.INFO("Galacticraft EntityAutoRocket Patch", "Transforming "+transformedName); + return new ClassTransformer_GC_EntityAutoRocket(basicClass, false).getWriter().toByteArray(); + } + } + + + /** + * Gregtech ASM Patches + */ + +// if (transformedName.equals(GT_UTILITY)) { +// Preloader_Logger.INFO("Gregtech Utilities Patch", "Transforming "+transformedName); +// return new ClassTransformer_GT_Utility(basicClass, transformedName).getWriter().toByteArray(); +// } + //Inject Custom constructors for RTG Hatches + if (transformedName.equals(GT_MTE_HATCH_ENERGY) || transformedName.equals(GTPP_MTE_HATCH_RTG)) { + Preloader_Logger.INFO("Gregtech RTG Patch", "Transforming " + transformedName); + return new ClassTransformer_GT_EnergyHatchPatch(basicClass, transformedName).getWriter().toByteArray(); + } + //Try patch achievements + if (transformedName.equals(GT_ACHIEVEMENTS)) { + Preloader_Logger.INFO("Gregtech Achievements Patch", "Transforming " + transformedName); + return new ClassTransformer_GT_Achievements_CrashFix(basicClass, obfuscated).getWriter().toByteArray(); + } + + //Fix bad handling of a loop left from original decompilation + //Also Fix Achievements, although currently disabled. + if (transformedName.equals(GT_CLIENT_PROXY)) { + Preloader_Logger.INFO("Gregtech Client Proxy Patch", "Transforming " + transformedName); + return new ClassTransformer_GT_Client(basicClass, obfuscated).getByteArray(); + } + + //Make GT packets safer, fill them with debug info. + if (transformedName.equals(GT_PACKET_TILE_ENTITY)) { + Preloader_Logger.INFO("Gregtech GT_Packet_TileEntity Patch", "Transforming "+transformedName); + return new ClassTransformer_GT_Packet_TileEntity(basicClass, obfuscated).getWriter().toByteArray(); + } + //Make the setting of GT Tiles safer, so as not to crash the client. + if (transformedName.equals(GT_BASE_META_TILE_ENTITY)) { + Preloader_Logger.INFO("Gregtech setMetaTileEntity Patch", "Transforming "+transformedName); + return new ClassTransformer_GT_BaseMetaTileEntity(basicClass).getWriter().toByteArray(); + } + //Add extra tools if we're in a dev environment. + if (transformedName.equals(GT_METAGENERATED_TOOL) && CORE_Preloader.DEV_ENVIRONMENT) { + Preloader_Logger.INFO("Gregtech Additional Tools Patch", "Transforming "+transformedName); + return new ClassTransformer_GT_MetaGenerated_Tool(basicClass).getWriter().toByteArray(); + } + //Fix log handling on the charcoal pit + if (transformedName.equals(GT_MTE_CHARCOAL_PIT) && AsmConfig.enableGtCharcoalPitFix) { + Preloader_Logger.INFO("GT Charcoal Pit Fix", "Transforming "+transformedName); + return new ClassTransformer_GT_CharcoalPit(basicClass, obfuscated).getWriter().toByteArray(); + } + + + + + //Patching Meta Tile Tooltips + if (transformedName.equals(GT_ITEM_MACHINES) && AsmConfig.enableGtTooltipFix) { + //Preloader_Logger.INFO("Gregtech Tooltip Patch", "Transforming "+transformedName); + //return new ClassTransformer_GT_ItemMachines_Tooltip(basicClass, false).getWriter().toByteArray(); + } + + + if (transformedName.equals(GT_BLOCK_MACHINES)) { + //Fix GT NBT Persistency issue + Preloader_Logger.INFO("Gregtech NBT Persistency Patch", "Transforming "+transformedName); + byte[] g = new ClassTransformer_GT_BlockMachines_NBT(basicClass, false).getWriter().toByteArray(); + Preloader_Logger.INFO("Gregtech getTileEntityBaseType Patch", "Transforming "+transformedName); + return new ClassTransformer_GT_BlockMachines_MetaPipeEntity(g, 0).getWriter().toByteArray(); + } + if (transformedName.equals(GT_METAPIPE_ITEM) || transformedName.equals(GT_METAPIPE_FRAME) || transformedName.equals(GT_METAPIPE_FLUID)) { + Preloader_Logger.INFO("Gregtech getTileEntityBaseType Patch", "Transforming "+transformedName); + int mode = 0; + if (transformedName.equals(GT_METAPIPE_ITEM)) { + mode = 1; + } + else if (transformedName.equals(GT_METAPIPE_FRAME)) { + mode = 2; + } + else { + mode = 3; + } + return new ClassTransformer_GT_BlockMachines_MetaPipeEntity(basicClass, mode).getWriter().toByteArray(); + } + + + //Fix IC2 Wrench Harvesting + for (String y : IC2_WRENCH_PATCH_CLASS_NAMES) { + if (transformedName.equals(y)) { + Preloader_Logger.INFO("IC2 getHarvestTool Patch", "Transforming "+transformedName); + return new ClassTransformer_IC2_GetHarvestTool(basicClass, obfuscated, transformedName).getWriter().toByteArray(); + } + } + + //This is breaking IC2 Hazmat, moved to hodgepodge +// if (transformedName.equals(IC2_ITEM_ARMOUR_HAZMAT)) { +// Preloader_Logger.INFO("IC2 Hazmat Patch", "Transforming "+transformedName); +// return new ClassTransformer_IC2_Hazmat(basicClass, transformedName).getWriter().toByteArray(); +// } + + //Fix Thaumcraft Shit + //Patching ItemWispEssence to allow invalid item handling + if (transformedName.equals(THAUMCRAFT_ITEM_WISP_ESSENCE) && AsmConfig.enableTcAspectSafety) { + Preloader_Logger.INFO("Thaumcraft WispEssence_Patch", "Transforming "+transformedName); + return new ClassTransformer_TC_ItemWispEssence(basicClass, obfuscated).getWriter().toByteArray(); + } + //Fix Thaumic Tinkerer Shit + if (transformedName.equals(THAUMICTINKERER_TILE_REPAIRER) && AsmConfig.enableThaumicTinkererRepairFix) { + //Preloader_Logger.INFO("Thaumic Tinkerer RepairItem Patch", "Transforming "+transformedName); + //return new ClassTransformer_TT_ThaumicRestorer(basicClass).getWriter().toByteArray(); + } + + + return basicClass; + } + + + +} |