From bf55408ff52a29ca0a7c9497c239cc2989bb4381 Mon Sep 17 00:00:00 2001 From: HerobaneNair Date: Tue, 16 Jun 2026 08:43:05 -0500 Subject: [PATCH] Fixing isLocalInstanceAuthoritative and getKnownMovement for EntityPlayerMPFakes (#2176) Fixes: - At least some spear attacks - Mace attacks (not verified myself) - Fall damage (#2198) Possibly needs further checking that isLocalInstanceAuthoritative doesn't break other things, but I don't have the time right now. Co-authored-by: altrisi --- src/main/java/carpet/mixins/EntityMixin.java | 3 +- .../ServerPlayer_fakeLastMovementMixin.java | 33 +++++++++++++++++++ .../carpet/patches/EntityPlayerMPFake.java | 5 --- src/main/resources/carpet.mixins.json | 1 + 4 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java diff --git a/src/main/java/carpet/mixins/EntityMixin.java b/src/main/java/carpet/mixins/EntityMixin.java index 4c781b08..3574ada6 100644 --- a/src/main/java/carpet/mixins/EntityMixin.java +++ b/src/main/java/carpet/mixins/EntityMixin.java @@ -38,7 +38,8 @@ public abstract class EntityMixin implements EntityInterface @Inject(method = "isLocalInstanceAuthoritative", at = @At("HEAD"), cancellable = true) private void isFakePlayer(CallbackInfoReturnable cir) { - if (getControllingPassenger() instanceof EntityPlayerMPFake) cir.setReturnValue(!level.isClientSide()); + // getControllingPassenger() does not return the EntityPlayerMPFake if there are no passengers involved with it + if ((Object) this instanceof EntityPlayerMPFake || getControllingPassenger() instanceof EntityPlayerMPFake) cir.setReturnValue(!level.isClientSide()); } @Shadow diff --git a/src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java b/src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java new file mode 100644 index 00000000..ab12fa88 --- /dev/null +++ b/src/main/java/carpet/mixins/ServerPlayer_fakeLastMovementMixin.java @@ -0,0 +1,33 @@ +package carpet.mixins; + +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Debug; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mojang.authlib.GameProfile; + +import carpet.patches.EntityPlayerMPFake; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; + +@Mixin(ServerPlayer.class) +@Debug(export = true) +public abstract class ServerPlayer_fakeLastMovementMixin extends Player { + public ServerPlayer_fakeLastMovementMixin(Level level, GameProfile gameProfile) { + super(level, gameProfile); + throw new AssertionError(); + } + + @ModifyExpressionValue( + method = {"getKnownMovement", "getKnownSpeed"}, // both because ServerPlayer overrides both to the same "movement" field + at = @At(value = "FIELD", target = "lastKnownClientMovement", opcode = Opcodes.GETFIELD), + require = 2 + ) + private Vec3 bypassClientMovementInfo(Vec3 original) { + return ((Player)this) instanceof EntityPlayerMPFake ? super.getKnownMovement() : original; + } +} diff --git a/src/main/java/carpet/patches/EntityPlayerMPFake.java b/src/main/java/carpet/patches/EntityPlayerMPFake.java index 5db6d5ea..f136eef8 100644 --- a/src/main/java/carpet/patches/EntityPlayerMPFake.java +++ b/src/main/java/carpet/patches/EntityPlayerMPFake.java @@ -267,11 +267,6 @@ public class EntityPlayerMPFake extends ServerPlayer return CarpetSettings.allowListingFakePlayers; } - @Override - protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) { - doCheckFallDamage(0.0, y, 0.0, onGround); - } - @Override public ServerPlayer teleport(TeleportTransition serverLevel) { diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index 2b09a204..d9b7cf43 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -49,6 +49,7 @@ "MobMixin", "Villager_aiMixin", "Player_fakePlayersMixin", + "ServerPlayer_fakeLastMovementMixin", "TickRateManager_fakePlayersMixin", "ServerGamePacketListenerImpl_coreMixin", "MinecraftServer_scarpetMixin",