From c0d5742f5d0c69c0cd6f305bcf9e87c77e78bc75 Mon Sep 17 00:00:00 2001 From: ratkosrb Date: Sun, 17 Dec 2023 02:56:54 +0200 Subject: [PATCH] Fix some false positives with movement anticheat. Closes https://github.com/vmangos/core/issues/2338 --- .../MovementAnticheat/MovementAnticheat.cpp | 23 ++++++++++++++----- src/game/Movement/PointMovementGenerator.cpp | 2 +- src/game/Movement/spline/MoveSplineInit.cpp | 1 + src/game/Objects/Player.cpp | 4 ++-- src/game/Objects/Unit.cpp | 5 +++- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/game/Anticheat/MovementAnticheat/MovementAnticheat.cpp b/src/game/Anticheat/MovementAnticheat/MovementAnticheat.cpp index 733c1bcc2e4..8b97d8daf01 100644 --- a/src/game/Anticheat/MovementAnticheat/MovementAnticheat.cpp +++ b/src/game/Anticheat/MovementAnticheat/MovementAnticheat.cpp @@ -972,7 +972,7 @@ bool MovementAnticheat::CheckMultiJump(uint16 opcode) return false; } -#define NO_WALL_CLIMB_CHECK_MOVE_FLAGS (MOVEFLAG_JUMPING | MOVEFLAG_FALLINGFAR | MOVEFLAG_SWIMMING | MOVEFLAG_CAN_FLY | MOVEFLAG_FLYING | MOVEFLAG_PITCH_UP | MOVEFLAG_PITCH_DOWN | MOVEFLAG_ONTRANSPORT) +#define NO_WALL_CLIMB_CHECK_MOVE_FLAGS (MOVEFLAG_JUMPING | MOVEFLAG_FALLINGFAR | MOVEFLAG_SWIMMING | MOVEFLAG_CAN_FLY | MOVEFLAG_FLYING | MOVEFLAG_PITCH_UP | MOVEFLAG_PITCH_DOWN | MOVEFLAG_ONTRANSPORT | MOVEFLAG_SPLINE_ELEVATION) #define NO_WALL_CLIMB_CHECK_UNIT_FLAGS (UNIT_FLAG_UNK_0 | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_CONFUSED | UNIT_FLAG_FLEEING | UNIT_FLAG_POSSESSED) bool MovementAnticheat::CheckWallClimb(MovementInfo const& movementInfo, uint16 opcode) const @@ -996,7 +996,17 @@ bool MovementAnticheat::CheckWallClimb(MovementInfo const& movementInfo, uint16 float const angleRad = atan(deltaZ / deltaXY); //float const angleDeg = angleRad * (360 / (M_PI_F * 2)); - return angleRad > sWorld.getConfig(CONFIG_FLOAT_AC_MOVEMENT_CHEAT_WALL_CLIMB_ANGLE); + if (angleRad > sWorld.getConfig(CONFIG_FLOAT_AC_MOVEMENT_CHEAT_WALL_CLIMB_ANGLE)) + { + // check height with and without vmaps and compare + // if player is stepping over model like stairs, that can increase wall climb angle + float const height1 = me->GetMap()->GetHeight(movementInfo.pos.x, movementInfo.pos.y, movementInfo.pos.z, false); + float const height2 = me->GetMap()->GetHeight(movementInfo.pos.x, movementInfo.pos.y, movementInfo.pos.z, true); + if ((std::abs(height1 - height2) < 0.5f) || (deltaZ > 5.0f)) + return true; + } + + return false; } bool MovementAnticheat::CheckForbiddenArea(MovementInfo const& movementInfo) const @@ -1297,9 +1307,10 @@ bool MovementAnticheat::CheckTeleport(MovementInfo const& movementInfo) const return true; // check moving in given axis without appropriate move flags + // during fall collision with cliffs can change xy so skip that case if (GetLastMovementInfo().ctime && - !GetLastMovementInfo().HasMovementFlag(MOVEFLAG_MASK_XZ) && - !movementInfo.HasMovementFlag(MOVEFLAG_MASK_XZ) && + !GetLastMovementInfo().HasMovementFlag(MOVEFLAG_MASK_XZ | MOVEFLAG_JUMPING | MOVEFLAG_FALLINGFAR) && + !movementInfo.HasMovementFlag(MOVEFLAG_MASK_XZ | MOVEFLAG_JUMPING | MOVEFLAG_FALLINGFAR) && GetLastMovementInfo().HasMovementFlag(MOVEFLAG_ONTRANSPORT) == movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT)) { float const distance2d = movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT) ? @@ -1311,8 +1322,8 @@ bool MovementAnticheat::CheckTeleport(MovementInfo const& movementInfo) const // swimming flag only included in check because of 1.14 // vanilla clients do not have a descend/ascend flag - if (!GetLastMovementInfo().HasMovementFlag(MOVEFLAG_JUMPING | MOVEFLAG_FALLINGFAR | MOVEFLAG_SWIMMING) && - !movementInfo.HasMovementFlag(MOVEFLAG_JUMPING | MOVEFLAG_FALLINGFAR | MOVEFLAG_SWIMMING)) + if (!GetLastMovementInfo().HasMovementFlag(MOVEFLAG_SWIMMING) && + !movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING)) { float const distanceZ = movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT) ? std::abs(GetLastMovementInfo().t_pos.z - movementInfo.t_pos.z) : diff --git a/src/game/Movement/PointMovementGenerator.cpp b/src/game/Movement/PointMovementGenerator.cpp index df0559a368c..86e11d3aff4 100644 --- a/src/game/Movement/PointMovementGenerator.cpp +++ b/src/game/Movement/PointMovementGenerator.cpp @@ -236,7 +236,7 @@ void ChargeMovementGenerator::Initialize(T& unit) return; unit.AddUnitState(UNIT_STAT_ROAMING | UNIT_STAT_ROAMING_MOVE); - unit.m_movementInfo.moveFlags = unit.m_movementInfo.moveFlags & ~MOVEFLAG_MASK_MOVING_OR_TURN; + unit.m_movementInfo.RemoveMovementFlag(MOVEFLAG_MASK_MOVING_OR_TURN); unit.m_movementInfo.ctime = 0; Movement::MoveSplineInit init(unit, "ChargeMovementGenerator::Initialize"); diff --git a/src/game/Movement/spline/MoveSplineInit.cpp b/src/game/Movement/spline/MoveSplineInit.cpp index 02401bb8a9d..0f5c9a986e8 100644 --- a/src/game/Movement/spline/MoveSplineInit.cpp +++ b/src/game/Movement/spline/MoveSplineInit.cpp @@ -133,6 +133,7 @@ int32 MoveSplineInit::Launch() if (unit.IsPlayer() || unit.GetPossessorGuid().IsPlayer()) unit.SetSplineDonePending(true); + unit.m_movementInfo.ctime = 0; unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags); move_spline.SetMovementOrigin(movementType); move_spline.Initialize(args); diff --git a/src/game/Objects/Player.cpp b/src/game/Objects/Player.cpp index 6af9867f846..b8dd906f53b 100644 --- a/src/game/Objects/Player.cpp +++ b/src/game/Objects/Player.cpp @@ -2297,6 +2297,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati DuelComplete(DUEL_FLED); // reset movement flags at teleport, because player will continue move with these flags after teleport + m_movementInfo.ctime = 0; m_movementInfo.RemoveMovementFlag(MOVEFLAG_MASK_MOVING_OR_TURN); if (!(options & TELE_TO_NOT_LEAVE_TRANSPORT) || !m_transport) m_movementInfo.RemoveMovementFlag(MOVEFLAG_ONTRANSPORT); @@ -2366,7 +2367,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati m_teleportRecover = wps; wps(); } - m_movementInfo.moveFlags &= ~MOVEFLAG_MASK_MOVING_OR_TURN; // For extrapolation } else { @@ -4994,7 +4994,7 @@ void Player::SetFly(bool enable) pTransport->RemovePassenger(this); StopMoving(true); } - + m_movementInfo.moveFlags = (MOVEFLAG_LEVITATING | MOVEFLAG_SWIMMING | MOVEFLAG_CAN_FLY | MOVEFLAG_FLYING); AddUnitState(UNIT_STAT_FLYING_ALLOWED); } diff --git a/src/game/Objects/Unit.cpp b/src/game/Objects/Unit.cpp index 651f5ff70c2..c02fc5a17f8 100644 --- a/src/game/Objects/Unit.cpp +++ b/src/game/Objects/Unit.cpp @@ -9057,7 +9057,8 @@ void Unit::ModConfuseSpell(bool apply, ObjectGuid casterGuid, uint32 spellId, Mo else RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING); - m_movementInfo.moveFlags &= ~MOVEFLAG_MASK_MOVING_OR_TURN; + m_movementInfo.ctime = 0; + m_movementInfo.RemoveMovementFlag(MOVEFLAG_MASK_MOVING_OR_TURN); if (apply) { @@ -9139,6 +9140,7 @@ void Unit::SetFeignDeath(bool apply, ObjectGuid casterGuid, bool success) { if (apply) { + m_movementInfo.ctime = 0; m_movementInfo.RemoveMovementFlag(MOVEFLAG_MASK_MOVING_OR_TURN); if (!IsPlayer()) StopMoving(); @@ -10622,6 +10624,7 @@ void Unit::DisableSpline() if (Player* me = ToPlayer()) me->SetFallInformation(0, me->GetPositionZ()); m_movementInfo.RemoveMovementFlag(MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD); + m_movementInfo.ctime = 0; movespline->_Interrupt(); }