aboutsummaryrefslogtreecommitdiff
path: root/src/Java/gtPlusPlus/preloader/asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/Java/gtPlusPlus/preloader/asm')
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/AsmConfig.java17
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_EntityLivingBase_SetHealth.java130
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java102
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java67
4 files changed, 262 insertions, 54 deletions
diff --git a/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java b/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java
index b3fbcb2d61..88bcf6b28b 100644
--- a/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java
+++ b/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java
@@ -15,6 +15,7 @@ public class AsmConfig {
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;
@@ -22,6 +23,7 @@ public class AsmConfig {
public static boolean enableRcItemDupeFix;
public static boolean enableTcAspectSafety;
public static boolean enabledLwjglKeybindingFix;
+ public static boolean enabledFixEntitySetHealth;
public static boolean disableAllLogging;
@@ -51,6 +53,12 @@ public class AsmConfig {
disableAllLogging = 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);
@@ -91,6 +99,14 @@ public class AsmConfig {
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);
@@ -137,6 +153,7 @@ public class AsmConfig {
FMLLog.log(Level.INFO, "[GT++ ASM] Gc Fuel Changes Patch - Enabled: "+enableGcFuelChanges, new Object[0]);
FMLLog.log(Level.INFO, "[GT++ ASM] Railcraft Fluid Flow Patch - Enabled: "+enableRcFlowFix, new Object[0]);
FMLLog.log(Level.INFO, "[GT++ ASM] Thaumcraft Aspect Safety Patch - Enabled: "+enableTcAspectSafety, new Object[0]);
+ FMLLog.log(Level.INFO, "[GT++ ASM] Fix bad usage of EntityLivingBase.setHealth Patch - Enabled: "+enabledFixEntitySetHealth, new Object[0]);
} catch (Exception var3) {
FMLLog.log(Level.ERROR, var3, "GT++ ASM had a problem loading it's config", new Object[0]);
diff --git a/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_EntityLivingBase_SetHealth.java b/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_Forge_EntityLivingBase_SetHealth.java
new file mode 100644
index 0000000000..d56b9de059
--- /dev/null
+++ b/src/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/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java b/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java
index 9c79db265d..1e54bd3632 100644
--- a/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java
+++ b/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_GT_CharcoalPit.java
@@ -1,10 +1,6 @@
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.INVOKESTATIC;
-import static org.objectweb.asm.Opcodes.IRETURN;
+import static org.objectweb.asm.Opcodes.*;
import java.util.ArrayList;
@@ -17,10 +13,10 @@ import org.objectweb.asm.MethodVisitor;
import cpw.mods.fml.relauncher.FMLRelaunchLog;
import gregtech.api.enums.OrePrefixes;
-import gtPlusPlus.api.objects.Logger;
+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.block.material.Material;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
@@ -31,35 +27,58 @@ public class ClassTransformer_GT_CharcoalPit {
private final ClassWriter writer;
public static boolean isWoodLog(Block log) {
- //Logger.INFO("checking for log");
- boolean isLog1 = OrePrefixes.log.contains(new ItemStack(log, 1));
- if (isLog1) {
- //Logger.INFO("Found 1");
- return true;
+ 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;
+ }
}
- ArrayList<ItemStack> oredict = OreDictionary.getOres("logWood");
- if (oredict.contains(ItemUtils.getSimpleStack(log))) {
- //Logger.INFO("found 2");
- return true;
- }
- //Logger.INFO("Did not find. "+(log != null ? ""+log.getLocalizedName() : "Null or invalid block?"));
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);
- aTempReader.accept(new AddFieldAdapter(aTempWriter), 0);
- injectMethod("isWoodLog", obfuscated, aTempWriter);
- if (aTempReader != null && aTempWriter != null) {
- isValid = true;
- } else {
+ 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 + ".");
+ FMLRelaunchLog.log("[GT++ ASM] GT Charcoal Pit Fix", Level.INFO, "Valid? " + isValid + ".");
reader = aTempReader;
writer = aTempWriter;
}
@@ -80,17 +99,19 @@ public class ClassTransformer_GT_CharcoalPit {
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(49, 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);
@@ -100,15 +121,36 @@ public class ClassTransformer_GT_CharcoalPit {
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 AddFieldAdapter extends ClassVisitor {
+ public class CustomClassVisitor extends ClassVisitor {
- public AddFieldAdapter(ClassVisitor cv) {
+ public CustomClassVisitor(ClassVisitor cv) {
super(ASM5, cv);
this.cv = cv;
}
diff --git a/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java b/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java
index d81c96dcca..d8dc71dff0 100644
--- a/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java
+++ b/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java
@@ -30,9 +30,9 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
System.out.println("[GT++ ASM] Asm Config Location: "+mConfig.config.getConfigFile().getAbsolutePath());
System.out.println("[GT++ ASM] Is DevHelper Valid? "+gtPlusPlus.preloader.DevHelper.mIsValidHelper);
}
-
+
private static Boolean mObf = null;
-
+
public boolean checkObfuscated() {
if (mObf != null) {
return mObf;
@@ -60,6 +60,25 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
}
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 (mConfig.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()) {
+ FMLRelaunchLog.log("[GT++ ASM] Fix EntityLivingBase.setHealth misuse", Level.INFO, "Transforming %s", transformedName);
+ basicClass = aForgeHealthFix.getWriter().toByteArray();
+ }
+ }
+
// Is this environment obfuscated? (Extra checks just in case some weird shit happens during the check)
boolean obfuscated = checkObfuscated();
boolean probablyShouldBeFalse = false;
@@ -69,7 +88,7 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Transforming %s", transformedName);
return new ClassTransformer_LWJGL_Keyboard(basicClass).getWriter().toByteArray();
}
-
+
//Enable mapping of Tickets and loaded chunks. - Forge
if (transformedName.equals("net.minecraftforge.common.ForgeChunkManager") && mConfig.enableChunkDebugging) {
FMLRelaunchLog.log("[GT++ ASM] Chunkloading Patch", Level.INFO, "Transforming %s", transformedName);
@@ -94,7 +113,7 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
FMLRelaunchLog.log("[GT++ ASM] Bright Fluids", Level.INFO, "Transforming %s", transformedName);
return new ClassTransformer_TiConFluids("getLightValue", obfuscated, basicClass).getWriter().toByteArray();
}
-
+
//Fix RC stuff
//Patching PROCESS_VOLUME to allow 4x more transfer limits
if (transformedName.equals("mods.railcraft.common.fluids.FluidHelper") && mConfig.enableRcFlowFix) {
@@ -123,15 +142,15 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
}
}
-
-
-
-
-
+
+
+
+
+
/**
* Gregtech ASM Patches
*/
-
+
//Make GT_Utilities safer
if (transformedName.equals("gtPlusPlus.preloader.asm.transformers.ClassTransformer_GT_Utility")) {
FMLRelaunchLog.log("[GT++ ASM] Gregtech Utilities Patch", Level.INFO, "Transforming %s", transformedName);
@@ -147,7 +166,7 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
FMLRelaunchLog.log("[GT++ ASM] Gregtech Achievements Patch", Level.INFO, "Transforming %s", 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("gregtech.common.GT_Client")) {
@@ -165,16 +184,16 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
FMLRelaunchLog.log("[GT++ ASM] Gregtech setMetaTileEntity Patch", Level.INFO, "Transforming %s", transformedName);
return new ClassTransformer_GT_BaseMetaTileEntity(basicClass).getWriter().toByteArray();
}
-
+
//Fix log handling on the charcoal pit
- if (transformedName.equals("gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_Charcoal_Pit")) {
+ if (transformedName.equals("gregtech.common.tileentities.machines.multi.GT_MetaTileEntity_Charcoal_Pit") && mConfig.enableGtCharcoalPitFix) {
FMLRelaunchLog.log("[GT++ ASM] GT Charcoal Pit Fix", Level.INFO, "Transforming %s", transformedName);
return new ClassTransformer_GT_CharcoalPit(basicClass, obfuscated).getWriter().toByteArray();
}
-
-
-
-
+
+
+
+
//Patching Meta Tile Tooltips
if (transformedName.equals("gregtech.common.blocks.GT_Item_Machines") && mConfig.enableGtTooltipFix) {
FMLRelaunchLog.log("[GT++ ASM] Gregtech Tooltip Patch", Level.INFO, "Transforming %s", transformedName);
@@ -203,7 +222,7 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
}
return new ClassTransformer_GT_BlockMachines_MetaPipeEntity(basicClass, probablyShouldBeFalse, mode).getWriter().toByteArray();
}
-
+
String[] aIC2ClassNames = new String[] {
"ic2.core.block.BlockTileEntity",
"ic2.core.block.machine.BlockMachine",
@@ -230,24 +249,24 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
return new ClassTransformer_IC2_GetHarvestTool(basicClass, obfuscated, transformedName).getWriter().toByteArray();
}
}
-
+
//Fix IC2 Hazmat
if (transformedName.equals("ic2.core.item.armor.ItemArmorHazmat")) {
FMLRelaunchLog.log("[GT++ ASM] IC2 Hazmat Patch", Level.INFO, "Transforming %s", transformedName);
return new ClassTransformer_IC2_Hazmat(basicClass, transformedName).getWriter().toByteArray();
}
-
+
//Fix Thaumcraft Shit
//Patching ItemWispEssence to allow invalid item handling
if (transformedName.equals("thaumcraft.common.items.ItemWispEssence") && mConfig.enableTcAspectSafety) {
FMLRelaunchLog.log("[GT++ ASM] Thaumcraft WispEssence_Patch", Level.INFO, "Transforming %s", transformedName);
return new ClassTransformer_TC_ItemWispEssence(basicClass, obfuscated).getWriter().toByteArray();
}
-
-
+
+
return basicClass;
}
-
-
+
+
}