Jump to content

Recommended Posts

Posted

Hi there, let me explain why i need to use patch:

 

I need to patch very much stuff in one mc's classes, and using asm will too long to perform it. Not only  i need to patch a lot of methods, but i need also to insert bunch of loops, try cath, etc... So using asm will be a bit difficult here...

Also i know that forge uses .java.patch files to patch classes, and also i found how to use them (there is very old topic for that), but not how to write them...

Posted

Simple answer: you don't.

Forge does not actually use .patch files in production. Outside the development environment forge uses binary patches instead, which operate directly on the class files.

 

But this is less than ideal for a mod. If you need to add a lot of code into a class (why?), call a static helper method in one of your classes instead and write the code in java.

Thanks, i think i can do so... I have 2 more questions: how can i remove static field from class (not very important)? How can i add static field in class (ot is it easier to manipulate with new one in other class... BTW: in my case it's list of objects, where each object added in end of constructor...)

 

EDIT: on more question: how can i easily remove bunch of lines from method?

Posted

on more question: how can i easily remove bunch of lines from method?

Don't. Just put a GOTO before the instructions and the corresponding Label behind.

You mean that inserting GOTO before, will skip these lines??? Which kind of Node is GOTO by the way? And will it not be easier to use binary patches or replace entire class (like here)

Posted

And will it not be easier to use binary patches or replace entire class (like here)

It might be easier (the class replacing part at least) but it will be highly incompatible with many other mods, depending on what class you replace.

It just defies the entire point of a coremod.

 

I'm modifying static methods in KeyBinding. I don't think that they (onTick, setKeyBindState, resetKeyBindingArrayAndHash) are used somewhere, but minecraft...

Posted

Why?

Well, long story:

One time looking in game settings i saw that key bindings are stored in list, without beeing connected to id, so i got question: if so, why we can't put multiple key bindings on one key? (techically, they are not only red, but if you put multiple options, only one is executed).

So i dug deeper, and found that in KeyBinding, IntHashMap is used to acces keys, and if we change this to Multimap for example, we will be able to set multiple keys to one key...

Posted

I don't see how that requires many base edits or even any base edits at all.

Well all these 3 methods are using this set, if i change it to multimap (or create new somewhere else), i need or to redirect methods from somewhere or from there... Plus to make it compatible with other mods, <init> needs to be modified too...

Posted

Not that I know much about ASM, but couldn't you use your map as an addition (not overwrite) and read it (execute bindings) using client KeyEvents? You can make that one binding launches other bindings there (in event).

 

EDIT: To below: Ah, yes, true that.

1.7.10 is no longer supported by forge, you are on your own.

Posted

So, i'm back because i need to decide what will be better to use...

Here's 4 methods (and 1 private field without getter or setter) that needs to be modified and how:

//REMOVE
//    private static final IntHashMap hash = new IntHashMap();
//ADD
private static final Multimap<Integer, KeyBinding> keyId = HashMultimap.create();

public static void onTick(int id)
{
	if (id != 0)
	{
		//REMOVE
		/*KeyBinding keybinding = (KeyBinding)hash.lookup(id);

            if (keybinding != null)
            {
                ++keybinding.pressTime;
            }*/

		//ADD
		for(KeyBinding keybinding : keyId.get(id)){
			if (keybinding != null)
			{
				++keybinding.pressTime;
			}
		}
	}
}

public static void setKeyBindState(int id, boolean state)
{
	if (id != 0)
	{
		//REMOVE
		/*KeyBinding keybinding = (KeyBinding)hash.lookup(id);

            if (keybinding != null)
            {
                keybinding.pressed = state;
            }*/

		//ADD
		for(KeyBinding keybinding : keyId.get(id)){
			if (keybinding != null)
            {
                keybinding.pressed = state;
            }
		}
	}
}

public static void resetKeyBindingArrayAndHash()
{
	//REMOVE
	/*hash.clearMap();
        Iterator iterator = keybindArray.iterator();

        while (iterator.hasNext())
        {
            KeyBinding keybinding = (KeyBinding)iterator.next();
            hash.addKey(keybinding.keyCode, keybinding);
        }*/

	//ADD
	keyId.clear();
	Iterator iterator = keybindArray.iterator();

        while (iterator.hasNext())
        {
            KeyBinding keybinding = (KeyBinding)iterator.next();
            keyId.put(keybinding.keyCode, keybinding);
        }
}

public KeyBinding(String desc, int id, String cat)
{
	this.keyDescription = desc;
	this.keyCode = id;
	this.keyCodeDefault = id;
	this.keyCategory = cat;
	keybindArray.add(this);
	keybindSet.add(cat);
	//REMOVE
	//        hash.addKey(p_i45001_2_, this);
	//ADD
	keyId.put(id, this);
}

 

Posted

Yes, you need to modify some stuff in KeyBinding. For the Gui, make your own. You don't need any ASM for that.

I know about gui, that using events i can take it over... But in this case i don't even need to modify gui...

That way(with Gui event) should be far more better than using ASM, especially when what you need is replacing a field.

Some mods can get an access to the hash field using reflection, and they will be crash at that point.

 

So... don't use ASM for that.

  (It seems that you even know how to achieve what you want without ASM)

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

Yes, you need to modify some stuff in KeyBinding. For the Gui, make your own. You don't need any ASM for that.

I know about gui, that using events i can take it over... But in this case i don't even need to modify gui...

That way(with Gui event) should be far more better than using ASM, especially when what you need is replacing a field.

Some mods can get an access to the hash field using reflection, and they will be crash at that point.

 

So... don't use ASM for that.

 

 

  (It seems that you even know how to achieve what you want without ASM)

 

As i said, i don't need to change ANYTHING in any GUI (for now), i just need to change 4 methods in KeyBinding (It's not GUI!!!) and that's all!!!

