Paper/patches/server/0834-Implement-PlayerFailMoveEvent.patch
Bjarne Koll ad9c58e103
Only expose velocity relative tp flags to API (#11532)
Since 1.21.2, vanilla split relative teleportation flags into position
and delta/velocity flags into separate enum entries.
This highlighted a design flaw in the paper api addition for teleport
flags, which just simply mirrored internals while also only being able
to apply the delta/velocity part of a flag, given the teleport target is
always absolute in the API.

This patch proposes to simply no longer expose the non-velocity related
flags to the API, instead marking the entire Relative enum as being
purely velocity related, as non-velocity related flags are not useful to
callers. This was done over simply exposing all internal flags, as
another vanilla change to the internal enum would result in the same
breakage.

The newly proposed API *only* promises that the passed flags prevent the
loss of velocity in the specific axis/context, which should be
independent enough of vanillas specific implementation of this feature.
2024-10-31 17:25:52 +01:00

112 lines
9.1 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Moulberry <james.jenour@protonmail.com>
Date: Wed, 26 Jul 2023 20:13:31 +0800
Subject: [PATCH] Implement PlayerFailMoveEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index e653dc4ac16fd22674a6c1ba402f8913e0fbb336..2de655df951199c74758578c7f00fa053851b55e 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1271,8 +1271,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
double d0 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX(this.player.getX())); final double toX = d0; // Paper - OBFHELPER
double d1 = ServerGamePacketListenerImpl.clampVertical(packet.getY(this.player.getY())); final double toY = d1; // Paper - OBFHELPER
double d2 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ(this.player.getZ())); final double toZ = d2; // Paper - OBFHELPER
- float f = Mth.wrapDegrees(packet.getYRot(this.player.getYRot()));
- float f1 = Mth.wrapDegrees(packet.getXRot(this.player.getXRot()));
+ float f = Mth.wrapDegrees(packet.getYRot(this.player.getYRot())); final float toYaw = f; // Paper - OBFHELPER
+ float f1 = Mth.wrapDegrees(packet.getXRot(this.player.getXRot())); final float toPitch = f1; // Paper - OBFHELPER
if (this.player.isPassenger()) {
this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1);
@@ -1339,8 +1339,14 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
// Paper start - Prevent moving into unloaded chunks
if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) {
- this.internalTeleport(PositionMoveRotation.of(this.player), Collections.emptySet());
- return;
+ // Paper start - Add fail move event
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_INTO_UNLOADED_CHUNK,
+ toX, toY, toZ, toYaw, toPitch, false);
+ if (!event.isAllowed()) {
+ this.internalTeleport(PositionMoveRotation.of(this.player), Collections.emptySet());
+ return;
+ }
+ // Paper end - Add fail move event
}
// Paper end - Prevent moving into unloaded chunks
@@ -1349,9 +1355,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
if (d10 - d9 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2))) {
// CraftBukkit end
- ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8});
- this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot());
- return;
+ // Paper start - Add fail move event
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY,
+ toX, toY, toZ, toYaw, toPitch, true);
+ if (!event.isAllowed()) {
+ if (event.getLogWarning())
+ ServerGamePacketListenerImpl.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[]{this.player.getName().getString(), d6, d7, d8});
+ this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot());
+ return;
+ }
+ // Paper end - Add fail move event
}
}
}
@@ -1413,14 +1426,31 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
d8 = d2 - this.player.getZ();
d10 = d6 * d6 + d7 * d7 + d8 * d8;
- boolean flag3 = false;
+ boolean movedWrongly = false; // Paper - Add fail move event; rename
if (!this.player.isChangingDimension() && d10 > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.isSleeping() && !this.player.gameMode.isCreative() && this.player.gameMode.getGameModeForPlayer() != GameType.SPECTATOR) { // Spigot
- flag3 = true;
+ // Paper start - Add fail move event
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY,
+ toX, toY, toZ, toYaw, toPitch, true);
+ if (!event.isAllowed()) {
+ movedWrongly = true;
+ if (event.getLogWarning())
+ // Paper end
ServerGamePacketListenerImpl.LOGGER.warn("{} moved wrongly!", this.player.getName().getString());
+ } // Paper
}
- if (!this.player.noPhysics && !this.player.isSleeping() && (flag3 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2))) {
+ // Paper start - Add fail move event
+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2));
+ if (teleportBack) {
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
+ toX, toY, toZ, toYaw, toPitch, false);
+ if (event.isAllowed()) {
+ teleportBack = false;
+ }
+ }
+ if (teleportBack) {
+ // Paper end - Add fail move event
this.internalTeleport(d3, d4, d5, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet.
this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround());
} else {
@@ -3535,4 +3565,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand);
}
+
+ // Paper start - Add fail move event
+ private io.papermc.paper.event.player.PlayerFailMoveEvent fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason failReason,
+ double toX, double toY, double toZ, float toYaw, float toPitch, boolean logWarning) {
+ Player player = this.getCraftPlayer();
+ Location from = new Location(player.getWorld(), this.lastPosX, this.lastPosY, this.lastPosZ, this.lastYaw, this.lastPitch);
+ Location to = new Location(player.getWorld(), toX, toY, toZ, toYaw, toPitch);
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = new io.papermc.paper.event.player.PlayerFailMoveEvent(player, failReason,
+ false, logWarning, from, to);
+ event.callEvent();
+ return event;
+ }
+ // Paper end - Add fail move event
}