From 2dc7993b412d3ee9fd95f8087a7bb9f8e1de2a8b Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Sun, 26 Jul 2026 12:52:44 +0000 Subject: [PATCH] fix(core/movement): don't trust fallTime reset while actually falling [porte d ArgusCore 814282b0] --- src/server/game/Entities/Player/Player.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 299c562..f2b0fef 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -28368,7 +28368,15 @@ bool Player::IsAreaThatActivatesPvpTalents(AreaTableEntry const* area) const void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode) { - if (m_lastFallTime >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == CMSG_MOVE_FALL_LAND) + // minfo.jump.fallTime is entirely client-supplied. While actually airborne + // (MOVEMENTFLAG_FALLING), a modified client can repeatedly report a non-increasing + // fallTime to keep re-baselining m_lastFallZ to the current (still dropping) height, + // erasing the real fall distance by the time it lands and avoiding fall damage + // entirely. Only trust a fallTime reset as "not falling" when the player isn't + // actually flagged as falling; the height-increased and landing conditions below are + // still server-observed and safe on their own. + bool fallTimeReset = m_lastFallTime >= minfo.jump.fallTime && !minfo.HasMovementFlag(MOVEMENTFLAG_FALLING); + if (fallTimeReset || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == CMSG_MOVE_FALL_LAND) SetFallInformation(minfo.jump.fallTime, minfo.pos.GetPositionZ()); }