Posted

. Oh I misread something. sorry

So you need to patch the static field and the function nodes you want?

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted

. Oh I misread something. sorry

So you need to patch the static field and the function nodes you want?

Remove field (can not to remove, nut it will be useless), and change 3 static methods and constructor like that:

So, i'm back because i need to decide what will be better to use...

Here's 4 methods (and 1 private field without getter or setter) that needs to be modified and how:

//REMOVE
//    private static final IntHashMap hash = new IntHashMap();
//ADD
private static final Multimap<Integer, KeyBinding> keyId = HashMultimap.create();

public static void onTick(int id)
{
	if (id != 0)
	{
		//REMOVE
		/*KeyBinding keybinding = (KeyBinding)hash.lookup(id);

            if (keybinding != null)
            {
                ++keybinding.pressTime;
            }*/

		//ADD
		for(KeyBinding keybinding : keyId.get(id)){
			if (keybinding != null)
			{
				++keybinding.pressTime;
			}
		}
	}
}

public static void setKeyBindState(int id, boolean state)
{
	if (id != 0)
	{
		//REMOVE
		/*KeyBinding keybinding = (KeyBinding)hash.lookup(id);

            if (keybinding != null)
            {
                keybinding.pressed = state;
            }*/

		//ADD
		for(KeyBinding keybinding : keyId.get(id)){
			if (keybinding != null)
            {
                keybinding.pressed = state;
            }
		}
	}
}

public static void resetKeyBindingArrayAndHash()
{
	//REMOVE
	/*hash.clearMap();
        Iterator iterator = keybindArray.iterator();

        while (iterator.hasNext())
        {
            KeyBinding keybinding = (KeyBinding)iterator.next();
            hash.addKey(keybinding.keyCode, keybinding);
        }*/

	//ADD
	keyId.clear();
	Iterator iterator = keybindArray.iterator();

        while (iterator.hasNext())
        {
            KeyBinding keybinding = (KeyBinding)iterator.next();
            keyId.put(keybinding.keyCode, keybinding);
        }
}

public KeyBinding(String desc, int id, String cat)
{
	this.keyDescription = desc;
	this.keyCode = id;
	this.keyCodeDefault = id;
	this.keyCategory = cat;
	keybindArray.add(this);
	keybindSet.add(cat);
	//REMOVE
	//        hash.addKey(p_i45001_2_, this);
	//ADD
	keyId.put(id, this);
}

 

Posted

