9
0
mirror of https://github.com/SparklyPower/SparklyPaper.git synced 2025-12-19 15:09:27 +00:00

Add PlayerPreMoveEvent

This commit is contained in:
MrPowerGamerBR
2025-01-08 23:08:47 -03:00
parent 81aca647ae
commit 8e2077ebe5
6 changed files with 265 additions and 0 deletions

View File

@@ -0,0 +1,179 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrPowerGamerBR <git@mrpowergamerbr.com>
Date: Wed, 8 Jan 2025 22:49:00 -0300
Subject: [PATCH] Add PlayerPreMoveEvent
diff --git a/src/main/java/net/sparklypower/sparklypaper/event/player/PlayerPreMoveEvent.java b/src/main/java/net/sparklypower/sparklypaper/event/player/PlayerPreMoveEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..de57542c3a0ff3e093611f8362c60560a7ded964
--- /dev/null
+++ b/src/main/java/net/sparklypower/sparklypaper/event/player/PlayerPreMoveEvent.java
@@ -0,0 +1,167 @@
+package net.sparklypower.sparklypaper.event.player;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.player.PlayerEvent;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Called after the server attempts to move the player, but before the PlayerMoveEvent is called.
+ * <p>
+ * In contrast to PlayerMoveEvent, this event happens on every movement instead of being throttled like PlayerMoveEvent,
+ * and this event exposes the player's onGround/horizontalCollision status, allowing plugins to manipulate it.
+ */
+public class PlayerPreMoveEvent extends PlayerEvent {
+ private static final HandlerList handlers = new HandlerList();
+ private final Location from;
+ private final Location to;
+ private boolean onGround;
+ private boolean horizontalCollision;
+ private boolean resetFallDistance;
+
+ public PlayerPreMoveEvent(@NotNull final Player player, @NotNull final Location from, @Nullable final Location to, boolean onGround, boolean horizontalCollision, boolean resetFallDistance) {
+ super(player);
+ this.from = from;
+ this.to = to;
+ this.onGround = onGround;
+ this.horizontalCollision = horizontalCollision;
+ this.resetFallDistance = resetFallDistance;
+ }
+
+ /**
+ * Gets the location this player moved from
+ *
+ * @return Location the player moved from
+ */
+ @NotNull
+ public Location getFrom() {
+ return from;
+ }
+
+ /**
+ * Gets the location this player moved to
+ *
+ * @return Location the player moved to
+ */
+ @NotNull // Paper
+ public Location getTo() {
+ return to;
+ }
+
+ // Paper start - PlayerMoveEvent improvements
+ /**
+ * Check if the player has changed position (even within the same block) in the event
+ *
+ * @return whether the player has changed position or not
+ */
+ public boolean hasChangedPosition() {
+ return hasExplicitlyChangedPosition() || !from.getWorld().equals(to.getWorld());
+ }
+
+ /**
+ * Check if the player has changed position (even within the same block) in the event, disregarding a possible world change
+ *
+ * @return whether the player has changed position or not
+ */
+ public boolean hasExplicitlyChangedPosition() {
+ return from.getX() != to.getX() || from.getY() != to.getY() || from.getZ() != to.getZ();
+ }
+
+ /**
+ * Check if the player has moved to a new block in the event
+ *
+ * @return whether the player has moved to a new block or not
+ */
+ public boolean hasChangedBlock() {
+ return hasExplicitlyChangedBlock() || !from.getWorld().equals(to.getWorld());
+ }
+
+ /**
+ * Check if the player has moved to a new block in the event, disregarding a possible world change
+ *
+ * @return whether the player has moved to a new block or not
+ */
+ public boolean hasExplicitlyChangedBlock() {
+ return from.getBlockX() != to.getBlockX() || from.getBlockY() != to.getBlockY() || from.getBlockZ() != to.getBlockZ();
+ }
+
+ /**
+ * Check if the player has changed orientation in the event
+ *
+ * @return whether the player has changed orientation or not
+ */
+ public boolean hasChangedOrientation() {
+ return from.getPitch() != to.getPitch() || from.getYaw() != to.getYaw();
+ }
+ // Paper end
+
+ /**
+ * Gets if the client said that they are on ground, keep in mind that this value is controlled by the client, so it can
+ * be spoofed by malicious clients or be out of sync.
+ *
+ * @return if the client said that the is on ground
+ */
+ public boolean isOnGround() {
+ return onGround;
+ }
+
+ /**
+ * Sets if the player should be on ground.
+ *
+ * @param onGround true if the player should be on ground
+ */
+ public void setOnGround(boolean onGround) {
+ this.onGround = onGround;
+ }
+
+ /**
+ * Gets if the client said that they are horizontally colliding, keep in mind that this value is controlled by the client, so it can
+ * be spoofed by malicious clients or be out of sync.
+ *
+ * @return if the player is horizontally colliding on a block
+ */
+ public boolean isHorizontalCollision() {
+ return horizontalCollision;
+ }
+
+ /**
+ * Sets if the player should be horizontally colliding on a block.
+ *
+ * @param horizontalCollision true if the player should be colliding horizontally be on ground
+ */
+ public void setHorizontalCollision(boolean horizontalCollision) {
+ this.horizontalCollision = horizontalCollision;
+ }
+
+ /**
+ * Gets if the player's fall distance should be reset. By default, the fall distance is reset every time the player moves upwards on the y axis.
+ *
+ * @return if the fall distance should be reset
+ */
+ public boolean isResetFallDistance() {
+ return resetFallDistance;
+ }
+
+ /**
+ * Sets if the player's fall distance should be reset.
+ *
+ * @param resetFallDistance true if the player fall distance should be reset
+ */
+ public void setResetFallDistance(boolean resetFallDistance) {
+ this.resetFallDistance = resetFallDistance;
+ }
+
+ @NotNull
+ @Override
+ public HandlerList getHandlers() {
+ return handlers;
+ }
+
+ @NotNull
+ public static HandlerList getHandlerList() {
+ return handlers;
+ }
+
+}

