Intresting
This commit is contained in:
@@ -7,6 +7,7 @@ import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.InsnNode;
|
||||
import org.objectweb.asm.tree.InsnList;
|
||||
import org.objectweb.asm.tree.LdcInsnNode;
|
||||
import org.objectweb.asm.tree.MethodInsnNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
@@ -17,6 +18,9 @@ import org.objectweb.asm.Opcodes;
|
||||
*/
|
||||
public final class BaseVehicleConstraintPatch {
|
||||
private static final String TARGET_NAME = "addPointConstraint";
|
||||
private static final String CLINIT_NAME = "<clinit>";
|
||||
private static final String VOID_NOARG_DESC = "()V";
|
||||
private static final String PATCH_LOG_LINE = "[Landtrain][BaseVehiclePatch] BaseVehicle override enabled";
|
||||
private static final String BREAK_DESC_OBJECT_BOOL = "(ZLjava/lang/Boolean;)V";
|
||||
private static final String BREAK_DESC_PRIMITIVE_BOOL = "(ZZ)V";
|
||||
private static final String BASE_VEHICLE_OWNER = "zombie/vehicles/BaseVehicle";
|
||||
@@ -55,13 +59,19 @@ public final class BaseVehicleConstraintPatch {
|
||||
+ inspectedAddPointMethods
|
||||
+ ")");
|
||||
}
|
||||
if (!ensureClassInitLog(classNode)) {
|
||||
throw new IllegalStateException("Failed to inject BaseVehicle class-init debug log");
|
||||
}
|
||||
|
||||
ClassWriter writer = new ClassWriter(0);
|
||||
classNode.accept(writer);
|
||||
|
||||
Files.createDirectories(output.getParent());
|
||||
Files.write(output, writer.toByteArray());
|
||||
System.out.println("Patched BaseVehicle.class; removed breakConstraint calls: " + removedCalls);
|
||||
System.out.println(
|
||||
"Patched BaseVehicle.class; removed breakConstraint calls: "
|
||||
+ removedCalls
|
||||
+ ", class-init debug log: enabled");
|
||||
}
|
||||
|
||||
private static boolean isTargetAddPointConstraint(String methodDesc) {
|
||||
@@ -102,4 +112,72 @@ public final class BaseVehicleConstraintPatch {
|
||||
|
||||
return patched;
|
||||
}
|
||||
|
||||
private static boolean ensureClassInitLog(ClassNode classNode) {
|
||||
MethodNode clinit = null;
|
||||
for (MethodNode method : classNode.methods) {
|
||||
if (CLINIT_NAME.equals(method.name) && VOID_NOARG_DESC.equals(method.desc)) {
|
||||
clinit = method;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (clinit == null) {
|
||||
clinit = new MethodNode(Opcodes.ACC_STATIC, CLINIT_NAME, VOID_NOARG_DESC, null, null);
|
||||
clinit.instructions = new InsnList();
|
||||
clinit.instructions.add(createPatchLogInstructions());
|
||||
clinit.instructions.add(new InsnNode(Opcodes.RETURN));
|
||||
clinit.maxStack = 2;
|
||||
clinit.maxLocals = 0;
|
||||
classNode.methods.add(clinit);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasPatchLog(clinit)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean inserted = false;
|
||||
for (AbstractInsnNode node = clinit.instructions.getFirst(); node != null; ) {
|
||||
AbstractInsnNode next = node.getNext();
|
||||
if (node.getOpcode() == Opcodes.RETURN) {
|
||||
clinit.instructions.insertBefore(node, createPatchLogInstructions());
|
||||
inserted = true;
|
||||
}
|
||||
node = next;
|
||||
}
|
||||
|
||||
if (inserted) {
|
||||
clinit.maxStack = Math.max(clinit.maxStack, 2);
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
|
||||
private static boolean hasPatchLog(MethodNode method) {
|
||||
for (AbstractInsnNode node = method.instructions.getFirst(); node != null; node = node.getNext()) {
|
||||
if (node instanceof LdcInsnNode ldc
|
||||
&& ldc.cst instanceof String text
|
||||
&& PATCH_LOG_LINE.equals(text)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static InsnList createPatchLogInstructions() {
|
||||
InsnList insns = new InsnList();
|
||||
insns.add(new org.objectweb.asm.tree.FieldInsnNode(
|
||||
Opcodes.GETSTATIC,
|
||||
"java/lang/System",
|
||||
"out",
|
||||
"Ljava/io/PrintStream;"));
|
||||
insns.add(new LdcInsnNode(PATCH_LOG_LINE));
|
||||
insns.add(new MethodInsnNode(
|
||||
Opcodes.INVOKEVIRTUAL,
|
||||
"java/io/PrintStream",
|
||||
"println",
|
||||
"(Ljava/lang/String;)V",
|
||||
false));
|
||||
return insns;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user