From 26bb8f45a6d7b397ecb8294bc1ce5b9ccbc5605a Mon Sep 17 00:00:00 2001 From: Myst1cS04p Date: Mon, 17 Nov 2025 07:53:39 +0300 Subject: [PATCH] Fix setVelocity infinite regress crash Added a guard flag to BukkitPlayer.setVelocity and PlayerKnockbackListener.onPlayerVelocity. Hopefully ts guard flag will stop ts plugin from looping endlessly and crashing the server --- .../knockbacksync/player/BukkitPlayer.java | 20 ++++++++++++++++++- .../listener/PlayerKnockbackListener.java | 5 +++++ .../knockbacksync/player/PlayerData.java | 2 ++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/bukkit/src/main/java/me/caseload/knockbacksync/player/BukkitPlayer.java b/bukkit/src/main/java/me/caseload/knockbacksync/player/BukkitPlayer.java index f928fc1c..02db0525 100644 --- a/bukkit/src/main/java/me/caseload/knockbacksync/player/BukkitPlayer.java +++ b/bukkit/src/main/java/me/caseload/knockbacksync/player/BukkitPlayer.java @@ -8,6 +8,7 @@ import com.google.common.base.Preconditions; import me.caseload.knockbacksync.BukkitBase; import me.caseload.knockbacksync.Platform; +import me.caseload.knockbacksync.manager.PlayerDataManager; import me.caseload.knockbacksync.world.FoliaWorld; import me.caseload.knockbacksync.world.PlatformWorld; import me.caseload.knockbacksync.world.SpigotWorld; @@ -190,7 +191,24 @@ public int getMainHandKnockbackLevel() { @Override public void setVelocity(Vector3d adjustedVelocity) { - bukkitPlayer.setVelocity(new Vector(adjustedVelocity.x, adjustedVelocity.y, adjustedVelocity.z)); + PlayerData data = PlayerDataManager.getPlayerData(this.getUser()); + + if(data == null){ + // Fallback to normal behavior in the absence of a guard + bukkitPlayer.setVelocity(new Vector(adjustedVelocity.x, adjustedVelocity.y, adjustedVelocity.z)); + return; + } + + if(data.isVelocityGuard()){ + return; // Already applying velocity + } + + data.setVelocityGuard(true); + try { + this.bukkitPlayer.setVelocity(new Vector(adjustedVelocity.x, adjustedVelocity.y, adjustedVelocity.z)); + } finally { + data.setVelocityGuard(false); + } } @Override diff --git a/common/src/main/java/me/caseload/knockbacksync/listener/PlayerKnockbackListener.java b/common/src/main/java/me/caseload/knockbacksync/listener/PlayerKnockbackListener.java index 0878ac17..fe39346a 100644 --- a/common/src/main/java/me/caseload/knockbacksync/listener/PlayerKnockbackListener.java +++ b/common/src/main/java/me/caseload/knockbacksync/listener/PlayerKnockbackListener.java @@ -21,6 +21,9 @@ public void onPlayerVelocity(PlatformPlayer victim, Vector3d velocity) { PlayerData victimPlayerData = PlayerDataManager.getPlayerData(user); if (victimPlayerData == null) return; + if (victimPlayerData.isVelocityGuard()) { // Prevent velocity setter from looping infinitely + return; + } if (victimPlayerData.getNotNullPing() < PlayerData.PING_OFFSET) return; @@ -50,6 +53,8 @@ else if (victimPlayerData.isOffGroundSyncEnabled()) else return; + victimPlayerData.setVelocityGuard(true);; victim.setVelocity(adjustedVelocity); + victimPlayerData.setVelocityGuard(false); } } \ No newline at end of file diff --git a/common/src/main/java/me/caseload/knockbacksync/player/PlayerData.java b/common/src/main/java/me/caseload/knockbacksync/player/PlayerData.java index dbad8279..b8efa0bd 100644 --- a/common/src/main/java/me/caseload/knockbacksync/player/PlayerData.java +++ b/common/src/main/java/me/caseload/knockbacksync/player/PlayerData.java @@ -47,6 +47,8 @@ public class PlayerData { public static final long PING_OFFSET = 25; private static Field playerField; + @Getter @Setter + private boolean velocityGuard = false; // Used to prevent infinite recursion while setting velocity public final Queue> transactionsSent = new ConcurrentLinkedQueue<>(); public final Queue> keepaliveMap = new ConcurrentLinkedQueue<>();