View File

@@ -0,0 +1,86 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MrPowerGamerBR <git@mrpowergamerbr.com>
Date: Wed, 8 Jan 2025 22:48:04 -0300
Subject: [PATCH] Add PlayerPreMoveEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index ac0af5da6646df1cfe66aead3f945a9f77efa5de..3a74c35da37326ee52bc7ccee79791732cb2e092 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1462,7 +1462,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
d6 = d0 - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
d7 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
d8 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
- boolean flag1 = d7 > 0.0D;
+ boolean flag1 = d7 > 0.0D; // SparklyPaper - diff on change, used to reset the fall distance, checks if d7 is > 0.0D (player is moving upwards)
if (this.player.onGround() && !packet.isOnGround() && flag1) {
// Paper start - Add PlayerJumpEvent
@@ -1498,7 +1498,37 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
boolean flag2 = this.player.verticalCollisionBelow;
this.player.move(MoverType.PLAYER, new Vec3(d6, d7, d8));
- this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
+ // SparklyPaper start - Add PlayerPreMoveEvent event
+ boolean isOnGround = packet.isOnGround();
+ boolean horizontalCollision = packet.horizontalCollision();
+ if (net.sparklypower.sparklypaper.event.player.PlayerPreMoveEvent.getHandlerList().getRegisteredListeners().length != 0) {
+ Player player = this.getCraftPlayer();
+ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
+
+ // If the packet contains movement information then we update the To location with the correct XYZ.
+ if (packet.hasPos) {
+ to.setX(packet.x);
+ to.setY(packet.y);
+ to.setZ(packet.z);
+ }
+
+ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
+ if (packet.hasRot) {
+ to.setYaw(packet.yRot);
+ to.setPitch(packet.xRot);
+ }
+
+ net.sparklypower.sparklypaper.event.player.PlayerPreMoveEvent event = new net.sparklypower.sparklypaper.event.player.PlayerPreMoveEvent(player, from, to, packet.isOnGround(), packet.horizontalCollision(), flag1);
+
+ if (event.callEvent()) {
+ isOnGround = event.isOnGround();
+ horizontalCollision = event.isHorizontalCollision();
+ flag1 = event.isResetFallDistance();
+ }
+ }
+ // SparklyPaper end
+ this.player.onGround = isOnGround; // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move // SparklyPaper - Add PlayerPreMoveEvent
boolean didCollide = toX != this.player.getX() || toY != this.player.getY() || toZ != this.player.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
// Paper start - prevent position desync
if (this.awaitingPositionFromClient != null) {
@@ -1551,7 +1581,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
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());
+ this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, isOnGround); // SparklyPaper - Add PlayerPreMoveEvent
} else {
// CraftBukkit start - fire PlayerMoveEvent
// Reset to old location first
@@ -1626,15 +1656,15 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.player.serverLevel().getChunkSource().move(this.player);
Vec3 vec3d = new Vec3(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5);
- this.player.setOnGroundWithMovement(packet.isOnGround(), packet.horizontalCollision(), vec3d);
- this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, packet.isOnGround());
+ this.player.setOnGroundWithMovement(isOnGround, horizontalCollision, vec3d); // SparklyPaper start - PlayerPreMoveEvent
+ this.player.doCheckFallDamage(this.player.getX() - d3, this.player.getY() - d4, this.player.getZ() - d5, isOnGround); // SparklyPaper - PlayerPreMoveEvent
this.player.recordMovementThroughBlocks(new Vec3(d3, d4, d5), this.player.position());
this.handlePlayerKnownMovement(vec3d);
if (flag1) {
this.player.resetFallDistance();
}
- if (packet.isOnGround() || this.player.hasLandedInLiquid() || this.player.onClimbable() || this.player.isSpectator() || flag || flag4) {
+ if (isOnGround || this.player.hasLandedInLiquid() || this.player.onClimbable() || this.player.isSpectator() || flag || flag4) { // SparklyPaper - PlayerPreMoveEvent
this.player.tryResetCurrentImpulseContext();
}