From cf189f00a3abb921f0c96b73383504f5bb2fba66 Mon Sep 17 00:00:00 2001 From: Kogepan229 <73163994+Kogepan229@users.noreply.github.com> Date: Sat, 17 Jan 2026 01:13:56 +0900 Subject: [PATCH] Revert part of "remove transformers (#389)" (#393) --- gradle.properties | 2 +- .../github/coremod/FCClassTransformer.java | 55 +++++++++ .../github/coremod/FluidCraftCore.java | 48 ++++++++ .../github/coremod/hooker/CoreModHooks.java | 28 +++++ .../coremod/hooker/CoreModHooksClient.java | 9 ++ .../ExternalStorageRegistryTransformer.java | 104 ++++++++++++++++++ .../transform/GuiCraftingTransformer.java | 58 ++++++++++ .../coremod/transform/NEITransformer.java | 62 +++++++++++ 8 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/glodblock/github/coremod/FCClassTransformer.java create mode 100644 src/main/java/com/glodblock/github/coremod/FluidCraftCore.java create mode 100644 src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java create mode 100644 src/main/java/com/glodblock/github/coremod/hooker/CoreModHooksClient.java create mode 100644 src/main/java/com/glodblock/github/coremod/transform/ExternalStorageRegistryTransformer.java create mode 100644 src/main/java/com/glodblock/github/coremod/transform/GuiCraftingTransformer.java create mode 100644 src/main/java/com/glodblock/github/coremod/transform/NEITransformer.java diff --git a/gradle.properties b/gradle.properties index 3b43a313..8cfe02e3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -108,7 +108,7 @@ mixinsPackage = # Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin! # This parameter is for legacy compatibility only # Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin -coreModClass = +coreModClass = coremod.FluidCraftCore # If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class # that is annotated with @Mod) you want this to be true. When in doubt: leave it on false! diff --git a/src/main/java/com/glodblock/github/coremod/FCClassTransformer.java b/src/main/java/com/glodblock/github/coremod/FCClassTransformer.java new file mode 100644 index 00000000..ebd48a06 --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/FCClassTransformer.java @@ -0,0 +1,55 @@ +package com.glodblock.github.coremod; + +import net.minecraft.launchwrapper.IClassTransformer; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; + +import com.glodblock.github.coremod.transform.ExternalStorageRegistryTransformer; +import com.glodblock.github.coremod.transform.GuiCraftingTransformer; +import com.glodblock.github.coremod.transform.NEITransformer; +import com.gtnewhorizon.gtnhlib.asm.ASMUtil; + +public class FCClassTransformer implements IClassTransformer { + + private static final Logger logger = LogManager.getLogger("ASM AE2FC"); + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + ClassMapper tform; + switch (transformedName) { + case "appeng.client.gui.implementations.GuiCraftingCPU", "appeng.client.gui.implementations.GuiCraftConfirm", "net.p455w0rd.wirelesscraftingterminal.client.gui.GuiCraftConfirm", "appeng.client.gui.widgets.GuiCraftingTree" -> tform = GuiCraftingTransformer.INSTANCE; + case "appeng.integration.modules.NEI" -> tform = NEITransformer.INSTANCE; + case "appeng.core.features.registries.ExternalStorageRegistry" -> tform = ExternalStorageRegistryTransformer.INSTANCE; + default -> { + return basicClass; + } + } + logger.debug("Transforming class: " + transformedName); + final byte[] bytes = tform.transformClass(basicClass); + if (FluidCraftCore.DUMP_CLASSES()) { + ASMUtil.saveAsRawClassFile(basicClass, transformedName + "_PRE", this); + ASMUtil.saveAsRawClassFile(bytes, transformedName + "_POST", this); + } + return bytes; + } + + public abstract static class ClassMapper { + + public final byte[] transformClass(byte[] code) { + ClassReader reader = new ClassReader(code); + ClassWriter writer = new ClassWriter(reader, getWriteFlags()); + reader.accept(getClassMapper(writer), ClassReader.EXPAND_FRAMES); + return writer.toByteArray(); + } + + protected int getWriteFlags() { + return 0; + } + + protected abstract ClassVisitor getClassMapper(ClassVisitor downstream); + } +} diff --git a/src/main/java/com/glodblock/github/coremod/FluidCraftCore.java b/src/main/java/com/glodblock/github/coremod/FluidCraftCore.java new file mode 100644 index 00000000..6f9b97a9 --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/FluidCraftCore.java @@ -0,0 +1,48 @@ +package com.glodblock.github.coremod; + +import java.util.Map; + +import javax.annotation.Nullable; + +import cpw.mods.fml.relauncher.IFMLLoadingPlugin; + +@IFMLLoadingPlugin.Name("FluidCraftCore") +@IFMLLoadingPlugin.MCVersion("1.7.10") +@IFMLLoadingPlugin.TransformerExclusions("com.glodblock.github.coremod") +public class FluidCraftCore implements IFMLLoadingPlugin { + + private static final boolean DUMP_CLASSES = Boolean.parseBoolean(System.getProperty("ae2fc.dumpClass", "false")); + private static boolean OBF_ENV; + + @Override + public String[] getASMTransformerClass() { + return new String[] { FCClassTransformer.class.getName() }; + } + + @Nullable + @Override + public String getModContainerClass() { + return null; + } + + @Nullable + @Override + public String getSetupClass() { + return null; + } + + @Override + public void injectData(Map data) { + OBF_ENV = (boolean) data.get("runtimeDeobfuscationEnabled"); + } + + @Nullable + @Override + public String getAccessTransformerClass() { + return null; + } + + public static boolean DUMP_CLASSES() { + return DUMP_CLASSES || !OBF_ENV; + } +} diff --git a/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java b/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java new file mode 100644 index 00000000..7a98dd7b --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooks.java @@ -0,0 +1,28 @@ +package com.glodblock.github.coremod.hooker; + +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import com.glodblock.github.common.item.ItemFluidDrop; +import com.glodblock.github.common.item.ItemFluidPacket; + +import appeng.api.storage.data.IAEItemStack; +import appeng.client.gui.IGuiTooltipHandler; + +public class CoreModHooks { + + public static ItemStack displayFluid(IAEItemStack aeStack) { + if (aeStack.getItemStack() != null && aeStack.getItemStack().getItem() instanceof ItemFluidDrop) { + FluidStack fluid = ItemFluidDrop.getFluidStack(aeStack.getItemStack()); + return ItemFluidPacket.newDisplayStack(fluid); + } else return aeStack.getItemStack(); + } + + public static ItemStack getStackUnderMouse(GuiContainer gui, int mousex, int mousey) { + if (gui instanceof IGuiTooltipHandler guiTooltipHandler) { + return guiTooltipHandler.getHoveredStack(); + } + return null; + } +} diff --git a/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooksClient.java b/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooksClient.java new file mode 100644 index 00000000..bf94e47f --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/hooker/CoreModHooksClient.java @@ -0,0 +1,9 @@ +package com.glodblock.github.coremod.hooker; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public class CoreModHooksClient { + +} diff --git a/src/main/java/com/glodblock/github/coremod/transform/ExternalStorageRegistryTransformer.java b/src/main/java/com/glodblock/github/coremod/transform/ExternalStorageRegistryTransformer.java new file mode 100644 index 00000000..0ad99cc6 --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/transform/ExternalStorageRegistryTransformer.java @@ -0,0 +1,104 @@ +package com.glodblock.github.coremod.transform; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import com.glodblock.github.coremod.FCClassTransformer; + +public class ExternalStorageRegistryTransformer extends FCClassTransformer.ClassMapper { + + public static final ExternalStorageRegistryTransformer INSTANCE = new ExternalStorageRegistryTransformer(); + + private ExternalStorageRegistryTransformer() { + // NO-OP + } + + @Override + protected ClassVisitor getClassMapper(ClassVisitor downstream) { + return new TransformExternalStorageRegistry(Opcodes.ASM5, downstream); + } + + @Override + protected int getWriteFlags() { + return ClassWriter.COMPUTE_FRAMES; + } + + private static class TransformExternalStorageRegistry extends ClassVisitor { + + public TransformExternalStorageRegistry(int api, ClassVisitor cv) { + super(api, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if ("getHandler".equals(name)) { + return new TransformGetHandler(api, super.visitMethod(access, name, desc, signature, exceptions)); + } else { + return super.visitMethod(access, name, desc, signature, exceptions); + } + } + } + + private static class TransformGetHandler extends MethodVisitor { + + private int cnt_return = 0; + private int cnt_if = 0; + private Label L6 = null; + private final Label L9 = new Label(); + + TransformGetHandler(int api, MethodVisitor mv) { + super(api, mv); + } + + @Override + public void visitJumpInsn(int opcode, Label label) { + if (opcode == Opcodes.IFEQ) { + cnt_if++; + } + if (cnt_if == 3) { + L6 = label; + cnt_if++; + super.visitJumpInsn(opcode, L9); + return; + } + super.visitJumpInsn(opcode, label); + } + + @Override + public void visitInsn(int opcode) { + if (opcode == Opcodes.ARETURN) { + cnt_return++; + } + super.visitInsn(opcode); + if (cnt_return == 2) { + super.visitLabel(L9); + super.visitFieldInsn( + Opcodes.GETSTATIC, + "com/glodblock/github/inventory/external/AEFluidTankHandler", + "INSTANCE", + "Lcom/glodblock/github/inventory/external/AEFluidTankHandler;"); + super.visitVarInsn(Opcodes.ALOAD, 1); + super.visitVarInsn(Opcodes.ALOAD, 2); + super.visitVarInsn(Opcodes.ALOAD, 3); + super.visitVarInsn(Opcodes.ALOAD, 4); + super.visitMethodInsn( + Opcodes.INVOKEVIRTUAL, + "com/glodblock/github/inventory/external/AEFluidTankHandler", + "canHandle", + "(Lnet/minecraft/tileentity/TileEntity;Lnet/minecraftforge/common/util/ForgeDirection;Lappeng/api/storage/StorageChannel;Lappeng/api/networking/security/BaseActionSource;)Z", + false); + super.visitJumpInsn(Opcodes.IFEQ, L6); + super.visitFieldInsn( + Opcodes.GETSTATIC, + "com/glodblock/github/inventory/external/AEFluidTankHandler", + "INSTANCE", + "Lcom/glodblock/github/inventory/external/AEFluidTankHandler;"); + super.visitInsn(Opcodes.ARETURN); + cnt_return++; + } + } + } +} diff --git a/src/main/java/com/glodblock/github/coremod/transform/GuiCraftingTransformer.java b/src/main/java/com/glodblock/github/coremod/transform/GuiCraftingTransformer.java new file mode 100644 index 00000000..da1874e3 --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/transform/GuiCraftingTransformer.java @@ -0,0 +1,58 @@ +package com.glodblock.github.coremod.transform; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import com.glodblock.github.coremod.FCClassTransformer; + +public class GuiCraftingTransformer extends FCClassTransformer.ClassMapper { + + public static final GuiCraftingTransformer INSTANCE = new GuiCraftingTransformer(); + + private GuiCraftingTransformer() { + // NO-OP + } + + @Override + protected ClassVisitor getClassMapper(ClassVisitor downstream) { + return new TransformGuiCrafting(Opcodes.ASM5, downstream); + } + + private static class TransformGuiCrafting extends ClassVisitor { + + TransformGuiCrafting(int api, ClassVisitor cv) { + super(api, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if ("drawFG".equals(name) || "drawListFG".equals(name) || "drawStack".equals(name)) { + return new TransformFluidIcon(api, super.visitMethod(access, name, desc, signature, exceptions)); + } + return super.visitMethod(access, name, desc, signature, exceptions); + } + } + + private static class TransformFluidIcon extends MethodVisitor { + + TransformFluidIcon(int api, MethodVisitor mv) { + super(api, mv); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + if (opcode == Opcodes.INVOKEINTERFACE && owner.equals("appeng/api/storage/data/IAEItemStack") + && name.equals("getItemStack")) { + super.visitMethodInsn( + Opcodes.INVOKESTATIC, + "com/glodblock/github/coremod/hooker/CoreModHooks", + "displayFluid", + "(Lappeng/api/storage/data/IAEItemStack;)Lnet/minecraft/item/ItemStack;", + false); + } else { + super.visitMethodInsn(opcode, owner, name, desc, itf); + } + } + } +} diff --git a/src/main/java/com/glodblock/github/coremod/transform/NEITransformer.java b/src/main/java/com/glodblock/github/coremod/transform/NEITransformer.java new file mode 100644 index 00000000..6c8a8dc7 --- /dev/null +++ b/src/main/java/com/glodblock/github/coremod/transform/NEITransformer.java @@ -0,0 +1,62 @@ +package com.glodblock.github.coremod.transform; + +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import com.glodblock.github.coremod.FCClassTransformer; + +public class NEITransformer extends FCClassTransformer.ClassMapper { + + public static final NEITransformer INSTANCE = new NEITransformer(); + + private NEITransformer() { + // NO-OP + } + + @Override + protected ClassVisitor getClassMapper(ClassVisitor downstream) { + return new TransformNEI(Opcodes.ASM5, downstream); + } + + private static class TransformNEI extends ClassVisitor { + + TransformNEI(int api, ClassVisitor cv) { + super(api, cv); + } + + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + return switch (name) { + case "getStackUnderMouse" -> new TransformStackUnderMouse( + api, + super.visitMethod(access, name, desc, signature, exceptions)); + default -> super.visitMethod(access, name, desc, signature, exceptions); + }; + } + } + + private static class TransformStackUnderMouse extends MethodVisitor { + + TransformStackUnderMouse(int api, MethodVisitor mv) { + super(api, mv); + } + + @Override + public void visitInsn(int opcode) { + if (opcode == Opcodes.ACONST_NULL) { + super.visitVarInsn(Opcodes.ALOAD, 1); + super.visitVarInsn(Opcodes.ILOAD, 2); + super.visitVarInsn(Opcodes.ILOAD, 3); + super.visitMethodInsn( + Opcodes.INVOKESTATIC, + "com/glodblock/github/coremod/hooker/CoreModHooks", + "getStackUnderMouse", + "(Lnet/minecraft/client/gui/inventory/GuiContainer;II)Lnet/minecraft/item/ItemStack;", + false); + return; + } + super.visitInsn(opcode); + } + } +}