Well i'm back with another problems:

I wrote transformer for KeyBinding, but when i start the game it crashes...

Transformer class:

public class KeysOverhaulTransformer implements IClassTransformer{

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
	if(name.equals(KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding"))){
		System.out.println("##################################################");
		System.out.println("Patching KeyBinding");
		byte[] b = patchKeyBinding(name, bytes);
		System.out.println("Patching KeyBinding Completed");
		System.out.println("##################################################");
		return b;
	}
	return bytes;
}

private byte[] patchKeyBinding(String name, byte[] bytes) {
	String onTick = KeysOverhaulTranslator.getMapedMethodName(name, "func_74507_a", "onTick");
	String setKeyBindState = KeysOverhaulTranslator.getMapedMethodName(name, "func_74510_a", "setKeyBindState");
	String resetKeyBindingArrayAndHash = KeysOverhaulTranslator.getMapedMethodName(name, "func_74508_b", "resetKeyBindingArrayAndHash");
	String init = "<init>";

	ClassNode classNode = new ClassNode();
	ClassReader classReader = new ClassReader(bytes);
	classReader.accept(classNode, 0);

	Iterator<MethodNode> methods = classNode.methods.iterator();

	while(methods.hasNext()){
		MethodNode method = methods.next();

		if(method.name.equals(onTick)){
			try{
				System.out.println("**************************************************");
				System.out.println("Patching onTick");

				AbstractInsnNode currentNode = null;
				AbstractInsnNode targetNode = null;
				int place = -1;
				int index = -1;

				Iterator<AbstractInsnNode> iter = method.instructions.iterator();

				while (iter.hasNext())
				{
					index++;
					currentNode = iter.next();

					if(currentNode.getOpcode() == Opcodes.ILOAD){
						if(currentNode.getNext().getOpcode() == Opcodes.IFEQ){
							targetNode = currentNode;
							place = index;
							break;
						}
					}
				}

				method.instructions.set(targetNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "code/elix_x/coremods/keysoverhaul/KeyBindingHelper", ".onTick", "(I)Z"));

				System.out.println("Patching onTick Completed");
				System.out.println("**************************************************");
			}catch(Exception e){
				System.out.println("Patching onTick Failed With Exception:");
				e.printStackTrace();
				System.out.println("**************************************************");
			}
		}

		if(method.name.equals(setKeyBindState)){
			try{
				System.out.println("**************************************************");
				System.out.println("Patching setKeyBindState");

				AbstractInsnNode currentNode = null;
				AbstractInsnNode targetNode = null;
				int place = -1;
				int index = -1;

				Iterator<AbstractInsnNode> iter = method.instructions.iterator();

				while (iter.hasNext())
				{
					index++;
					currentNode = iter.next();

					if(currentNode.getOpcode() == Opcodes.ILOAD){
						if(currentNode.getNext().getOpcode() == Opcodes.IFEQ){
							targetNode = currentNode;
							place = index;
							break;
						}
					}
				}

				method.instructions.insertBefore(targetNode, createNewListAndFillWith(new VarInsnNode(Opcodes.ILOAD, 1), new MethodInsnNode(Opcodes.INVOKESTATIC, "code/elix_x/coremods/keysoverhaul/KeyBindingHelper", ".setKeyBindState", "(I,Z)Z")));
				method.instructions.remove(targetNode);

				System.out.println("Patching setKeyBindState Completed");
				System.out.println("**************************************************");
			}catch(Exception e){
				System.out.println("Patching setKeyBindState Failed With Exception:");
				e.printStackTrace();
				System.out.println("**************************************************");
			}
		}

		if(method.name.equals(resetKeyBindingArrayAndHash)){
			try{
				System.out.println("**************************************************");
				System.out.println("Patching resetKeyBindingArrayAndHash");

				AbstractInsnNode currentNode = null;
				AbstractInsnNode targetNode = null;
				int place = -1;
				int index = -1;

				Iterator<AbstractInsnNode> iter = method.instructions.iterator();

				while (iter.hasNext())
				{
					index++;
					currentNode = iter.next();

					if(currentNode.getOpcode() == Opcodes.GETSTATIC){
						FieldInsnNode field = (FieldInsnNode) currentNode;
						/*System.out.println("Owner: " + field.owner.replace("/", ".") + " Searching for: " + KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding"));
						System.out.println("Name: " + field.name + " Searching for: " + KeysOverhaulTranslator.getMapedFieldName("client.settings.KeyBinding", "field_74514_b", "hash"));
						System.out.println("Desc: " + field.desc);*/
						if(field.owner.replace("/", ".").equals(KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding")) && field.name.equals(KeysOverhaulTranslator.getMapedFieldName("client.settings.KeyBinding", "field_74514_b", "hash"))){
							targetNode = currentNode;
							place = index;
							break;
						}
					}
				}

				method.instructions.insert(targetNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "code/elix_x/coremods/keysoverhaul/KeyBindingHelper", ".resetKeyBindingArrayAndHash", "(Lnet/minecraft/util/IntHashMap;)Lnet/minecraft/util/IntHashMap;"));

				System.out.println("Patching resetKeyBindingArrayAndHash Completed");
				System.out.println("**************************************************");
			}catch(Exception e){
				System.out.println("Patching resetKeyBindingArrayAndHash Failed With Exception:");
				e.printStackTrace();
				System.out.println("**************************************************");
			}
		}

		if(method.name.equals(init)){
			try{
				System.out.println("**************************************************");
				System.out.println("Patching <init>");

				AbstractInsnNode currentNode = null;
				AbstractInsnNode targetNode = null;
				int place = -1;
				int index = -1;

				Iterator<AbstractInsnNode> iter = method.instructions.iterator();

				while (iter.hasNext())
				{
					index++;
					currentNode = iter.next();

					if(currentNode.getOpcode() == Opcodes.GETSTATIC){
						FieldInsnNode field = (FieldInsnNode) currentNode;
						if(field.owner.replace("/", ".").equals(KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding")) && field.name.equals(KeysOverhaulTranslator.getMapedFieldName("client.settings.KeyBinding", "field_74514_b", "hash"))){
							targetNode = currentNode;
							place = index;
							break;
						}
					}
				}

				method.instructions.remove(targetNode.getNext());
				method.instructions.remove(targetNode.getNext());

				System.out.println("(IL" + KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding") + ";)L" + KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding") + ";");
				method.instructions.insert(targetNode, createNewListAndFillWith(new VarInsnNode(Opcodes.ILOAD, 2), new VarInsnNode(Opcodes.ILOAD, 2), new VarInsnNode(Opcodes.ALOAD, 0), new MethodInsnNode(Opcodes.INVOKESTATIC, "code/elix_x/coremods/keysoverhaul/KeyBindingHelper", ".register", "(IL" + KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding") + ";)L" + KeysOverhaulTranslator.getMapedClassName("client.settings.KeyBinding") + ";")));

				System.out.println("Patching <init> Completed");
				System.out.println("**************************************************");
			}catch(Exception e){
				System.out.println("Patching <init> Failed With Exception:");
				e.printStackTrace();
				System.out.println("**************************************************");
			}
		}
	}

	ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
	classNode.accept(writer);
	return writer.toByteArray();
}

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;
}
}

 

