Jump to content

Recommended Posts

Posted (edited)

Hi.

I am trying to write a small coremod for my 1.12.2 private server to disable the "Moved wrongly" and maybe the "Moved too quickly" checks in NetHandlerPlayServer, as it is very buggy with Psi's Blink-spell, just teleports you back constantly.

 

First of all, I know this is a security risk because of hacking, but as I said, it's a private server so I don't care about that.

Second, I sadly don't have much experience in modding Minecraft and especially not in bytecode and that sort of stuff in Java.

 

So I got most of the code from this post and just tried to update it for 1.12.2.

But according to the printlns I added in analyzeClass the methods I need to patch (processVehicleMove and processPlayer) aren't even scanned through.

So I don't know if I'm doing the scanning wrong or if there is something else.

Everything else seems to work, the mod is loaded and is shown in the Mods-section as expected, so the error must be in this class.

 

Any help would be appreciated.

Thanks : )

 

package rsge.mods.blinkfixer.asm;

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.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodNode;

import net.minecraft.launchwrapper.IClassTransformer;


/**
 * Removes the "Moved Wrongly" checks from {@link net.minecraft.network.NetHandlerPlayServer}
 * 
 * @author Rsge
 */
public class NetHandlerPlayServerTransformer implements IClassTransformer
{
	private static enum MovedWronglyState
	{
		FIND_LDC, FIND_DCMPL, FIND_IFLE, DONE
	}

	/**
	 * Before: LDC2_W 0.0625 DCMPL IFLE <label> (code to execute if the value was greater) After: LDC2_W 0.0625 DCMPL IFLE <label> GOTO <same label> (code that
	 * no longer ever gets executed) I leave the IFLE in just so the DCMPL result gets popped off the stack
	 */
	private boolean disableMovedWrongly(MethodNode node)
	{
		MovedWronglyState state = MovedWronglyState.FIND_LDC;
		InsnList insnList = node.instructions;
		AbstractInsnNode insn = insnList.getFirst();
		AbstractInsnNode patchTarget = null;
		LabelNode gotoLabel = null;

		while (insn != null && state != MovedWronglyState.DONE)
		{
			switch (state)
			{
			case FIND_LDC:
				if (insn.getOpcode() == Opcodes.LDC)
				{
					Object value = ((LdcInsnNode) insn).cst;
					// 0.0625 is 1/16, which can be perfectly represented by a float (power of two denominator)
					if (value instanceof Double && ((Double) value).doubleValue() == 0.0625)
					{
						state = MovedWronglyState.FIND_DCMPL;
					}

				}
				break;

			case FIND_DCMPL:
				if (insn.getOpcode() == Opcodes.DCMPL)
				{
					state = MovedWronglyState.FIND_IFLE;
				}
				else
				{
					state = MovedWronglyState.FIND_LDC;
				}
				break;

			case FIND_IFLE:
				if (insn.getOpcode() == Opcodes.IFLE)
				{
					state = MovedWronglyState.DONE;
					gotoLabel = ((JumpInsnNode) insn).label;
					patchTarget = insn;
				}
				else
				{
					state = MovedWronglyState.FIND_LDC;
				}
				break;
			case DONE:
				break;
			default:
				break;
			}
			insn = insn.getNext();
		}

		if (state == MovedWronglyState.DONE)
		{
			applyGotoPatch(insnList, gotoLabel, patchTarget);
			return true;
		}
		else
		{
			return false;
		}

	}

	/* ————————————————————————————————————————————————————— */

	private static enum MovedTooQuicklyState
	{
		FIND_LDC, FIND_DCMPL, FIND_IFLE, DONE
	}

