42#include <boost/accumulators/framework/accumulator_set.hpp>
43#include <boost/accumulators/framework/features.hpp>
44#include <boost/accumulators/statistics/mean.hpp>
45#include <boost/accumulators/statistics/median.hpp>
46#include <boost/accumulators/statistics/variance.hpp>
47#include <boost/circular_buffer.hpp>
54 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
58 TC_LOG_DEBUG("entities.unit", "Player::ValidateMovementInfo: Violation of MovementFlags found ({}). " \
59 "MovementFlags: {} for player {}. Mask {} will be removed.", \
60 STRINGIZE(check), mi->GetMovementFlags(), GetPlayer()->GetGUID(), maskToRemove); \
61 mi->RemoveMovementFlag((maskToRemove)); \
65 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
68 mi->RemoveMovementFlag((maskToRemove)); \
143 #undef REMOVE_VIOLATING_FLAGS
153 if (!forStatusAck && (!activelyMovedUnit || activelyMovedUnit->
GetGUID() != guid))
155 TC_LOG_DEBUG(
"entities.unit",
"{} Attempted tampering movement data in {}, requesting not allowed mover {} but expected {}",
160 if (activelyMovedUnit && activelyMovedUnit->
GetGUID() == guid)
161 return activelyMovedUnit;
174 TC_LOG_WARN(
"misc",
"The computed movement time using clockDelta is erronous. Using fallback instead");
178 return uint32(movementTime);
219 transport->RemovePassenger(player);
247 resumeToken.
Reason = seamlessTeleport ? 2 : 1;
250 if (!seamlessTeleport)
259 newTransport->AddPassenger(player, loc.
Location);
265 transport->RemovePassenger(player);
269 TC_LOG_ERROR(
"network",
"WORLD: failed to teleport player {} {} to map {} ({}) because of unknown reason!",
297 if (!seamlessTeleport)
303 garrison->SendRemoteInfo();
311 if (!seamlessTeleport)
341 if (entries.MapDifficulty->HasResetSchedule())
345 raidInstanceMessage.
MapID = mEntry->
ID;
349 raidInstanceMessage.
Locked = !playerLock->IsExpired();
350 raidInstanceMessage.
Extended = playerLock->IsExtended();
354 raidInstanceMessage.
Locked =
false;
355 raidInstanceMessage.
Extended =
false;
439 transport->AddPassenger(plMover, destLocation);
453 if (old_zone != newzone)
484 TC_LOG_TRACE(
"opcodes.movement",
"HandleMovementOpcode Name {}: opcode {} {} Flags {} Pos {}",
486 movementInfo.
flags, movementInfo.
pos);
522 transport->AddPassenger(plrMover, movementInfo.
transport.
pos);
687 TC_LOG_ERROR(
"network",
"WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: {}", opcode);
704 TC_LOG_ERROR(
"network",
"{}SpeedChange player {} is NOT correct (must be {} instead {}), force set to correct value",
710 TC_LOG_DEBUG(
"misc",
"Player {} from account id {} kicked for incorrect speed (must be {} instead {})",
797 updateApplyMovementForce.
Status = &moveApplyMovementForceAck.
Ack.
Status;
798 updateApplyMovementForce.
Force = &moveApplyMovementForceAck.
Force;
814 updateRemoveMovementForce.
Status = &moveRemoveMovementForceAck.
Ack.
Status;
815 updateRemoveMovementForce.
TriggerGUID = moveRemoveMovementForceAck.
ID;
834 float expectedModMagnitude = 1.0f;
836 expectedModMagnitude = movementForces->GetModMagnitude();
838 if (std::fabs(expectedModMagnitude - setModMovementForceMagnitudeAck.
Speed) > 0.01f)
840 TC_LOG_DEBUG(
"misc",
"Player {} from account id {} kicked for incorrect movement force magnitude (must be {} instead {})",
851 updateModMovementForceMagnitude.
Status = &setModMovementForceMagnitudeAck.
Ack.
Status;
852 updateModMovementForceMagnitude.
Speed = setModMovementForceMagnitudeAck.
Speed;
939 TaxiPathNodeEntry const* currentNode = flight->GetPath()[flight->GetCurrentNode()];
946 flight->SetCurrentNodeAfterTeleport();
948 flight->SkipCurrentNode();
959 if (
GetPlayer()->m_taxi.GetPath().size() != 1)
985 if (!serverTimeAtSent)
993 int64 lagDelay = roundTripDuration / 2;
1005 int64 clockDelta = serverTimeAtSent.mapped() + lagDelay - clientTime;
1032 using namespace boost::accumulators;
1034 accumulator_set<
uint32, features<tag::mean, tag::median, tag::variance(lazy)> > latencyAccumulator;
1037 latencyAccumulator(roundTripDuration);
1039 uint32 latencyMedian =
static_cast<uint32>(std::round(median(latencyAccumulator)));
1040 uint32 latencyStandardDeviation =
static_cast<uint32>(std::round(sqrt(variance(latencyAccumulator))));
1042 accumulator_set<int64, features<tag::mean> > clockDeltasAfterFiltering;
1043 uint32 sampleSizeAfterFiltering = 0;
1046 if (roundTripDuration < latencyStandardDeviation + latencyMedian) {
1047 clockDeltasAfterFiltering(clockDelta);
1048 sampleSizeAfterFiltering++;
1052 if (sampleSizeAfterFiltering != 0)
1054 int64 meanClockDelta =
static_cast<int64>(std::round(mean(clockDeltasAfterFiltering)));
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< TaxiNodesEntry > sTaxiNodesStore("TaxiNodes.db2", &TaxiNodesLoadInfo::Instance)
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
@ TAXI_PATH_NODE_FLAG_TELEPORT
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
#define TC_LOG_DEBUG(filterType__, message__,...)
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_WARN(filterType__, message__,...)
#define TC_LOG_TRACE(filterType__, message__,...)
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove)
@ MOVEMENTFLAG_DESCENDING
@ MOVEMENTFLAG_PITCH_DOWN
@ MOVEMENTFLAG_STRAFE_LEFT
@ MOVEMENTFLAG_WATERWALKING
@ MOVEMENTFLAG_MASK_MOVING
@ MOVEMENTFLAG_DISABLE_GRAVITY
@ MOVEMENTFLAG_FALLING_SLOW
@ MOVEMENTFLAG_MASK_TURNING
@ MOVEMENTFLAG_STRAFE_RIGHT
@ MOVEMENTFLAG_SPLINE_ELEVATION
@ SMSG_MOVE_UPDATE_MOD_MOVEMENT_FORCE_MAGNITUDE
constexpr FormattedOpcodeName< OpcodeClient > GetOpcodeNameForLogging(OpcodeClient opcode)
Lookup opcode name for human understandable logging.
@ CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK
@ CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK
@ CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK
@ CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK
@ CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK
@ CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK
@ CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
@ CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK
@ CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
@ TELE_REVIVE_AT_TELEPORT
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
@ PLAYER_LOCAL_FLAG_OVERRIDE_TRANSPORT_SERVER_TIME
@ WaitingForSuspendTokenResponse
constexpr BattlegroundQueueTypeId BATTLEGROUND_QUEUE_NONE
@ SPELL_AURA_FEATHER_FALL
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
@ PROC_SPELL_TYPE_MASK_ALL
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
@ VEHICLE_FLAG_FIXED_POSITION
ObjectGuid const & GetGUID() const
virtual bool HandlePlayerUnderMap(Player *)
static bool IsValidMapCoord(uint32 mapid, float x, float y)
virtual void RemovePlayerFromMap(Player *, bool)
virtual bool AddPlayerToMap(Player *player, bool initPlayer=true)
virtual TransferAbortParams CannotEnter(Player *)
float GetMinHeight(PhaseShift const &phaseShift, float x, float y)
GameObject * GetGameObject(ObjectGuid const &guid)
Difficulty GetDifficultyID() const
char const * GetMapName() const
Transport * GetTransport(ObjectGuid const &guid)
MovementGenerator * GetCurrentMovementGenerator() const
virtual bool Initialize(Unit *owner)=0
std::string ToString() const
uint32 GetTaxiDestination() const
void SendInitialPacketsAfterAddToMap()
WorldLocation const & GetCorpseLocation() const
void UpdateFallInformationIfNeed(MovementInfo const &minfo, uint32 opcode)
void SetPlayerFlag(PlayerFlags flags)
void SetBGTeam(Team team)
void SetPlayerLocalFlag(PlayerLocalFlags flags)
void RemovePlayerFlag(PlayerFlags flags)
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
void SetBattlegroundId(uint32 val, BattlegroundTypeId bgTypeId, BattlegroundQueueTypeId queueId)
uint8 m_movementForceModMagnitudeChanges
bool InBattleground() const
void SpawnCorpseBones(bool triggerSave=true)
void UpdateZone(uint32 newZone, uint32 newArea)
void SetFallInformation(uint32 time, float z)
void SendInitialPacketsBeforeAddToMap()
int32 GetNewWorldCounter() const
WorldSession * GetSession() const
bool IsInvitedForBattlegroundInstance(uint32 instanceId) const
void UnsummonPetTemporaryIfAny()
TeleportState GetTeleportState() const
TeleportLocation m_teleport_dest
void UpdateVisibilityForPlayer()
void ResummonBattlePetTemporaryUnSummonedIfAny()
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={}, uint32 teleportSpellId=0)
Battleground * GetBattleground() const
void ProcessDelayedOperations()
void UpdateIndoorsOutdoorsAuras()
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport=false) override
void SummonIfPossible(bool agree)
std::array< uint8, MAX_MOVE_TYPE > m_forced_speed_changes
void SetTransportServerTime(int32 transportServerTime)
bool CheckInstanceValidity(bool)
Garrison * GetGarrison() const
void UnsummonBattlePetTemporaryIfAny(bool onFlyingMount=false)
uint32 GetBattlegroundId() const
bool HasPlayerFlag(PlayerFlags flags) const
TeleportLocation & GetTeleportDest()
void UpdateObjectVisibility(bool forced=true) override
void SetMap(Map *map) override
std::string GetDebugInfo() const override
void ResummonPetTemporaryUnSummonedIfAny()
void SetTeleportState(TeleportState state)
void UpdatePvP(bool state, bool override=false)
void CleanupAfterTaxiFlight()
void UpdateTavernRestingState()
void UpdateZoneAndAreaId()
bool IsBeingTeleported() const
EnumFlag< TeleportToOptions > GetTeleportOptions() const
void ResurrectPlayer(float restore_percent, bool applySickness=false)
virtual ObjectGuid GetTransportGUID() const =0
virtual void AddPassenger(WorldObject *passenger, Position const &offset)=0
virtual TransportBase * RemovePassenger(WorldObject *passenger)=0
Vehicle * GetVehicle() const
float GetSpeed(UnitMoveType mtype) const
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Emote GetEmoteState() const
MotionMaster * GetMotionMaster()
MovementForces const * GetMovementForces() const
uint32 m_movementCounter
Incrementing counter used in movement packets.
void SetEmoteState(Emote emote)
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Unit * GetUnitBeingMoved() const
float GetHoverOffset() const
bool HasAuraType(AuraType auraType) const
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
float GetSpeedRate(UnitMoveType mtype) const
void SetSpeedRate(UnitMoveType mtype, float rate)
std::unique_ptr< Movement::MoveSpline > movespline
static void ProcSkillsAndAuras(Unit *actor, Unit *actionTarget, ProcFlagsInit const &typeMaskActor, ProcFlagsInit const &typeMaskActionTarget, ProcFlagsSpellType spellTypeMask, ProcFlagsSpellPhase spellPhaseMask, ProcFlagsHit hitMask, Spell *spell, DamageInfo *damageInfo, HealInfo *healInfo)
constexpr uint32 GetMapId() const
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
PhaseShift & GetPhaseShift()
TransportBase * GetTransport() const
std::string const & GetName() const
void UpdatePositionData()
MovementInfo m_movementInfo
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
TimePoint GetReceivedTime() const
OpcodeClient GetOpcode() const
WorldPacket const * Write() override
WorldPacket const * Write() override
TimePoint GetReceivedTime() const
Duration< Milliseconds, uint32 > LifetimeMs
WorldPacket const * Write() override
WorldPacket const * Write() override
Duration< Milliseconds, uint32 > LifetimeMs
MovementForce const * Force
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * GetRawPacket() const
void LogoutPlayer(bool save)
Log the player out
void HandleMovementOpcode(OpcodeClient opcode, MovementInfo &movementInfo)
void HandleMoveWorldportAck()
void HandleTimeSyncResponse(WorldPackets::Misc::TimeSyncResponse const &timeSyncResponse)
AccountTypes GetSecurity() const
int64 _timeSyncClockDelta
void HandleSetAdvFlyingSpeedRangeAck(WorldPackets::Movement::MovementSpeedRangeAck &speedRangeAck)
void HandleMoveApplyMovementForceAck(WorldPackets::Movement::MoveApplyMovementForceAck &moveApplyMovementForceAck)
uint32 AdjustClientMovementTime(uint32 time) const
void HandleSetAdvFlyingSpeedAck(WorldPackets::Movement::MovementSpeedAck &speedAck)
std::string GetPlayerInfo() const
void HandleMovementAckMessage(WorldPackets::Movement::MovementAckMessage &movementAck)
void HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortResponse &packet)
static constexpr uint32 SPECIAL_RESUME_COMMS_TIME_SYNC_COUNTER
void HandleTimeSync(uint32 counter, int64 clientTime, TimePoint responseReceiveTime)
static constexpr uint32 SPECIAL_INIT_ACTIVE_MOVER_TIME_SYNC_COUNTER
void HandleMoveSplineDoneOpcode(WorldPackets::Movement::MoveSplineDone &moveSplineDone)
Player * GetPlayer() const
void HandleSetCollisionHeightAck(WorldPackets::Movement::MoveSetCollisionHeightAck &setCollisionHeightAck)
bool ValidateMovementInfo(Unit const *mover, MovementInfo *mi) const
void HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMovement &packet)
void HandleMoveKnockBackAck(WorldPackets::Movement::MoveKnockBackAck &movementAck)
void ComputeNewClockDelta()
void HandleMoveApplyInertiaAck(WorldPackets::Movement::MoveApplyInertiaAck &moveApplyInertiaAck)
void HandleSetActiveMoverOpcode(WorldPackets::Movement::SetActiveMover &packet)
void HandleMoveSetModMovementForceMagnitudeAck(WorldPackets::Movement::MovementSpeedAck &setModMovementForceMagnitudeAck)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetAccountId() const
void HandleMoveTimeSkippedOpcode(WorldPackets::Movement::MoveTimeSkipped &moveTimeSkipped)
void HandleMoveRemoveInertiaAck(WorldPackets::Movement::MoveRemoveInertiaAck &moveRemoveInertiaAck)
void HandleMoveRemoveMovementForceAck(WorldPackets::Movement::MoveRemoveMovementForceAck &moveRemoveMovementForceAck)
void HandleForceSpeedChangeAck(WorldPackets::Movement::MovementSpeedAck &packet)
void HandleMoveForceGravityModifierChangeAck(WorldPackets::Movement::MoveForceGravityModifierChangeAck &moveForceGravityModifierChangeAck)
void HandleQueuedMessagesEnd(WorldPackets::Auth::QueuedMessagesEnd const &queuedMessagesEnd)
void HandleMoveInitActiveMoverComplete(WorldPackets::Movement::MoveInitActiveMoverComplete const &moveInitActiveMoverComplete)
Unit * ValidateAndGetUnitBeingMoved(ObjectGuid guid, OpcodeClient opcode, bool forStatusAck) const
std::unique_ptr< boost::circular_buffer< std::pair< int64, uint32 > > > _timeSyncClockDeltaQueue
void HandleSuspendTokenResponse(WorldPackets::Movement::SuspendTokenResponse &suspendTokenResponse)
void HandleSummonResponseOpcode(WorldPackets::Movement::SummonResponse &packet)
void KickPlayer(std::string_view reason)
Kick a player out of the World.
void HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck &packet)
std::map< uint32, int64 > _pendingTimeSyncRequests
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
bool IsValidMapCoord(float c)
BattlegroundQueueTypeId queueId
bool IsBattlegroundOrArena() const
bool HasMovementFlag(MovementFlags flag) const
void AddMovementFlag(MovementFlags flag)
float stepUpStartElevation
struct MovementInfo::TransportInfo transport
constexpr void SetOrientation(float orientation)
constexpr float GetPositionX() const
constexpr float GetPositionY() const
float GetExactDist2d(const float x, const float y) const
bool IsPositionValid() const
constexpr void Relocate(float x, float y)
constexpr float GetOrientation() const
constexpr float GetPositionZ() const
Optional< uint32 > InstanceId
Optional< uint32 > LfgDungeonsId
Optional< ObjectGuid > TransportGuid
TaggedPosition< Position::XYZO > Pos