And console log + crash:

[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:transform:26]: ##################################################
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:transform:27]: Patching KeyBinding
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:56]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:57]: Patching onTick
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:82]: Patching onTick Completed
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:83]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:94]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:95]: Patching setKeyBindState
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:121]: Patching setKeyBindState Completed
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:122]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:133]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:134]: Patching resetKeyBindingArrayAndHash
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:163]: Patching resetKeyBindingArrayAndHash Completed
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:164]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:174]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:175]: Patching <init>
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:226]: (ILnet.minecraft.client.settings.KeyBinding;)Lnet.minecraft.client.settings.KeyBinding;
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:229]: Patching <init> Completed
[18:38:22] [Client thread/INFO] [sTDOUT]: [code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer:patchKeyBinding:230]: **************************************************
[18:38:22] [Client thread/INFO] [sTDOUT]: [net.minecraft.client.Minecraft:displayCrashReport:388]: ---- Minecraft Crash Report ----
// Everything's going to plan. No, really, that was supposed to happen.

Time: 15.03.15 18:38
Description: Initializing game

java.lang.NoClassDefFoundError: net/minecraft/client/settings/KeyBinding
at net.minecraft.client.settings.GameSettings.<init>(GameSettings.java:204)
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.KeyBinding
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 12 more
Caused by: java.lang.NegativeArraySizeException
at org.objectweb.asm.Frame.merge(Frame.java:1343)
at org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1475)
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:834)
at org.objectweb.asm.tree.MethodNode.accept(MethodNode.java:726)
at org.objectweb.asm.tree.ClassNode.accept(ClassNode.java:412)
at code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer.patchKeyBinding(KeysOverhaulTransformer.java:240)
at code.elix_x.coremods.keysoverhaul.core.KeysOverhaulTransformer.transform(KeysOverhaulTransformer.java:29)
at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279)
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176)
... 14 more


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Stacktrace:
at net.minecraft.client.settings.GameSettings.<init>(GameSettings.java:204)
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: 783634056 bytes (747 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~~ NullPointerException: null
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~~ NullPointerException: null
[18:38:22] [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-03-15_18.38.22-client.txt
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release

Posted

:o

 

All that crap code just to add a method call? Nope. I am not debugging that.

 

Please learn ASM properly, here is a video:

Okay, i'll watch video, but...

1) In onTick and setKeyBindState, i'm inserting my method call in main if statement, and in my method always return false.

2) In resetKeyBindingArrayAndHash i'm calling it like getter for hash to be cleared.