	/**
	 * Before: LDC2_W 100.0 DCMPL IFLE <label> (code to execute if the value was greater) After: LDC2_W 100.0 DCMPL IFLE <label> GOTO <same label> (code that no
	 * longer ever gets executed) As above, I leave the IFLE in so the DCMPL result gets popped off the stack
	 */
	private boolean disableMovedTooQuickly(MethodNode node)
	{
		MovedTooQuicklyState state = MovedTooQuicklyState.FIND_LDC;
		InsnList insnList = node.instructions;
		AbstractInsnNode insn = insnList.getFirst();
		AbstractInsnNode patchTarget = null;
		LabelNode gotoLabel = null;

		while (insn != null && state != MovedTooQuicklyState.DONE)
		{
			switch (state)
			{
			case FIND_LDC:
				if (insn.getOpcode() == Opcodes.LDC)
				{
					Object value = ((LdcInsnNode) insn).cst;
					if (value instanceof Double && ((Double) value).doubleValue() == 100.0)
					{
						state = MovedTooQuicklyState.FIND_DCMPL;
					}
				}
				break;

			case FIND_DCMPL:
				if (insn.getOpcode() == Opcodes.DCMPL)
				{
					state = MovedTooQuicklyState.FIND_IFLE;
				}
				else
				{
					state = MovedTooQuicklyState.FIND_LDC;
				}
				break;

			case FIND_IFLE:
				if (insn.getOpcode() == Opcodes.IFLE)
				{
					state = MovedTooQuicklyState.DONE;
					gotoLabel = ((JumpInsnNode) insn).label;
					patchTarget = insn;
				}
				else
				{
					state = MovedTooQuicklyState.FIND_LDC;
				}
				break;
			case DONE:
				break;
			default:
				break;
			}

			insn = insn.getNext();
		}

		if (state == MovedTooQuicklyState.DONE)
		{
			applyGotoPatch(insnList, gotoLabel, patchTarget);
			return true;
		}
		else
		{
			return false;
		}

	}

	/* ————————————————————————————————————————————————————— */

	private void applyGotoPatch(InsnList instr, LabelNode lbl, AbstractInsnNode trg)
	{
		instr.insert(trg, generatePatch(lbl));
	}

	private InsnList generatePatch(LabelNode lbl)
	{
		InsnList list = new InsnList();
		list.add(new JumpInsnNode(Opcodes.GOTO, lbl));
		return list;
	}

	/* ————————————————————————————————————————————————————— */

	private boolean analyzeClass(ClassNode node)
	{
		boolean successVehicleMove = false;
		boolean successProcessPlayer = false;

		for (MethodNode method : node.methods)
		{
			System.out.println("Method: " + method.name);
			// Method processVehicleMove
			if (method.name.equals("a") && method.desc.equals("(Lll;)V"))
			{
				successVehicleMove = disableMovedTooQuickly(method) && disableMovedWrongly(method);
			}
			// Method processPlayer
			if (method.name.equals("a") && method.desc.equals("(Llk;)V"))
			{
				successProcessPlayer = disableMovedTooQuickly(method) && disableMovedWrongly(method);
			}
		}
		if (!(successVehicleMove && successProcessPlayer))
			System.out.println("Unabled to find method to patch");
		
		return successVehicleMove && successProcessPlayer;
	}

	@Override
	public byte[] transform(String name, String transname, byte[] bytes)
	{
		if (transname.contains("net.minecraft.network"))
			System.out.println(name + "; " + transname);
		if (transname.contains("net.minecraft.network.NetHandlerPlayServer"))
		{
			System.out.println("Class to transform: " + transname);
			ClassReader reader = new ClassReader(bytes);
			ClassNode node = new ClassNode();
			reader.accept(node, 0);

			if (analyzeClass(node))
			{
				ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
				node.accept(writer);
				bytes = writer.toByteArray();
			}
			else
			{
				System.out.println("Failed to patch methods");
			}
		}
		return bytes;
	}
}

 

Edited by Rsge
Posted

Thats not going to work, thats extremely old code targeted at a very old version. If you don't already know how to write a coremod, don't. You need to have extensive knowledge of ASM, IJVM code and how the JVM works to write a coremod.

 

9 hours ago, Rsge said:

as it is very buggy with Psi's Blink-spell

Tell the author to fix this issue then.

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Posted (edited)
6 hours ago, Cadiboo said:

thats extremely old code targeted at a very old version.

That's why I'm trying to update it so it does work.

 

6 hours ago, Cadiboo said:

Tell the author to fix this issue then. 

I don't think Vazkii will disable these checks as they have their security reasons.

Also, it seems to be different on different servers/modpacks, as another 1.12.2-modpack I played didn't have this issue - at least not as bad as in the other pack.

So I don't think this is necessarily a bug in Psi itself... - I'll report it regardless, if he still does 1.12.2-fixes...

Edited by Rsge

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.