diff --git a/src/main/java/codechicken/nei/asm/GuiContainerManagerAPITransformer.java b/src/main/java/codechicken/nei/asm/GuiContainerManagerAPITransformer.java new file mode 100644 index 00000000..dc182a79 --- /dev/null +++ b/src/main/java/codechicken/nei/asm/GuiContainerManagerAPITransformer.java @@ -0,0 +1,38 @@ +package codechicken.nei.asm; + +import codechicken.lib.asm.ASMHelper; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; + +import static org.objectweb.asm.Opcodes.POP; +import static org.objectweb.asm.Opcodes.PUTSTATIC; + +public class GuiContainerManagerAPITransformer extends ClassVisitor { + private final String tname; + private boolean changed = false; + + public GuiContainerManagerAPITransformer(int api, ClassVisitor cv, String tname) { + super(api, cv); + this.tname = tname; + } + + @Override + public MethodVisitor visitMethod(int access, String mname, String mdesc, String signature, String[] exceptions) { + return new MethodVisitor(api, super.visitMethod(access, mname, mdesc, signature, exceptions)) { + @Override + public void visitFieldInsn(int opcode, String owner, String name, String desc) { + if (opcode == PUTSTATIC && "codechicken/nei/guihook/GuiContainerManager".equals(owner) && name.endsWith("Handlers") && desc.equals("Ljava/util/LinkedList;")) { + ASMHelper.logger.warn("Found suspicious PUTSTATIC {} in {}#{}{}, replacing with POP!", name, tname, mname, mdesc); + changed = true; + super.visitInsn(POP); + } else { + super.visitFieldInsn(opcode, owner, name, desc); + } + } + }; + } + + public boolean isChanged() { + return changed; + } +} diff --git a/src/main/java/codechicken/nei/asm/NEITransformer.java b/src/main/java/codechicken/nei/asm/NEITransformer.java index 7ba9a732..bbea66d9 100644 --- a/src/main/java/codechicken/nei/asm/NEITransformer.java +++ b/src/main/java/codechicken/nei/asm/NEITransformer.java @@ -41,6 +41,7 @@ public class NEITransformer implements IClassTransformer ASMInit.init(); } + private final boolean paranoidMode = Boolean.getBoolean("nei.paranoid"); private final ModularASMTransformer transformer = new ModularASMTransformer(); private final Map asmblocks = ASMReader.loadResource("/assets/nei/asm/blocks.asm"); @@ -264,6 +265,14 @@ public class NEITransformer implements IClassTransformer } bytes = transformSubclasses(name, bytes); } + if (paranoidMode && !tname.startsWith("codechicken.nei")) { + ClassReader cr = new ClassReader(bytes); + ClassWriter cw = new ClassWriter(0); + GuiContainerManagerAPITransformer cv = new GuiContainerManagerAPITransformer(ASM5, cw, tname); + cr.accept(cv, ClassReader.SKIP_DEBUG); + if (cv.isChanged()) + bytes = cw.toByteArray(); + } bytes = transformer.transform(name, bytes); } catch (Exception e) { diff --git a/src/main/java/codechicken/nei/guihook/GuiContainerManager.java b/src/main/java/codechicken/nei/guihook/GuiContainerManager.java index 596b464e..d45fe8aa 100644 --- a/src/main/java/codechicken/nei/guihook/GuiContainerManager.java +++ b/src/main/java/codechicken/nei/guihook/GuiContainerManager.java @@ -36,11 +36,11 @@ public class GuiContainerManager public GuiContainer window; public static RenderItem drawItems = new RenderItem(); - public static LinkedList tooltipHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); - public static LinkedList inputHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); - public static LinkedList drawHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); - public static LinkedList objectHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); - public static LinkedList slotClickHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); + public static final LinkedList tooltipHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); + public static final LinkedList inputHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); + public static final LinkedList drawHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); + public static final LinkedList objectHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); + public static final LinkedList slotClickHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>()); static { addSlotClickHandler(new DefaultSlotClickHandler());