3) In costructor, i'm calling it like getter instance tu be put with id in hash.

 

Changes:

1)From:

if (p_74507_0_ != 0)

To:

if(KeyBindingHelper.onTick(id))

2)From:

hash.clearMap();

To:

KeyBindingHelper.resetKeyBindingArrayAndHash(hash).clearMap();

3)From:

hash.addKey(p_i45001_2_, this);

To:

hash.addKey(id, KeyBindingHelper.register(id, this));

 

EDIT: i'll edit 3rd one...

Posted

And again you are stabbing around inside the method. Don't do that.

Technically, 1st one makes no sense to insert more labels and return, if there's already if statement that i can use...

 

Interesting thing by the way: i commented out all changes excluding 1st one and it crashes too. Same thing happens whenever i leave at least one method transformer...

  • 2 weeks later...
Posted

Yes, it makes sense. Keep changes to the methods as minimal as possible.

Okay, i got it working... long time ago...

But now i have problems with another coremod:

I need to insert piece of code in onUpdate in EntityTNTPrimed (because there's no super call or any event there.)

What i need to insert is this:

ExplosionSrcManager.onUpdate(this);

onUpdate modified should look like this:

 public void onUpdate()
    {
        this.prevPosX = this.posX;
        this.prevPosY = this.posY;
        this.prevPosZ = this.posZ;
        this.motionY -= 0.03999999910593033D;
        this.moveEntity(this.motionX, this.motionY, this.motionZ);
        this.motionX *= 0.9800000190734863D;
        this.motionY *= 0.9800000190734863D;
        this.motionZ *= 0.9800000190734863D;

        ExplosionSrcManager.onUpdate(this);

        if (this.onGround)
        {
            this.motionX *= 0.699999988079071D;
            this.motionZ *= 0.699999988079071D;
            this.motionY *= -0.5D;
        }

        if (this.fuse-- <= 0)
        {
            this.setDead();

            if (!this.worldObj.isRemote)
            {
                this.explode();
            }
        }
        else
        {
            this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
        }
    }

Here's TNT transformer method:

private byte[] patchEntityTNTPrimed(String name, byte[] bytes) {
	String onUpdate = AvoidExplodingCreepersTranslator.getMapedMethodName("EntityTNTPrimed", "func_70071_h_", "onUpdate");
	String onUpdateDesc = AvoidExplodingCreepersTranslator.getMapedMethodDesc("EntityTNTPrimed", "func_70071_h_", "()V");

	ClassNode classNode = new ClassNode();
	ClassReader classReader = new ClassReader(bytes);
	classReader.accept(classNode, 0);

	for(MethodNode method : classNode.methods){
		if(method.name.equals(onUpdate) && method.desc.equals(onUpdateDesc)){
			try{
				System.out.println("**************************************************");
				System.out.println("Patching onUpdate");

				//PUTFIELD net/minecraft/entity/item/EntityTNTPrimed.motionZ : D

				AbstractInsnNode targetNode = null;

				for(AbstractInsnNode currentNode : method.instructions.toArray()){
					if(currentNode.getOpcode() == Opcodes.PUTFIELD){
						FieldInsnNode field = (FieldInsnNode) currentNode;
						if(field.owner.replace("/", ".").equals(EntityTNTPrimedClass) && field.name.equals(AvoidExplodingCreepersTranslator.getMapedFieldName("EntityTNTPrimed", "field_70179_y", "motionZ"))){
							targetNode = currentNode;
							break;
						}
					}
				}

				InsnList list = new InsnList();
				list.add(new LabelNode());
				list.add(new VarInsnNode(Opcodes.ALOAD, 0));
				list.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "code.elix_x.coremods.avoidexplodingcreepers.explosions.ExplosionSrcManager", "onUpdate", "(L" + EntityTNTPrimedClass.replace(".", "/") + ";)V"));
				method.instructions.insert(targetNode, list);

				System.out.println("Patching onUpdate Completed");
				System.out.println("**************************************************");
			}catch(Exception e){
				System.out.println("Patching onUpdate Failed With Exception:");
				e.printStackTrace();
				System.out.println("**************************************************");
			}
		}
	}

	ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
	classNode.accept(writer);
	return writer.toByteArray();
}

 

