diff --git a/tools/java/BaseVehicleConstraintPatch.java b/tools/java/BaseVehicleConstraintPatch.java index 45e217c..dc85fba 100644 --- a/tools/java/BaseVehicleConstraintPatch.java +++ b/tools/java/BaseVehicleConstraintPatch.java @@ -21,6 +21,7 @@ import org.objectweb.asm.tree.VarInsnNode; */ public final class BaseVehicleConstraintPatch { private static final String TARGET_NAME = "addPointConstraint"; + private static final String UPDATE_NAME = "update"; private static final String CONSTRAINT_CHANGED_NAME = "constraintChanged"; private static final String AUTHORIZATION_CHANGED_NAME = "authorizationChanged"; private static final String AUTHORIZATION_CLIENT_COLLIDE_NAME = "authorizationClientCollide"; @@ -49,6 +50,9 @@ public final class BaseVehicleConstraintPatch { private static final String BULLET_ADD_POINT = "addPointConstraint"; private static final String BULLET_ADD_ROPE_DESC = "(IIFFFFFFF)I"; private static final String BULLET_ADD_POINT_DESC = "(IIFFFFFF)I"; + private static final String CAR_CONTROLLER_OWNER = "zombie/core/physics/CarController"; + private static final String CAR_CONTROLLER_PARK = "park"; + private static final String CAR_CONTROLLER_PARK_DESC = "()V"; private static final String GET_DRIVER_DESC = "()Lzombie/characters/IsoGameCharacter;"; private static final String HELPER_OWNER = "zombie/vehicles/LandtrainConstraintAuthHelper"; private static final String HELPER_METHOD = "resolveConstraintDriver"; @@ -75,6 +79,9 @@ public final class BaseVehicleConstraintPatch { "authorizationServerOnSeatLandtrain"; private static final String HELPER_AUTHORIZATION_SERVER_ON_SEAT_DESC = "(Lzombie/vehicles/BaseVehicle;Lzombie/characters/IsoPlayer;Z)V"; + private static final String HELPER_SAFE_PARK = "safeParkControllerLandtrain"; + private static final String HELPER_SAFE_PARK_DESC = + "(Lzombie/core/physics/CarController;)V"; private static final class AddPointPatchStats { int removedBreakCalls; @@ -107,6 +114,7 @@ public final class BaseVehicleConstraintPatch { int patchedAuthorizationClientCollideMethods = 0; int patchedAuthorizationServerCollideMethods = 0; int patchedAuthorizationServerOnSeatMethods = 0; + int patchedSafeParkCalls = 0; for (MethodNode method : classNode.methods) { if (TARGET_NAME.equals(method.name) && isTargetAddPointConstraint(method.desc)) { @@ -114,6 +122,8 @@ public final class BaseVehicleConstraintPatch { AddPointPatchStats stats = patchAddPointConstraint(method); removedCalls += stats.removedBreakCalls; forcedRigidCalls += stats.forcedRigidCalls; + } else if (UPDATE_NAME.equals(method.name) && VOID_NOARG_DESC.equals(method.desc)) { + patchedSafeParkCalls += patchNullSafeParkCalls(method); } else if (CONSTRAINT_CHANGED_NAME.equals(method.name) && VOID_NOARG_DESC.equals(method.desc)) { patchedConstraintDriverCalls += patchConstraintChangedDriverCalls(method); @@ -198,6 +208,11 @@ public final class BaseVehicleConstraintPatch { "Expected to patch authorizationServerOnSeat, patched " + patchedAuthorizationServerOnSeatMethods); } + if (patchedSafeParkCalls < 1) { + throw new IllegalStateException( + "Expected to patch at least 1 CarController.park call, patched " + + patchedSafeParkCalls); + } if (patchedEnterBlockedCalls < 1) { throw new IllegalStateException( "Expected to patch isEnterBlocked call, patched " + patchedEnterBlockedCalls); @@ -230,6 +245,8 @@ public final class BaseVehicleConstraintPatch { + patchedAuthorizationServerCollideMethods + "/" + patchedAuthorizationServerOnSeatMethods + + ", safe park hooks: " + + patchedSafeParkCalls + ", enter-block hooks: " + patchedEnterBlockedCalls + "/" @@ -318,6 +335,36 @@ public final class BaseVehicleConstraintPatch { return patched; } + private static int patchNullSafeParkCalls(MethodNode method) { + int patched = 0; + InsnList insns = method.instructions; + for (AbstractInsnNode node = insns.getFirst(); node != null; ) { + AbstractInsnNode next = node.getNext(); + if (!(node instanceof MethodInsnNode call)) { + node = next; + continue; + } + if (!CAR_CONTROLLER_OWNER.equals(call.owner) + || !CAR_CONTROLLER_PARK.equals(call.name) + || !CAR_CONTROLLER_PARK_DESC.equals(call.desc)) { + node = next; + continue; + } + + MethodInsnNode replacement = + new MethodInsnNode( + Opcodes.INVOKESTATIC, + HELPER_OWNER, + HELPER_SAFE_PARK, + HELPER_SAFE_PARK_DESC, + false); + insns.set(call, replacement); + patched++; + node = next; + } + return patched; + } + private static int patchMethodDelegateToHelper( MethodNode method, String helperMethod, String helperDesc) { InsnList insns = new InsnList(); diff --git a/tools/java/LandtrainConstraintAuthHelper.java b/tools/java/LandtrainConstraintAuthHelper.java index 016e22b..f12dc0f 100644 --- a/tools/java/LandtrainConstraintAuthHelper.java +++ b/tools/java/LandtrainConstraintAuthHelper.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Set; import zombie.characters.IsoGameCharacter; import zombie.characters.IsoPlayer; +import zombie.core.physics.CarController; /** * Resolves the effective driver for constraint auth in chained towing. @@ -195,4 +196,10 @@ public final class LandtrainConstraintAuthHelper { } } } + + public static void safeParkControllerLandtrain(CarController controller) { + if (controller != null) { + controller.park(); + } + } } diff --git a/zombie/vehicles/BaseVehicle.class b/zombie/vehicles/BaseVehicle.class index a93c7ad..8f6e13c 100644 Binary files a/zombie/vehicles/BaseVehicle.class and b/zombie/vehicles/BaseVehicle.class differ diff --git a/zombie/vehicles/LandtrainConstraintAuthHelper.class b/zombie/vehicles/LandtrainConstraintAuthHelper.class index b092a3c..1893e8e 100644 Binary files a/zombie/vehicles/LandtrainConstraintAuthHelper.class and b/zombie/vehicles/LandtrainConstraintAuthHelper.class differ