Jump to content

[1.7.10] [COREMOD] Coremod launched simulatenously with MC, causes crash.


Elix_x

Recommended Posts

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???

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.