Posted February 2, 201510 yr I'm making coremod, that patches few things in GameSettings, how ever doesn't finish patching it before MC asks this class... Transformer's code: package code.elix_x.coremods.keysoverhaul; import java.io.IOException; import java.util.Iterator; import net.minecraft.launchwrapper.IClassTransformer; 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.InsnList; import org.objectweb.asm.tree.LocalVariableNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; public class Transformer implements IClassTransformer{ @Override public byte[] transform(String className, String transformedName, byte[] bytes) { // System.out.println(className); if(className.equals(KeysOverhaulTranslator.getMapedClassName("client.settings.GameSettings"))){ System.out.println("*************** Patching GameSettings ***************"); byte[] b = patchGameSettings(className, bytes); System.out.println("*************** Patching GameSettings Complete ***************"); return b; } return bytes; } private byte[] patchGameSettings(String className, byte[] bytes) { String loadOptions = KeysOverhaulTranslator.getMapedMethodName("GameSettings", "func_74300_a", "loadOptions"); String saveOptions = KeysOverhaulTranslator.getMapedMethodName("GameSettings", "func_74303_b", "saveOptions"); String isKeyDown = KeysOverhaulTranslator.getMapedMethodName("GameSettings", "func_100015_a", "isKeyDown"); String setOptionKeyBinding = KeysOverhaulTranslator.getMapedMethodName("GameSettings", "setOptionKeyBinding", "setOptionKeyBinding"); ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(bytes); classReader.accept(classNode, 0); Iterator<MethodNode> methods = classNode.methods.iterator(); while(methods.hasNext()){ MethodNode m = methods.next(); if(m.name.equals(loadOptions) && m.desc.equals("()V")){ System.out.println("*************** Patching loadOptions ***************"); AbstractInsnNode currentNode = null; AbstractInsnNode targetNode = null; int place = -1; int index = -1; Iterator<AbstractInsnNode> iter = m.instructions.iterator(); while (iter.hasNext()) { index++; currentNode = iter.next(); if (currentNode.getOpcode() == Opcodes.INVOKEVIRTUAL) { MethodInsnNode currentMethod = (MethodInsnNode) currentNode; if(doesMethodEqual(currentMethod, "net/minecraft/client/settings/KeyBinding", ".setKeyCode", "(I)V")){ targetNode = currentNode; place = index; break; } } } // INVOKESTATIC java/lang/Integer.parseInt (Ljava/lang/String;)I AbstractInsnNode remNode = m.instructions.get(place - 1); m.instructions.remove(remNode); replace(m.instructions, place, createNewListAndFillWith(createMethodNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/client/settings/KeyBinding", ".setKeyCode", "(Ljava/lang/String)V"))); System.out.println("*************** Patching loadOptions complete ***************"); } if(m.name.equals(saveOptions) && m.desc.equals("()V")){ System.out.println("*************** Patching saveOptions ***************"); AbstractInsnNode currentNode = null; AbstractInsnNode targetNode = null; int place = -1; int index = -1; Iterator<AbstractInsnNode> iter = m.instructions.iterator(); while (iter.hasNext()) { index++; currentNode = iter.next(); if (currentNode.getOpcode() == Opcodes.INVOKEVIRTUAL) { MethodInsnNode currentMethod = (MethodInsnNode) currentNode; if(doesMethodEqual(currentMethod, "net/minecraft/client/settings/KeyBinding", ".getKeyCode", "()I")){ targetNode = currentNode; place = index; break; } } } replace(m.instructions, place, createMethodNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/client/settings/KeyBinding", ".getKeyCodeS", "()Ljava/lang/String")); System.out.println("*************** Patching saveOptions complete ***************"); } if(m.name.equals(isKeyDown) && m.desc.equals("(Lnet/minecraft/client/settings/KeyBinding;)Z")){ System.out.println("*************** Patching isKeyDown ***************"); /*InsnList fields = m.instructions; fields.clear();*/ try { ClassNode methodsNode = new ClassNode(); ClassReader methodsReader = new ClassReader(Methods.class.getName()); methodsReader.accept(classNode, 0); for(MethodNode method : methodsNode.methods){ if(method.name == "isKeyDown" && method.desc == "(Lcode/elix_x/coremods/keysoverhaul/replace/KeyBinding;)Z"){ // classNode.methods.add(classNode.methods.indexOf(m), method); method.desc = "(Lnet/minecraft/client/settings/KeyBinding;)Z"; AbstractInsnNode currentNode = null; AbstractInsnNode targetNode = null; AbstractInsnNode targetNode2 = null; int place = -1; int index = -1; Iterator<AbstractInsnNode> iter = method.instructions.iterator(); while (iter.hasNext()) { index++; currentNode = iter.next(); if (currentNode.getOpcode() == Opcodes.INVOKESTATIC) { MethodInsnNode currentMethod = (MethodInsnNode) currentNode; if(doesMethodEqual(currentMethod, "code/elix_x/coremods/keysoverhaul/replace/KeyBinding", ".isKeyDown", "(Lcode/elix_x/coremods/keysoverhaul/replace/KeyBinding;)Z")){ targetNode = currentNode; } } // if(currentNode.getOpcode() == Opcodes.LOc) } /*for(LocalVariableNode var : method.localVariables){ System.out.println("node: " + var.name + " desc: " + var.desc + " index: " + var.index + " signature: " + var.signature); }*/ method.instructions.insert(targetNode, createMethodNode(Opcodes.INVOKESTATIC, "net/minecraft/client/settings/KeyBinding", ".isKeyDown", "(Lnet/minecraft/client/settings/KeyBinding;)Z")); classNode.methods.add(classNode.methods.indexOf(m), method); } } } catch (IOException e) { e.printStackTrace(); } System.out.println("*************** Patching isKeyDown complete ***************"); } if(m.name.equals(isKeyDown) && m.desc.equals("(Lnet/minecraft/client/settings/KeyBinding;)Z")){ System.out.println("*************** Patching setOptionKeyBinding ***************"); m.desc = "(Lnet/minecraft/client/settings/KeyBinding;[i)V"; AbstractInsnNode currentNode = null; AbstractInsnNode targetNode = null; int place = -1; int index = -1; Iterator<AbstractInsnNode> iter = m.instructions.iterator(); while (iter.hasNext()) { index++; currentNode = iter.next(); if (currentNode.getOpcode() == Opcodes.INVOKEVIRTUAL) { MethodInsnNode currentMethod = (MethodInsnNode) currentNode; if(doesMethodEqual(currentMethod, "net/minecraft/client/settings/KeyBinding", ".setKeyCode", "()I")){ targetNode = currentNode; place = index; break; } } } m.instructions.insert(currentNode, createMethodNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/client/settings/KeyBinding", ".setKeyCode", "([i)V")); System.out.println("*************** Patching setOptionKeyBinding complete ***************"); } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); classNode.accept(writer); return writer.toByteArray(); } private AbstractInsnNode findNode(InsnList list, AbstractInsnNode node) { AbstractInsnNode currentNode = null; AbstractInsnNode targetNode = null; int place = -1; int index = -1; Iterator<AbstractInsnNode> iter = list.iterator(); while (iter.hasNext()) { index++; currentNode = iter.next(); if(areNodesEqual(node, currentNode)){ targetNode = currentNode; place = index; break; } } return targetNode; } private int findNodePos(InsnList list, AbstractInsnNode node) { AbstractInsnNode currentNode = null; AbstractInsnNode targetNode = null; int place = -1; int index = -1; Iterator<AbstractInsnNode> iter = list.iterator(); while (iter.hasNext()) { index++; currentNode = iter.next(); if(areNodesEqual(node, currentNode)){ targetNode = currentNode; place = index; break; } } return place; } private boolean areNodesEqual(AbstractInsnNode node, AbstractInsnNode node1) { if(node.getOpcode() == node1.getOpcode()){ if(node.getType() == node1.getType()){ return true; } } return false; } private InsnList createNewListAndFillWith(Object... nodes) { InsnList list = new InsnList(); for(Object node : nodes){ if(node instanceof AbstractInsnNode){ list.add((AbstractInsnNode) node); } if(node instanceof InsnList){ list.add(list); } } return list; } private void replace(InsnList instructions, int index, AbstractInsnNode node) { instructions.insert(instructions.get(index), node); } private void replace(InsnList instructions, int index, InsnList node) { instructions.insert(instructions.get(index), node); } private MethodInsnNode createMethodNode(int opcode, String owner, String name, String desc) { return new MethodInsnNode(opcode, owner, name, desc); } private boolean doesMethodEqual(MethodInsnNode method, String owner, String name, String desc) { return method.owner == owner && method.name == name && method.desc == desc; } } And console output: ... [18:39:11] [main/INFO]: Setting user: Player458 [18:39:13] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.Transformer:transform:41]: *************** Patching GameSettings *************** [18:39:13] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.Transformer:patchGameSettings:132]: *************** Patching isKeyDown *************** [18:39:13] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.Transformer:patchGameSettings:178]: *************** Patching isKeyDown complete *************** [18:39:13] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.Transformer:patchGameSettings:182]: *************** Patching setOptionKeyBinding *************** [18:39:13] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.Transformer:patchGameSettings:210]: *************** Patching setOptionKeyBinding complete *************** [18:39:13] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.Transformer:patchGameSettings:69]: *************** Patching loadOptions *************** [18:39:13] [Client thread/INFO] [sTDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:388]: ---- Minecraft Crash Report ---- // Don't be sad. I'll do better next time, I promise! Time: 02.02.15 18:39 Description: Initializing game java.lang.NoClassDefFoundError: net/minecraft/client/settings/GameSettings at net.minecraft.client.Minecraft.startGame(Minecraft.java:420) at net.minecraft.client.Minecraft.run(Minecraft.java:931) at net.minecraft.client.main.Main.main(Main.java:164) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:78) at GradleStart.main(GradleStart.java:45) Caused by: java.lang.ClassNotFoundException: net.minecraft.client.settings.GameSettings at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) ... 11 more Caused by: java.lang.IndexOutOfBoundsException at org.objectweb.asm.tree.InsnList.get(InsnList.java:107) at code.elix_x.coremods.keysoverhaul.Transformer.patchGameSettings(Transformer.java:94) at code.elix_x.coremods.keysoverhaul.Transformer.transform(Transformer.java:42) at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279) at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176) ... 13 more A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Stacktrace: at net.minecraft.client.Minecraft.startGame(Minecraft.java:420) -- Initialization -- Details: Stacktrace: at net.minecraft.client.Minecraft.run(Minecraft.java:931) at net.minecraft.client.main.Main.main(Main.java:164) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) at net.minecraft.launchwrapper.Launch.main(Launch.java:28) at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:78) at GradleStart.main(GradleStart.java:45) -- System Details -- Details: Minecraft Version: 1.7.10 Operating System: Windows 7 (amd64) version 6.1 Java Version: 1.8.0_25, Oracle Corporation Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation Memory: 857592600 bytes (817 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB) JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0 FML: Launched Version: 1.7.10 LWJGL: 2.9.1 OpenGL: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread. GL Caps: Is Modded: Definitely; Client brand changed to 'fml,forge' Type: Client (map_client.txt) Resource Packs: ~~ERROR~~ NoClassDefFoundError: net/minecraft/client/settings/GameSettings Current Language: ~~ERROR~~ NullPointerException: null Profiler Position: N/A (disabled) Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used Anisotropic Filtering: ~~ERROR~~ NoClassDefFoundError: net/minecraft/client/settings/GameSettings [18:39:13] [Client thread/INFO] [sTDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:398]: #@!@# Game crashed! Crash report saved to: #@!@# C:\my\mcmodding\mods\toolscompressor\eclipse\.\crash-reports\crash-2015-02-02_18.39.13-client.txt Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release ANY HELP, PLEASE??? Check out my mods: BTAM Armor sets Avoid Exploding Creepers Tools compressor Anti Id Conflict Key bindings overhaul Colourfull blocks Invisi Zones
February 2, 201510 yr Author I'm trying to rewrite vanilla key system, to make it possible to bind few keys for one action. (shift + alt + i for example) Check out my mods: BTAM Armor sets Avoid Exploding Creepers Tools compressor Anti Id Conflict Key bindings overhaul Colourfull blocks Invisi Zones
February 2, 201510 yr Author You do not need to patch any vanilla classes for that. Why do you think so? I'll have to patch at least GUIControls for that... or use events to overhandle Gui opening... But there's still some methods that will be needed to be patched. Check out my mods: BTAM Armor sets Avoid Exploding Creepers Tools compressor Anti Id Conflict Key bindings overhaul Colourfull blocks Invisi Zones
February 3, 201510 yr Author Finding ways, i know, that i can extend class, remap everything in post init, but there are still some things to patch Some that have not the best solution: loadOptions and saveOtions, but i can still save to world, but then gui will not be acessible outside of world... One that needs to be patched: runTick in MC, because MC uses "wrong" keyupdate system isKeyDown, just needs to be patched, just because it uses int PS: way to make this possible: by saving keys in int[] instead of int allows to store more keys for one Key Binding Check out my mods: BTAM Armor sets Avoid Exploding Creepers Tools compressor Anti Id Conflict Key bindings overhaul Colourfull blocks Invisi Zones
February 4, 201510 yr Author Making another coremod I ENCOUNTERED THE SAME PROBLEM: COREMOD LOADS SIMULATENOUSLY TO MC, AND THAT'S VERY PROBLEMATIC IF YOU WANT TO OVERHANDLE BIOME REGISTRATION FOR EXAMPLE!!!!!! Check out my mods: BTAM Armor sets Avoid Exploding Creepers Tools compressor Anti Id Conflict Key bindings overhaul Colourfull blocks Invisi Zones
February 4, 201510 yr If you do not understand these fundamentals of how coremods work, you should not be creating a coremod. There is no need for you to. I do Forge for free, however the servers to run it arn't free, so anything is appreciated. Consider supporting the team on Patreon
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.