diff --git a/src/main/java/glowredman/txloader/MinecraftClassTransformer.java b/src/main/java/glowredman/txloader/MinecraftClassTransformer.java index 9c60c3f..0dd37ee 100644 --- a/src/main/java/glowredman/txloader/MinecraftClassTransformer.java +++ b/src/main/java/glowredman/txloader/MinecraftClassTransformer.java @@ -1,7 +1,5 @@ package glowredman.txloader; -import java.util.List; - import net.minecraft.launchwrapper.IClassTransformer; import net.minecraft.launchwrapper.Launch; @@ -10,80 +8,56 @@ import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.VarInsnNode; public class MinecraftClassTransformer implements IClassTransformer { @Override public byte[] transform(String name, String transformedName, byte[] basicClass) { - if (!"net.minecraft.client.Minecraft".equals(transformedName)) { - return basicClass; + if ("net.minecraft.client.Minecraft".equals(transformedName)) { + return transformMinecraft(basicClass); } - return transformMinecraft(basicClass); + return basicClass; } private static byte[] transformMinecraft(byte[] basicClass) { - TXLoaderCore.LOGGER.info("Transforming net.minecraft.client.Minecraft"); - boolean devEnv = (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); - - ClassNode classNode = new ClassNode(); - ClassReader classReader = new ClassReader(basicClass); - classReader.accept(classNode, 0); - - // find refreshResources() method - MethodNode targetMethod = null; - final String refreshResourcesName = devEnv ? "refreshResources" : "func_110436_a"; - final String refreshResourcesDesc = "()V"; - - for (MethodNode method : classNode.methods) { - if (method.name.equals(refreshResourcesName) && method.desc.equals(refreshResourcesDesc)) { - targetMethod = method; - break; - } - } - - if (targetMethod == null) throw new RuntimeException("Could not find method refreshResources()!"); - - // find first invocation of IReloadableResourceManager.reloadResources() - AbstractInsnNode targetInsn = null; - final String reloadResourcesName = devEnv ? "reloadResources" : "func_110541_a"; - final String reloadResourcesDesc = "(Ljava/util/List;)V"; - - for (AbstractInsnNode ain : targetMethod.instructions.toArray()) { - if (ain instanceof MethodInsnNode) { - MethodInsnNode min = (MethodInsnNode) ain; - if (min.name.equals(reloadResourcesName) && min.desc.equals(reloadResourcesDesc)) { - targetInsn = ain; - break; + TXLoaderCore.LOGGER.debug("Transforming net.minecraft.client.Minecraft"); + final boolean devEnv = (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); + final ClassNode classNode = new ClassNode(); + final ClassReader classReader = new ClassReader(basicClass); + classReader.accept(classNode, ClassReader.SKIP_DEBUG); + final String targetMethodName = devEnv ? "refreshResources" : "func_110436_a"; + final String targetMethodInsnName = devEnv ? "reloadResources" : "func_110541_a"; + boolean success = false; + for (MethodNode mn : classNode.methods) { + if (mn.name.equals(targetMethodName) && mn.desc.equals("()V")) { + for (AbstractInsnNode node : mn.instructions.toArray()) { + if (isTargetNode(node, targetMethodInsnName)) { + mn.instructions.insertBefore( + node, + new MethodInsnNode( + Opcodes.INVOKESTATIC, + "glowredman/txloader/MinecraftHook", + "insertForcePack", + "(Ljava/util/List;)Ljava/util/List;", + false)); + success = true; + break; + } } + break; } } - - if (targetInsn == null) - throw new RuntimeException("Could not find invocation of reloadResources() in method refreshResources()!"); - - // insert new instructions - InsnList insertForcePackInsnList = new InsnList(); - insertForcePackInsnList.add( - new MethodInsnNode( - Opcodes.INVOKESTATIC, - "glowredman/txloader/MinecraftClassTransformer", - "insertForcePack", - "(Ljava/util/List;)V", - false)); - insertForcePackInsnList.add(new VarInsnNode(Opcodes.ALOAD, 1)); - targetMethod.instructions.insertBefore(targetInsn, insertForcePackInsnList); - - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + if (!success) throw new RuntimeException("TX Loader couldn't transform Minecraft!"); + final ClassWriter classWriter = new ClassWriter(0); classNode.accept(classWriter); return classWriter.toByteArray(); } - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static void insertForcePack(List resourcePackList) { - resourcePackList.add(new TXResourcePack.Force()); + private static boolean isTargetNode(AbstractInsnNode node, String name) { + return node instanceof MethodInsnNode && ((MethodInsnNode) node).name.equals(name) + && ((MethodInsnNode) node).desc.equals("(Ljava/util/List;)V"); } + } diff --git a/src/main/java/glowredman/txloader/MinecraftHook.java b/src/main/java/glowredman/txloader/MinecraftHook.java new file mode 100644 index 0000000..7163c21 --- /dev/null +++ b/src/main/java/glowredman/txloader/MinecraftHook.java @@ -0,0 +1,14 @@ +package glowredman.txloader; + +import java.util.List; + +import net.minecraft.client.resources.IResourcePack; + +@SuppressWarnings("unused") +public class MinecraftHook { + + public static List insertForcePack(List resourcePackList) { + resourcePackList.add(new TXResourcePack.Force()); + return resourcePackList; + } +} diff --git a/src/main/java/glowredman/txloader/TXLoaderCore.java b/src/main/java/glowredman/txloader/TXLoaderCore.java index 0768973..ac23712 100644 --- a/src/main/java/glowredman/txloader/TXLoaderCore.java +++ b/src/main/java/glowredman/txloader/TXLoaderCore.java @@ -36,13 +36,18 @@ public class TXLoaderCore implements IFMLLoadingPlugin { @Override public String[] getASMTransformerClass() { - return FMLLaunchHandler.side().isClient() ? new String[] { MinecraftClassTransformer.class.getName() } - : new String[0]; + if (FMLLaunchHandler.side().isClient()) { + return new String[] { MinecraftClassTransformer.class.getName() }; + } + return null; } @Override public String getModContainerClass() { - return FMLLaunchHandler.side().isClient() ? "glowredman.txloader.TXLoaderModContainer" : null; + if (FMLLaunchHandler.side().isClient()) { + return "glowredman.txloader.TXLoaderModContainer"; + } + return null; } @Override