From cd52f98cba73eb319123097f4290ecaf3cf8300f Mon Sep 17 00:00:00 2001 From: Jason Mitchell Date: Wed, 9 Oct 2024 16:51:02 -0700 Subject: [PATCH] Revert back to old behavior * RFB Plugin loads earlier and can run in both obf and deobf --- .../angelica/transform/BlockTransformer.java | 35 ++++------- .../transform/RedirectorTransformer.java | 60 ++++++++----------- 2 files changed, 35 insertions(+), 60 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/transform/BlockTransformer.java b/src/main/java/com/gtnewhorizons/angelica/transform/BlockTransformer.java index 6504288a2..37e2df746 100644 --- a/src/main/java/com/gtnewhorizons/angelica/transform/BlockTransformer.java +++ b/src/main/java/com/gtnewhorizons/angelica/transform/BlockTransformer.java @@ -3,6 +3,7 @@ import com.google.common.collect.ImmutableList; import com.gtnewhorizons.angelica.loading.AngelicaTweaker; import net.minecraft.launchwrapper.IClassTransformer; +import org.apache.commons.lang3.tuple.Pair; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.tree.ClassNode; @@ -12,28 +13,14 @@ public class BlockTransformer implements IClassTransformer { private static final String BlockClassFriendly = "net.minecraft.block.Block"; - private static final List mcpMapping = ImmutableList.of( - "minX", - "minY", - "minZ", - "maxX", - "maxY", - "maxZ"); - private static final List srgMapping = ImmutableList.of( - "field_149759_B", - "field_149760_C", - "field_149754_D", - "field_149755_E", - "field_149756_F", - "field_149757_G"); - - public static List getBlockBoundsFields() { - return AngelicaTweaker.isObfEnv() ? srgMapping : mcpMapping; - } - - public static String getClearFieldName(String name) { - return AngelicaTweaker.isObfEnv() ? mcpMapping.get(srgMapping.indexOf(name)) : name; - } + public static final List> BlockBoundsFields = ImmutableList.of( + Pair.of("minX", "field_149759_B"), + Pair.of("minY", "field_149760_C"), + Pair.of("minZ", "field_149754_D"), + Pair.of("maxX", "field_149755_E"), + Pair.of("maxY", "field_149756_F"), + Pair.of("maxZ", "field_149757_G") + ); /** * Delete the global vanilla bounding box fields off the Block object. {@link RedirectorTransformer} @@ -45,8 +32,8 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) final ClassReader cr = new ClassReader(basicClass); final ClassNode cn = new ClassNode(); cr.accept(cn, 0); - cn.fields.removeIf(field -> getBlockBoundsFields().contains(field.name)); - ClassWriter cw = new ClassWriter(0); + cn.fields.removeIf(field -> BlockBoundsFields.stream().anyMatch(pair -> field.name.equals(pair.getLeft()) || field.name.equals(pair.getRight()))); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cn.accept(cw); final byte[] bytes = cw.toByteArray(); AngelicaTweaker.dumpClass(transformedName, basicClass, bytes, this); diff --git a/src/main/java/com/gtnewhorizons/angelica/transform/RedirectorTransformer.java b/src/main/java/com/gtnewhorizons/angelica/transform/RedirectorTransformer.java index 5c4318e08..3ace8e090 100644 --- a/src/main/java/com/gtnewhorizons/angelica/transform/RedirectorTransformer.java +++ b/src/main/java/com/gtnewhorizons/angelica/transform/RedirectorTransformer.java @@ -1,17 +1,18 @@ package com.gtnewhorizons.angelica.transform; +import com.google.common.collect.ImmutableSet; import com.gtnewhorizon.gtnhlib.asm.ClassConstantPoolParser; import com.gtnewhorizons.angelica.loading.AngelicaTweaker; import net.coderbot.iris.IrisLogging; import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; +import org.apache.commons.lang3.tuple.Pair; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.FieldNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.InsnNode; import org.objectweb.asm.tree.IntInsnNode; @@ -28,6 +29,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; /** * This transformer redirects many GL calls to our custom GLStateManager @@ -49,10 +51,13 @@ public class RedirectorTransformer implements IClassTransformer { private static final String OpenGlHelper = "net/minecraft/client/renderer/OpenGlHelper"; private static final String EXTBlendFunc = "org/lwjgl/opengl/EXTBlendFuncSeparate"; private static final String ARBMultiTexture = "org/lwjgl/opengl/ARBMultitexture"; + private static final String MinecraftClient = "net.minecraft.client"; + private static final String SplashProgress = "cpw.mods.fml.client.SplashProgress"; private static final String ThreadedBlockData = "com/gtnewhorizons/angelica/glsm/ThreadedBlockData"; - private static final String MinecraftClient_dot = "net.minecraft.client.Minecraft"; - private static final String SplashProgress_dot = "cpw.mods.fml.client.SplashProgress"; - private static final String OpenGlHelper_dot = "net.minecraft.client.renderer.OpenGlHelper"; + private static final Set ExcludedMinecraftMainThreadChecks = ImmutableSet.of( + "startGame", "func_71384_a", + "initializeTextures", "func_77474_a" + ); /** All classes in net.minecraft.block.* are the block subclasses save for these. */ private static final List VanillaBlockExclusions = Arrays.asList( "net/minecraft/block/IGrowable", @@ -286,23 +291,16 @@ public boolean transformClassNode(String transformedName, ClassNode cn) { } // Check if this class shadows any fields of the parent class - if (moddedBlockSubclasses.contains(cn.name)) { - // If a superclass shadows, then so do we, because JVM - // will resolve a reference on our class to that superclass - final boolean doWeShadow; - if (blockOwnerExclusions.contains(cn.superName)) { + if(moddedBlockSubclasses.contains(cn.name)) { + // If a superclass shadows, then so do we, because JVM will resolve a reference on our class to that + // superclass + boolean doWeShadow; + if(blockOwnerExclusions.contains(cn.superName)) { doWeShadow = true; } else { // Check if we declare any known field names - final List blockBoundsNames = BlockTransformer.getBlockBoundsFields(); - boolean b = false; - for (FieldNode field : cn.fields) { - if (blockBoundsNames.contains(field.name)) { - b = true; - break; - } - } - doWeShadow = b; + Set fieldsDeclaredByClass = cn.fields.stream().map(f -> f.name).collect(Collectors.toSet()); + doWeShadow = BlockTransformer.BlockBoundsFields.stream().anyMatch(pair -> fieldsDeclaredByClass.contains(pair.getLeft()) || fieldsDeclaredByClass.contains(pair.getRight())); } if (doWeShadow) { AngelicaTweaker.LOGGER.info("Class '{}' shadows one or more block bounds fields, these accesses won't be redirected!", cn.name); @@ -312,7 +310,7 @@ public boolean transformClassNode(String transformedName, ClassNode cn) { boolean changed = false; for (MethodNode mn : cn.methods) { - if (transformedName.equals(OpenGlHelper_dot) && (mn.name.equals("glBlendFunc") || mn.name.equals("func_148821_a"))) { + if (transformedName.equals("net.minecraft.client.renderer.OpenGlHelper") && (mn.name.equals("glBlendFunc") || mn.name.equals("func_148821_a"))) { continue; } boolean redirectInMethod = false; @@ -374,11 +372,11 @@ public boolean transformClassNode(String transformedName, ClassNode cn) { } } else if ((node.getOpcode() == Opcodes.GETFIELD || node.getOpcode() == Opcodes.PUTFIELD) && node instanceof FieldInsnNode fNode) { - if (!blockOwnerExclusions.contains(fNode.owner) && isBlockSubclass(fNode.owner) && isSodiumEnabled()) { - String fieldToRedirect = null; - for (String name : BlockTransformer.getBlockBoundsFields()) { - if (fNode.name.equals(name)) { - fieldToRedirect = name; + if(!blockOwnerExclusions.contains(fNode.owner) && isBlockSubclass(fNode.owner) && isSodiumEnabled()) { + Pair fieldToRedirect = null; + for(Pair blockPairs : BlockTransformer.BlockBoundsFields) { + if(fNode.name.equals(blockPairs.getLeft()) || fNode.name.equals(blockPairs.getRight())) { + fieldToRedirect = blockPairs; break; } } @@ -387,7 +385,7 @@ else if ((node.getOpcode() == Opcodes.GETFIELD || node.getOpcode() == Opcodes.PU AngelicaTweaker.LOGGER.info("Redirecting Block.{} in {} to thread-safe wrapper", fNode.name, transformedName); } // Perform the redirect - fNode.name = BlockTransformer.getClearFieldName(fieldToRedirect); + fNode.name = fieldToRedirect.getLeft(); // use unobfuscated name fNode.owner = ThreadedBlockData; // Inject getter before the field access, to turn Block -> ThreadedBlockData final MethodInsnNode getter = new MethodInsnNode(Opcodes.INVOKESTATIC, ThreadedBlockData, "get", "(L" + BlockClass + ";)L" + ThreadedBlockData + ";", false); @@ -414,7 +412,7 @@ else if ((node.getOpcode() == Opcodes.GETFIELD || node.getOpcode() == Opcodes.PU } } } - if (ASSERT_MAIN_THREAD && redirectInMethod && !isExcludeFromMainThreadAssert(transformedName, mn.name)) { + if (ASSERT_MAIN_THREAD && redirectInMethod && !transformedName.startsWith(SplashProgress) && !(transformedName.startsWith(MinecraftClient) && ExcludedMinecraftMainThreadChecks.contains(mn.name))) { mn.instructions.insert(new MethodInsnNode(Opcodes.INVOKESTATIC, GLStateManager, "assertMainThread", "()V", false)); } } @@ -422,16 +420,6 @@ else if ((node.getOpcode() == Opcodes.GETFIELD || node.getOpcode() == Opcodes.PU return changed; } - private static boolean isExcludeFromMainThreadAssert(String className, String methodName) { - if (className.startsWith(SplashProgress_dot)) { - return true; - } - if (MinecraftClient_dot.equals(className) && methodName.equals(AngelicaTweaker.isObfEnv() ? "func_71384_a" :"startGame")) { - return true; - } - return OpenGlHelper_dot.equals(className) && methodName.equals(AngelicaTweaker.isObfEnv() ? "func_77474_a" : "initializeTextures"); - } - private static class RedirectMap extends HashMap { public static RedirectMap newMap() { return new RedirectMap<>();