void HandleMoveSetModMovementForceMagnitudeAck(MovementSpeedAck setModMovementForceMagnitudeAck) { Unit mover = _player.m_unitMovedByMe; Cypher.Assert(mover != null); // there must always be a mover _player.ValidateMovementInfo(setModMovementForceMagnitudeAck.Ack.Status); // prevent tampered movement data if (setModMovementForceMagnitudeAck.Ack.Status.Guid != mover.GetGUID()) { Log.outError(LogFilter.Network, $"HandleSetModMovementForceMagnitudeAck: guid error, expected {mover.GetGUID()}, got {setModMovementForceMagnitudeAck.Ack.Status.Guid}"); return; } // skip all except last if (_player.m_movementForceModMagnitudeChanges > 0) { --_player.m_movementForceModMagnitudeChanges; if (_player.m_movementForceModMagnitudeChanges == 0) { float expectedModMagnitude = 1.0f; MovementForces movementForces = mover.GetMovementForces(); if (movementForces != null) { expectedModMagnitude = movementForces.GetModMagnitude(); } if (Math.Abs(expectedModMagnitude - setModMovementForceMagnitudeAck.Speed) > 0.01f) { Log.outDebug(LogFilter.Misc, $"Player {_player.GetName()} from account id {_player.GetSession().GetAccountId()} kicked for incorrect movement force magnitude (must be {expectedModMagnitude} instead {setModMovementForceMagnitudeAck.Speed})"); _player.GetSession().KickPlayer(); return; } } } setModMovementForceMagnitudeAck.Ack.Status.Time += m_clientTimeDelay; MoveUpdateSpeed updateModMovementForceMagnitude = new MoveUpdateSpeed(ServerOpcodes.MoveUpdateModMovementForceMagnitude); updateModMovementForceMagnitude.Status = setModMovementForceMagnitudeAck.Ack.Status; updateModMovementForceMagnitude.Speed = setModMovementForceMagnitudeAck.Speed; mover.SendMessageToSet(updateModMovementForceMagnitude, false); }
void HandleForceSpeedChangeAck(MovementSpeedAck packet) { GetPlayer().ValidateMovementInfo(packet.Ack.Status); // now can skip not our packet if (GetPlayer().GetGUID() != packet.Ack.Status.Guid) { return; } /*----------------*/ // client ACK send one packet for mounted/run case and need skip all except last from its // in other cases anti-cheat check can be fail in false case UnitMoveType move_type; ClientOpcodes opcode = packet.GetOpcode(); switch (opcode) { case ClientOpcodes.MoveForceWalkSpeedChangeAck: move_type = UnitMoveType.Walk; break; case ClientOpcodes.MoveForceRunSpeedChangeAck: move_type = UnitMoveType.Run; break; case ClientOpcodes.MoveForceRunBackSpeedChangeAck: move_type = UnitMoveType.RunBack; break; case ClientOpcodes.MoveForceSwimSpeedChangeAck: move_type = UnitMoveType.Swim; break; case ClientOpcodes.MoveForceSwimBackSpeedChangeAck: move_type = UnitMoveType.SwimBack; break; case ClientOpcodes.MoveForceTurnRateChangeAck: move_type = UnitMoveType.TurnRate; break; case ClientOpcodes.MoveForceFlightSpeedChangeAck: move_type = UnitMoveType.Flight; break; case ClientOpcodes.MoveForceFlightBackSpeedChangeAck: move_type = UnitMoveType.FlightBack; break; case ClientOpcodes.MoveForcePitchRateChangeAck: move_type = UnitMoveType.PitchRate; break; default: Log.outError(LogFilter.Network, "WorldSession.HandleForceSpeedChangeAck: Unknown move type opcode: {0}", opcode); return; } // skip all forced speed changes except last and unexpected // in run/mounted case used one ACK and it must be skipped. m_forced_speed_changes[MOVE_RUN] store both. if (GetPlayer().m_forced_speed_changes[(int)move_type] > 0) { --GetPlayer().m_forced_speed_changes[(int)move_type]; if (GetPlayer().m_forced_speed_changes[(int)move_type] > 0) { return; } } if (!GetPlayer().GetTransport() && Math.Abs(GetPlayer().GetSpeed(move_type) - packet.Speed) > 0.01f) { if (GetPlayer().GetSpeed(move_type) > packet.Speed) // must be greater - just correct { Log.outError(LogFilter.Network, "{0}SpeedChange player {1} is NOT correct (must be {2} instead {3}), force set to correct value", move_type, GetPlayer().GetName(), GetPlayer().GetSpeed(move_type), packet.Speed); GetPlayer().SetSpeedRate(move_type, GetPlayer().GetSpeedRate(move_type)); } else // must be lesser - cheating { Log.outDebug(LogFilter.Server, "Player {0} from account id {1} kicked for incorrect speed (must be {2} instead {3})", GetPlayer().GetName(), GetPlayer().GetSession().GetAccountId(), GetPlayer().GetSpeed(move_type), packet.Speed); GetPlayer().GetSession().KickPlayer(); } } }