Notes:

1)i need to insert this after position updates (because reasons)

2)don't worry about AvoidExplodingCreepersTranslator.something and (string->) EntityTNTPrimedClass.replace(".", "/") : they always return good values (i tested via console) output)

3)crash report is the same (java.lang.ClassNotFoundException: net.minecraft.entity.item.EntityTNTPrimed)

 

Thanks for help...

Posted
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:transform:31]: ##################################################
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:transform:32]: Patching EntityTNTPrimed
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:patchEntityTNTPrimed:127]: **************************************************
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:patchEntityTNTPrimed:128]: Patching onUpdate
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:patchEntityTNTPrimed:157]: Patching onUpdate Completed
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:patchEntityTNTPrimed:158]: **************************************************
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:transform:35]: Patching EntityTNTPrimed Completed
[12:50:44] [main/INFO] [sTDOUT]: [code.elix_x.coremods.avoidexplodingcreepers.core.AvoidExplodingCreepersTransformer:transform:36]: ##################################################
[12:50:44] [main/ERROR] [LaunchWrapper]: Unable to launch
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_25]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_25]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_25]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_25]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.11.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.11.jar:?]
at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:78) [start/:?]
at GradleStart.main(GradleStart.java:45) [start/:?]
Caused by: java.lang.NoClassDefFoundError: net/minecraft/entity/item/EntityTNTPrimed
at net.minecraft.block.Block.registerBlocks(Block.java:289) ~[block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Caused by: java.lang.ClassNotFoundException: net.minecraft.entity.item.EntityTNTPrimed
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191) ~[launchwrapper-1.11.jar:?]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_25]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_25]
at net.minecraft.block.Block.registerBlocks(Block.java:289) ~[block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Caused by: java.lang.ClassFormatError: Illegal class name "code.elix_x.coremods.avoidexplodingcreepers.explosions.ExplosionSrcManager" in class file net/minecraft/entity/item/EntityTNTPrimed
at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_25]
at java.lang.ClassLoader.defineClass(Unknown Source) ~[?:1.8.0_25]
at java.security.SecureClassLoader.defineClass(Unknown Source) ~[?:1.8.0_25]
at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:182) ~[launchwrapper-1.11.jar:?]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_25]
at java.lang.ClassLoader.loadClass(Unknown Source) ~[?:1.8.0_25]
at net.minecraft.block.Block.registerBlocks(Block.java:289) ~[block.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:457) ~[bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release

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.

Announcements



×
×
  • Create New...

Important Information

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