41#include <boost/accumulators/statistics/variance.hpp>
42#include <boost/accumulators/accumulators.hpp>
43#include <boost/accumulators/statistics.hpp>
44#include <boost/circular_buffer.hpp>
51 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
55 TC_LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found \"{}\". " \
56 "MovementFlags: {}, MovementFlags2: {} for player {}. Mask {} will be removed.", \
57 STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUID(), maskToRemove); \
58 mi->RemoveMovementFlag((maskToRemove)); \
62 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
65 mi->RemoveMovementFlag((maskToRemove)); \
137 #undef REMOVE_VIOLATING_FLAGS
149 if (!forStatusAck && (!activelyMovedUnit || activelyMovedUnit->
GetGUID() != guid))
151 TC_LOG_DEBUG(
"entities.unit",
"{} Attempted tampering movement data in {}, requesting not allowed mover {} but expected {}",
161 TC_LOG_DEBUG(
"entities.unit",
"{} Sent bad or outdated movement data in {}, requesting not allowed mover {}",
166 if (activelyMovedUnit && activelyMovedUnit->
GetGUID() == guid)
167 return activelyMovedUnit;
180 TC_LOG_WARN(
"misc",
"The computed movement time using clockDelta is erronous. Using fallback instead");
184 return uint32(movementTime);
189 TC_LOG_DEBUG(
"network",
"WORLD: got MSG_MOVE_WORLDPORT_ACK.");
249 TC_LOG_ERROR(
"network",
"WORLD: failed to teleport player {} {} to map {} ({}) because of unknown reason!",
273 bg->AddPlayer(player);
314 if (mapDiff->RaidDuration)
383 if (old_zone != newzone)
447 transport->AddPassenger(plrMover);
453 transport->AddPassenger(plrMover);
599 movementInfo.
guid = guid;
601 recvData >> movementCounter;
603 recvData >> speedReceived;
615 float speedSent = pendingChange.
newValue;
630 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. movementChangeType: {}",
639 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. pendingChange.movementCounter: {}, movementCounter: {}",
646 if (std::fabs(speedSent - speedReceived) > 0.01f)
648 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. speedSent - speedReceived: {}",
655 if (moveTypeSent != move_type)
657 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. moveTypeSent: {}, move_type: {}",
679 TC_LOG_DEBUG(
"network",
"WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
703 TC_LOG_DEBUG(
"network",
"WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
756 movementInfo.
guid = guid;
767 data << movementInfo.jump.sinAngle;
768 data << movementInfo.jump.cosAngle;
769 data << movementInfo.jump.xyspeed;
770 data << movementInfo.jump.zspeed;
792 movementInfo.
guid = guid;
815 movementInfo.
guid = guid;
838 movementInfo.
guid = guid;
844 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
859 movementInfo.
guid = guid;
867 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_FORCE_UNROOT_ACK");
882 movementInfo.
guid = guid;
888 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
903 movementInfo.
guid = guid;
911 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK");
926 movementInfo.
guid = guid;
934 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_GRAVITY_DISABLE_ACK");
949 movementInfo.
guid = guid;
955 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_GRAVITY_ENABLE_ACK");
970 movementInfo.
guid = guid;
976 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_SET_COLLISION_HGT_ACK");
992 movementInfo.
guid = guid;
995 recvData >> newValue;
1005 recvData >> summonerGuid;
1013 TC_LOG_DEBUG(
"network",
"WORLD: Received CMSG_MOVE_TIME_SKIPPED");
1018 recvData >> timeSkipped;
1031 data << timeSkipped;
1048 uint32 lagDelay = roundTripDuration / 2;
1070 using namespace boost::accumulators;
1072 accumulator_set<
uint32, features<tag::mean, tag::median, tag::variance(lazy)> > latencyAccumulator;
1075 latencyAccumulator(roundTripDuration);
1077 uint32 latencyMedian =
static_cast<uint32>(std::round(median(latencyAccumulator)));
1078 uint32 latencyStandardDeviation =
static_cast<uint32>(std::round(sqrt(variance(latencyAccumulator))));
1080 accumulator_set<int64, features<tag::mean> > clockDeltasAfterFiltering;
1081 uint32 sampleSizeAfterFiltering = 0;
1084 if (roundTripDuration < latencyStandardDeviation + latencyMedian) {
1085 clockDeltasAfterFiltering(clockDelta);
1086 sampleSizeAfterFiltering++;
1090 if (sampleSizeAfterFiltering != 0)
1092 int64 meanClockDelta =
static_cast<int64>(std::round(mean(clockDeltasAfterFiltering)));
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
MapDifficultyEntry const * GetMapDifficultyData(uint32 mapId, Difficulty difficulty)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
#define TC_LOG_WARN(filterType__,...)
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove)
@ TELE_REVIVE_AT_TELEPORT
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
@ GAMEOBJECT_TYPE_TRANSPORT
@ SPELL_AURA_FEATHER_FALL
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
@ AURA_INTERRUPT_FLAG_TURNING
@ AURA_INTERRUPT_FLAG_LANDING
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
@ MOVEMENTFLAG_DESCENDING
@ MOVEMENTFLAG_PITCH_DOWN
@ MOVEMENTFLAG_SPLINE_ENABLED
@ MOVEMENTFLAG_STRAFE_LEFT
@ MOVEMENTFLAG_ONTRANSPORT
@ MOVEMENTFLAG_WATERWALKING
@ MOVEMENTFLAG_MASK_MOVING
@ MOVEMENTFLAG_DISABLE_GRAVITY
@ MOVEMENTFLAG_FALLING_SLOW
@ MOVEMENTFLAG_MASK_TURNING
@ MOVEMENTFLAG_STRAFE_RIGHT
float baseMoveSpeed[MAX_MOVE_TYPE]
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
@ SPEED_CHANGE_FLIGHT_SPEED
@ SPEED_CHANGE_FLIGHT_BACK_SPEED
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
@ VEHICLE_FLAG_FIXED_POSITION
virtual bool HandlePlayerUnderMap(Player *)
void SetActivelyMovedUnit(Unit *activelyMovedUnit)
Unit * GetActivelyMovedUnit() const
Player * GetBasePlayer() const
bool IsAllowedToMove(Unit *unit) const
GameobjectTypes GetGoType() const
static bool IsValidMapCoord(uint32 mapid, float x, float y)
virtual void RemovePlayerFromMap(Player *, bool)
float GetMinHeight(float x, float y) const
GameObject * GetGameObject(ObjectGuid const &guid)
virtual EnterState CannotEnter(Player *)
Difficulty GetDifficultyID() const
char const * GetMapName() const
virtual bool AddPlayerToMap(Player *)
Transport * GetTransport(ObjectGuid const &guid)
MovementGenerator * GetCurrentMovementGenerator() const
virtual bool Initialize(Unit *)=0
static void SendSpeedChangeToObservers(Unit *unit, UnitMoveType mtype, float newRate)
PackedGuidWriter WriteAsPacked() const
std::string ToString() const
PackedGuidReader ReadAsPacked()
void SetFlag(uint16 index, uint32 newFlag)
void RemoveFlag(uint16 index, uint32 oldFlag)
bool HasFlag(uint16 index, uint32 flag) const
static ObjectGuid GetGUID(Object const *o)
ObjectGuid GetGUID() const
static Player * ToPlayer(Object *o)
void SetSemaphoreTeleportNear(bool semphsetting)
void SendInitialPacketsAfterAddToMap()
WorldLocation const & GetCorpseLocation() const
WorldLocation & GetTeleportDest()
void SetBGTeam(uint32 team)
bool IsBeingTeleportedFar() const
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
void CheckOutdoorsAuraRequirements()
bool InBattleground() const
void SpawnCorpseBones(bool triggerSave=true)
void UpdateZone(uint32 newZone, uint32 newArea)
void SetFallInformation(uint32 time, float z)
void SendInitialPacketsBeforeAddToMap()
WorldSession * GetSession() const
bool IsInvitedForBattlegroundInstance(uint32 instanceId) const
void UpdateFallInformationIfNeed(MovementInfo const &minfo, uint16 opcode)
void SetSemaphoreTeleportFar(bool semphsetting)
Battleground * GetBattleground() const
void ProcessDelayedOperations()
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport=false) override
uint32 GetTeleportOptions() const
void SummonIfPossible(bool agree)
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
bool IsBeingTeleportedNear() const
bool CheckInstanceValidity(bool)
void SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) const
uint32 GetBattlegroundId() const
void SetMap(Map *map) override
std::string GetDebugInfo() const override
void SendMessageToSet(WorldPacket const *data, bool self) const override
void ResummonPetTemporaryUnSummonedIfAny()
void SetBattlegroundId(uint32 val, BattlegroundTypeId bgTypeId)
void UpdatePvP(bool state, bool override=false)
bool IsBeingTeleported() const
void ResurrectPlayer(float restore_percent, bool applySickness=false)
void RemovePassenger(WorldObject *passenger)
Vehicle * GetVehicle() const
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Movement::MoveSpline * movespline
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0)
Emote GetEmoteState() const
PlayerMovementPendingChange PopPendingMovementChange()
MotionMaster * GetMotionMaster()
PlayerMovementPendingChange & PeakFirstPendingMovementChange()
void SetSpeedRateReal(UnitMoveType mtype, float rate)
void SetEmoteState(Emote emote)
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
float GetHoverOffset() const
bool HasAuraType(AuraType auraType) const
void SetStandState(UnitStandStateType state)
bool IsControlledByPlayer() const
bool HasPendingMovementChange() const
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
std::string const & GetName() const
Transport * GetTransport() const
MovementInfo m_movementInfo
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
OpcodeClient GetOpcode() const
TimePoint GetReceivedTime() const
WorldPacket const * Write() override
void HandleMountSpecialAnimOpcode(WorldPacket &recvdata)
void LogoutPlayer(bool save)
Log the player out
void HandleMovementOpcode(OpcodeClient opcode, MovementInfo &movementInfo)
void HandleMoveWorldportAck()
void HandleMoveHoverAck(WorldPacket &recvData)
static void WriteMovementInfo(WorldPacket *data, MovementInfo *mi)
void HandleMoveRootAck(WorldPacket &recvPacket)
AccountTypes GetSecurity() const
int64 _timeSyncClockDelta
std::map< uint32, uint32 > _pendingTimeSyncRequests
uint32 AdjustClientMovementTime(uint32 time) const
void HandleSummonResponseOpcode(WorldPacket &recvData)
void HandleMoveTimeSkippedOpcode(WorldPacket &recvData)
void HandleMoveSetCollisionHgtAck(WorldPacket &recvData)
void HandleMoveGravityEnableAck(WorldPacket &recvData)
std::string GetPlayerInfo() const
void KickPlayer(std::string const &reason)
Kick a player out of the World.
void HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortResponse &packet)
Player * GetPlayer() const
void HandleMoveGravityDisableAck(WorldPacket &recvData)
bool ValidateMovementInfo(Unit const *mover, MovementInfo *mi) const
void HandleMoveSetCanTransitionBetweenSwinAndFlyAck(WorldPacket &recvData)
void HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMovement &packet)
void ComputeNewClockDelta()
void HandleForceSpeedChangeAck(WorldPacket &recvData)
void HandleMoveWaterWalkAck(WorldPacket &recvPacket)
void HandleMoveUnRootAck(WorldPacket &recvPacket)
uint32 GetAccountId() const
void ReadMovementInfo(WorldPacket &data, MovementInfo *mi)
Unit * ValidateAndGetUnitBeingMoved(ObjectGuid guid, OpcodeClient opcode, bool forStatusAck) const
void HandleMoveSetCanFlyAckOpcode(WorldPacket &recvData)
std::unique_ptr< boost::circular_buffer< std::pair< int64, uint32 > > > _timeSyncClockDeltaQueue
void HandleMoveNotActiveMover(WorldPacket &recvData)
GameClient * GetGameClient() const
void HandleTimeSyncResponse(WorldPackets::Misc::TimeSyncResponse &packet)
void HandleSetActiveMoverOpcode(WorldPacket &recvData)
void HandleMoveKnockBackAck(WorldPacket &recvPacket)
void HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck &packet)
void HandleFeatherFallAck(WorldPacket &recvData)
std::string GetOpcodeNameForLogging(Opcodes opcode)
Lookup opcode name for human understandable logging.
@ CMSG_FORCE_PITCH_RATE_CHANGE_ACK
@ CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK
@ CMSG_FORCE_TURN_RATE_CHANGE_ACK
@ CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
@ CMSG_FORCE_SWIM_SPEED_CHANGE_ACK
@ CMSG_FORCE_RUN_SPEED_CHANGE_ACK
@ CMSG_FORCE_WALK_SPEED_CHANGE_ACK
@ CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK
@ CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
@ CONFIG_PENDING_MOVE_CHANGES_TIMEOUT
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
bool IsValidMapCoord(float c)
bool IsBattlegroundOrArena() const
void RemoveMovementFlag(uint32 flag)
struct MovementInfo::TransportInfo transport
bool HasMovementFlag(uint32 flag) const
MovementChangeType movementChangeType
float GetExactDist2d(const float x, const float y) const
float GetPositionZ() const
float GetOrientation() const
bool IsPositionValid() const
void SetOrientation(float orientation)
float GetPositionX() const
float GetPositionY() const
void Relocate(float x, float y)