40#include <boost/accumulators/statistics/variance.hpp>
41#include <boost/accumulators/accumulators.hpp>
42#include <boost/accumulators/statistics.hpp>
43#include <boost/circular_buffer.hpp>
50 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
54 TC_LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found \"{}\". " \
55 "MovementFlags: {}, MovementFlags2: {} for player {}. Mask {} will be removed.", \
56 STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUID(), maskToRemove); \
57 mi->RemoveMovementFlag((maskToRemove)); \
61 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
64 mi->RemoveMovementFlag((maskToRemove)); \
136 #undef REMOVE_VIOLATING_FLAGS
148 if (!forStatusAck && (!activelyMovedUnit || activelyMovedUnit->
GetGUID() != guid))
163 if (activelyMovedUnit && activelyMovedUnit->
GetGUID() == guid)
164 return activelyMovedUnit;
177 TC_LOG_WARN(
"misc",
"The computed movement time using clockDelta is erronous. Using fallback instead");
181 return uint32(movementTime);
186 TC_LOG_DEBUG(
"network",
"WORLD: got MSG_MOVE_WORLDPORT_ACK.");
246 TC_LOG_ERROR(
"network",
"WORLD: failed to teleport player {} {} to map {} ({}) because of unknown reason!",
270 bg->AddPlayer(player);
311 if (mapDiff->resetTime)
367 uint32 sequenceIndex, time;
368 recvPacket >> sequenceIndex >> time;
389 if (old_zone != newzone)
453 transport->AddPassenger(plrMover);
459 transport->AddPassenger(plrMover);
605 movementInfo.
guid = guid;
607 recvData >> movementCounter;
609 recvData >> speedReceived;
621 float speedSent = pendingChange.
newValue;
636 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. movementChangeType: {}",
645 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. pendingChange.movementCounter: {}, movementCounter: {}",
652 if (std::fabs(speedSent - speedReceived) > 0.01f)
654 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. speedSent - speedReceived: {}",
661 if (moveTypeSent != move_type)
663 TC_LOG_INFO(
"cheat",
"WorldSession::HandleForceSpeedChangeAck: Player {} from account id {} kicked for incorrect data returned in an ack. moveTypeSent: {}, move_type: {}",
685 TC_LOG_DEBUG(
"network",
"WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
709 TC_LOG_DEBUG(
"network",
"WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
762 movementInfo.
guid = guid;
773 data << movementInfo.jump.sinAngle;
774 data << movementInfo.jump.cosAngle;
775 data << movementInfo.jump.xyspeed;
776 data << movementInfo.jump.zspeed;
798 movementInfo.
guid = guid;
821 movementInfo.
guid = guid;
844 movementInfo.
guid = guid;
850 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
865 movementInfo.
guid = guid;
873 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_FORCE_MOVE_UNROOT_ACK");
888 movementInfo.
guid = guid;
894 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_SET_CAN_FLY_ACK");
909 movementInfo.
guid = guid;
917 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK");
932 movementInfo.
guid = guid;
940 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_GRAVITY_DISABLE_ACK");
955 movementInfo.
guid = guid;
961 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_GRAVITY_ENABLE_ACK");
976 movementInfo.
guid = guid;
982 TC_LOG_DEBUG(
"network",
"WORLD: CMSG_MOVE_SET_COLLISION_HGT_ACK");
998 movementInfo.
guid = guid;
1001 recvData >> newValue;
1011 recvData >> summonerGuid;
1019 TC_LOG_DEBUG(
"network",
"WORLD: Received CMSG_MOVE_TIME_SKIPPED");
1024 recvData >> timeSkipped;
1037 data << timeSkipped;
1045 uint32 counter, clientTimestamp;
1046 recvData >> counter >> clientTimestamp;
1059 uint32 lagDelay = roundTripDuration / 2;
1081 using namespace boost::accumulators;
1083 accumulator_set<
uint32, features<tag::mean, tag::median, tag::variance(lazy)> > latencyAccumulator;
1086 latencyAccumulator(roundTripDuration);
1088 uint32 latencyMedian =
static_cast<uint32>(std::round(median(latencyAccumulator)));
1089 uint32 latencyStandardDeviation =
static_cast<uint32>(std::round(sqrt(variance(latencyAccumulator))));
1091 accumulator_set<int64, features<tag::mean> > clockDeltasAfterFiltering;
1092 uint32 sampleSizeAfterFiltering = 0;
1095 if (roundTripDuration < latencyStandardDeviation + latencyMedian) {
1096 clockDeltasAfterFiltering(clockDelta);
1097 sampleSizeAfterFiltering++;
1101 if (sampleSizeAfterFiltering != 0)
1103 int64 meanClockDelta =
static_cast<int64>(std::round(mean(clockDeltasAfterFiltering)));
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
MapDifficulty 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 *)
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)
static Player * ToPlayer(Object *o)
void SetSemaphoreTeleportNear(bool semphsetting)
void SendInitialPacketsAfterAddToMap()
WorldLocation const & GetCorpseLocation() const
WorldLocation & GetTeleportDest()
void SetBGTeam(uint32 team)
void HandleFall(MovementInfo const &movementInfo)
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)
Difficulty GetDifficulty(bool isRaid) const
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
TimePoint GetReceivedTime() const
OpcodeClient GetOpcode() const
WorldPacket const * Write() override
void HandleMountSpecialAnimOpcode(WorldPacket &recvdata)
void LogoutPlayer(bool save)
Log the player out
void HandleMovementOpcode(OpcodeClient opcode, MovementInfo &movementInfo)
void HandleMoveTeleportAck(WorldPacket &recvPacket)
Unit * ValidateAndGetUnitBeingMoved(ObjectGuid guid, bool forStatusAck) const
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)
void KickPlayer(std::string const &reason)
Kick a player out of the World.
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)
void HandleMoveSetCanFlyAckOpcode(WorldPacket &recvData)
std::unique_ptr< boost::circular_buffer< std::pair< int64, uint32 > > > _timeSyncClockDeltaQueue
void HandleMoveNotActiveMover(WorldPacket &recvData)
void HandleMoveWorldportAckOpcode(WorldPacket &recvPacket)
GameClient * GetGameClient() const
void HandleTimeSyncResponse(WorldPacket &recvData)
void HandleSetActiveMoverOpcode(WorldPacket &recvData)
void HandleMoveKnockBackAck(WorldPacket &recvPacket)
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)