TrinityCore
Loading...
Searching...
No Matches
MovementHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "WorldSession.h"
20#include "Battleground.h"
21#include "Corpse.h"
22#include "DB2Stores.h"
24#include "GameTime.h"
25#include "Garrison.h"
26#include "InstanceLockMgr.h"
27#include "InstancePackets.h"
28#include "Log.h"
29#include "Map.h"
30#include "MapManager.h"
31#include "MiscPackets.h"
32#include "MotionMaster.h"
33#include "MoveSpline.h"
34#include "MovementGenerator.h"
35#include "MovementPackets.h"
36#include "ObjectAccessor.h"
37#include "Player.h"
38#include "SpellInfo.h"
39#include "SpellMgr.h"
40#include "Transport.h"
41#include "Vehicle.h"
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>
48
50{
53 #ifdef TRINITY_DEBUG
54 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
55 { \
56 if (check) \
57 { \
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)); \
62 } \
63 } while (0)
64 #else
65 #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) do \
66 { \
67 if (check) \
68 mi->RemoveMovementFlag((maskToRemove)); \
69 } while (0)
70 #endif
71
72 if (!mover)
73 return false;
74
75 if (!mi->pos.IsPositionValid())
76 return false;
77
78 if (!GetPlayer()->GetVehicleBase() || !(GetPlayer()->GetVehicle()->GetVehicleInfo()->Flags & VEHICLE_FLAG_FIXED_POSITION))
80
87
91
95
99
103
107
111
117
121
129 !mover->HasAuraType(SPELL_AURA_FLY) &&
133
136
138
139 // Client first checks if spline elevation != 0, then verifies flag presence
140 if (G3D::fuzzyNe(mi->stepUpStartElevation, 0.0f))
142
143 #undef REMOVE_VIOLATING_FLAGS
144
145 return true;
146}
147
149{
150 // the client is attempting to tamper movement data
151 // edit: this wouldn't happen in retail but it does in TC, even with a legitimate client.
152 Unit* activelyMovedUnit = _player->GetUnitBeingMoved();
153 if (!forStatusAck && (!activelyMovedUnit || activelyMovedUnit->GetGUID() != guid))
154 {
155 TC_LOG_DEBUG("entities.unit", "{} Attempted tampering movement data in {}, requesting not allowed mover {} but expected {}",
156 GetPlayerInfo(), GetOpcodeNameForLogging(opcode), guid, Object::GetGUID(activelyMovedUnit));
157 return nullptr;
158 }
159
160 if (activelyMovedUnit && activelyMovedUnit->GetGUID() == guid)
161 return activelyMovedUnit;
162
163 if (_player->GetGUID() == guid)
164 return _player;
165
166 return ObjectAccessor::GetUnit(*_player, guid);
167}
168
170{
171 int64 movementTime = int64(time) + _timeSyncClockDelta;
172 if (_timeSyncClockDelta == 0 || movementTime < 0 || movementTime > SI64LIT(0xFFFFFFFF))
173 {
174 TC_LOG_WARN("misc", "The computed movement time using clockDelta is erronous. Using fallback instead");
176 }
177 else
178 return uint32(movementTime);
179}
180
188
190{
191 Player* player = GetPlayer();
192 // ignore unexpected far teleports
193 bool seamlessTeleport = player->GetTeleportOptions().HasFlag(TELE_TO_SEAMLESS);
195
196 // get the teleport destination
197 TeleportLocation const& loc = player->GetTeleportDest();
198
199 // possible errors in the coordinate validity check
201 {
202 LogoutPlayer(false);
203 return;
204 }
205
206 // get the destination map entry, not the current one, this will fix homebind and reset greeting
207 MapEntry const* mEntry = sMapStore.LookupEntry(loc.Location.GetMapId());
208
209 // reset instance validity, except if going to an instance inside an instance
210 if (player->m_InstanceValid == false && !mEntry->IsDungeon())
211 player->m_InstanceValid = true;
212
213 Map* oldMap = player->GetMap();
214 Map* newMap = loc.InstanceId ?
215 sMapMgr->FindMap(loc.Location.GetMapId(), *loc.InstanceId) :
216 sMapMgr->CreateMap(loc.Location.GetMapId(), GetPlayer(), loc.LfgDungeonsId);
217
218 if (TransportBase* transport = player->GetTransport())
219 transport->RemovePassenger(player);
220
221 if (player->IsInWorld())
222 {
223 TC_LOG_ERROR("network", "{} {} is still in world when teleported from map {} ({}) to new map {} ({})", player->GetGUID().ToString(), player->GetName(), oldMap->GetMapName(), oldMap->GetId(), newMap ? newMap->GetMapName() : "Unknown", loc.Location.GetMapId());
224 oldMap->RemovePlayerFromMap(player, false);
225 }
226
227 // relocate the player to the teleport destination
228 // the CannotEnter checks are done in TeleporTo but conditions may change
229 // while the player is in transit, for example the map may get full
230 if (!newMap || newMap->CannotEnter(player))
231 {
232 TC_LOG_ERROR("network", "Map {} ({}) could not be created for player {} ({}), porting player to homebind", loc.Location.GetMapId(), newMap ? newMap->GetMapName() : "Unknown", player->GetGUID().ToString(), player->GetName());
233 player->TeleportTo(player->m_homebind);
234 return;
235 }
236
237 float z = loc.Location.GetPositionZ() + player->GetHoverOffset();
239 player->SetFallInformation(0, player->GetPositionZ());
240
241 player->ResetMap();
242 player->SetMap(newMap);
243 player->UpdatePositionData();
244
246 resumeToken.SequenceIndex = player->m_movementCounter;
247 resumeToken.Reason = seamlessTeleport ? 2 : 1;
248 SendPacket(resumeToken.Write());
249
250 if (!seamlessTeleport)
252
253 if (player->m_teleport_dest.TransportGuid)
254 {
255 if (GameObject* go = newMap->GetTransport(*player->m_teleport_dest.TransportGuid))
256 {
257 if (TransportBase* newTransport = go->ToTransportBase())
258 {
259 newTransport->AddPassenger(player, loc.Location);
260 player->Relocate(newTransport->GetPositionWithOffset(loc.Location));
261 }
262 }
263 }
264 else if (TransportBase* transport = player->GetTransport())
265 transport->RemovePassenger(player);
266
267 if (!player->GetMap()->AddPlayerToMap(player, !seamlessTeleport))
268 {
269 TC_LOG_ERROR("network", "WORLD: failed to teleport player {} {} to map {} ({}) because of unknown reason!",
270 player->GetName(), player->GetGUID().ToString(), loc.Location.GetMapId(), newMap ? newMap->GetMapName() : "Unknown");
271 player->ResetMap();
272 player->SetMap(oldMap);
273 player->TeleportTo(player->m_homebind);
274 return;
275 }
276
277 // battleground state prepare (in case join to BG), at relogin/tele player not invited
278 // only add to bg group and object, if the player was invited (else he entered through command)
279 if (player->InBattleground())
280 {
281 // cleanup setting if outdated
282 if (!mEntry->IsBattlegroundOrArena())
283 {
284 // We're not in BG
286 // reset destination bg team
287 player->SetBGTeam(TEAM_OTHER);
288 }
289 // join to bg case
290 else if (Battleground* bg = player->GetBattleground())
291 {
293 bg->AddPlayer(player, player->m_bgData.queueId);
294 }
295 }
296
297 if (!seamlessTeleport)
299 else
300 {
302 if (Garrison* garrison = player->GetGarrison())
303 garrison->SendRemoteInfo();
304 }
305
306 // flight fast teleport case
307 if (player->IsInFlight())
308 {
309 if (!player->InBattleground())
310 {
311 if (!seamlessTeleport)
312 {
313 // short preparations to continue flight
314 MovementGenerator* movementGenerator = player->GetMotionMaster()->GetCurrentMovementGenerator();
315 movementGenerator->Initialize(player);
316 }
317 return;
318 }
319
320 // battleground state prepare, stop flight
321 player->FinishTaxiFlight();
322 }
323
324 if (!player->IsAlive() && player->GetTeleportOptions().HasFlag(TELE_REVIVE_AT_TELEPORT))
325 player->ResurrectPlayer(0.5f);
326
327 // resurrect character at enter into instance where his corpse exist after add to map
328 if (mEntry->IsDungeon() && !player->IsAlive())
329 {
330 if (player->GetCorpseLocation().GetMapId() == mEntry->ID)
331 {
332 player->ResurrectPlayer(0.5f);
333 player->SpawnCorpseBones();
334 }
335 }
336
337 if (mEntry->IsDungeon())
338 {
339 // check if this instance has a reset time and send it to player if so
340 MapDb2Entries entries{ mEntry->ID, newMap->GetDifficultyID() };
341 if (entries.MapDifficulty->HasResetSchedule())
342 {
344 raidInstanceMessage.Type = RAID_INSTANCE_WELCOME;
345 raidInstanceMessage.MapID = mEntry->ID;
346 raidInstanceMessage.DifficultyID = newMap->GetDifficultyID();
347 if (InstanceLock const* playerLock = sInstanceLockMgr.FindActiveInstanceLock(GetPlayer()->GetGUID(), entries))
348 {
349 raidInstanceMessage.Locked = !playerLock->IsExpired();
350 raidInstanceMessage.Extended = playerLock->IsExtended();
351 }
352 else
353 {
354 raidInstanceMessage.Locked = false;
355 raidInstanceMessage.Extended = false;
356 }
357 SendPacket(raidInstanceMessage.Write());
358 }
359
360 // check if instance is valid
361 if (!player->CheckInstanceValidity(false))
362 player->m_InstanceValid = false;
363 }
364
365 // update zone immediately, otherwise leave channel will cause crash in mtmap
366 uint32 newzone, newarea;
367 player->GetZoneAndAreaId(newzone, newarea);
368 player->UpdateZone(newzone, newarea);
369
370 // honorless target
371 if (player->pvpInfo.IsHostile)
372 player->CastSpell(player, 2479, true);
373
374 // in friendly area
375 else if (player->IsPvP() && !player->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
376 player->UpdatePvP(false, false);
377
378 // resummon pet
381
382 //lets process all delayed operations on successful teleport
383 player->ProcessDelayedOperations();
384}
385
387{
389 return;
390
392
393 if (sMapStore.AssertEntry(loc.Location.GetMapId())->IsDungeon())
394 {
396 updateLastInstance.MapID = loc.Location.GetMapId();
397 SendPacket(updateLastInstance.Write());
398 }
399
401 packet.MapID = loc.Location.GetMapId();
402 packet.Loc.Pos = loc.Location;
405 SendPacket(packet.Write());
406
408
411}
412
414{
415 TC_LOG_DEBUG("network", "CMSG_MOVE_TELEPORT_ACK: Guid: {}, Sequence: {}, Time: {}", packet.MoverGUID.ToString(), packet.AckIndex, packet.MoveTime);
416
417 Unit* mover = ValidateAndGetUnitBeingMoved(packet.MoverGUID, packet.GetOpcode(), false);
418 if (!mover)
419 return;
420
421 Player* plMover = mover->ToPlayer();
422
423 if (!plMover || plMover->GetTeleportState() != TeleportState::WaitingForTeleportAck)
424 return;
425
427
428 uint32 old_zone = plMover->GetZoneId();
429
430 TeleportLocation const& dest = plMover->GetTeleportDest();
431 WorldLocation destLocation = dest.Location;
432
433 if (dest.TransportGuid)
434 {
435 if (GameObject* go = plMover->GetMap()->GetGameObject(*dest.TransportGuid))
436 {
437 if (TransportBase* transport = go->ToTransportBase())
438 {
439 transport->AddPassenger(plMover, destLocation);
440 destLocation.Relocate(transport->GetPositionWithOffset(plMover->m_movementInfo.transport.pos));
441 }
442 }
443 }
444
445 plMover->UpdatePosition(destLocation, true);
446 plMover->SetFallInformation(0, GetPlayer()->GetPositionZ());
447
448 uint32 newzone, newarea;
449 plMover->GetZoneAndAreaId(newzone, newarea);
450 plMover->UpdateZone(newzone, newarea);
451
452 // new zone
453 if (old_zone != newzone)
454 {
455 // honorless target
456 if (plMover->pvpInfo.IsHostile)
457 plMover->CastSpell(plMover, 2479, true);
458
459 // in friendly area
460 else if (plMover->IsPvP() && !plMover->HasPlayerFlag(PLAYER_FLAGS_IN_PVP))
461 plMover->UpdatePvP(false, false);
462 }
463
464 // resummon pet
466
467 //lets process all delayed operations on successful teleport
469}
470
475
477{
478 Unit* mover = ValidateAndGetUnitBeingMoved(movementInfo.guid, opcode, false);
479 if (!ValidateMovementInfo(mover, &movementInfo))
480 return;
481
482 Player* plrMover = mover->ToPlayer();
483
484 TC_LOG_TRACE("opcodes.movement", "HandleMovementOpcode Name {}: opcode {} {} Flags {} Pos {}",
485 mover->GetName(), opcode, GetOpcodeNameForLogging(opcode),
486 movementInfo.flags, movementInfo.pos);
487
488 // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
489 if (plrMover && plrMover->IsBeingTeleported())
490 return;
491
492 if (!mover->movespline->Finalized())
493 return;
494
495 // stop some emotes at player move
496 if (plrMover && (plrMover->GetEmoteState() != 0))
498
499 /* handle special cases */
500 if (!movementInfo.transport.guid.IsEmpty())
501 {
502 // We were teleported, skip packets that were broadcast before teleport
503 if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
504 return;
505
506 // transports size limited
507 // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
508 if (fabs(movementInfo.transport.pos.GetPositionX()) > 75.0f || fabs(movementInfo.transport.pos.GetPositionY()) > 75.0f || fabs(movementInfo.transport.pos.GetPositionZ()) > 75.0f)
509 return;
510
511 if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
512 movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
513 return;
514
515 // if we boarded a transport, add us to it
516 if (plrMover)
517 {
518 if (!plrMover->GetTransport())
519 {
520 if (GameObject* go = plrMover->GetMap()->GetGameObject(movementInfo.transport.guid))
521 if (TransportBase* transport = go->ToTransportBase())
522 transport->AddPassenger(plrMover, movementInfo.transport.pos);
523 }
524 else if (plrMover->GetTransport()->GetTransportGUID() != movementInfo.transport.guid)
525 {
526 plrMover->GetTransport()->RemovePassenger(plrMover);
527 if (GameObject* go = plrMover->GetMap()->GetGameObject(movementInfo.transport.guid))
528 {
529 if (TransportBase* transport = go->ToTransportBase())
530 transport->AddPassenger(plrMover, movementInfo.transport.pos);
531 else
532 movementInfo.ResetTransport();
533 }
534 else
535 movementInfo.ResetTransport();
536 }
537 }
538
539 if (!mover->GetTransport() && !mover->GetVehicle())
540 movementInfo.transport.Reset();
541 }
542 else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
543 plrMover->GetTransport()->RemovePassenger(plrMover);
544
545 /* process position-change */
546 movementInfo.guid = mover->GetGUID();
547 movementInfo.time = AdjustClientMovementTime(movementInfo.time);
548 mover->m_movementInfo = movementInfo;
549
550 // Some vehicles allow the passenger to turn by himself
551 if (Vehicle* vehicle = mover->GetVehicle())
552 {
553 if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
554 {
555 if (seat->Flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING)
556 {
557 if (movementInfo.pos.GetOrientation() != mover->GetOrientation())
558 {
559 mover->SetOrientation(movementInfo.pos.GetOrientation());
561 }
562 }
563 }
564 return;
565 }
566
567 mover->UpdatePosition(movementInfo.pos);
568
570 moveUpdate.Status = &mover->m_movementInfo;
571 mover->SendMessageToSet(moveUpdate.Write(), _player);
572
573 // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
574 if (opcode == CMSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
575 plrMover->HandleFall();
576
577 // interrupt parachutes upon falling or landing in water
578 if (opcode == CMSG_MOVE_FALL_LAND || opcode == CMSG_MOVE_START_SWIM)
580
581 if (opcode == CMSG_MOVE_SET_FLY || opcode == CMSG_MOVE_SET_ADV_FLY)
582 {
583 _player->UnsummonPetTemporaryIfAny(); // always do the pet removal on current client activeplayer only
585 }
586
587 if (plrMover) // nothing is charmed, or player charmed
588 {
589 if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
591
592 plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
593
594 if (movementInfo.pos.GetPositionZ() < plrMover->GetMap()->GetMinHeight(plrMover->GetPhaseShift(), movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()))
595 {
596 if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player)))
597 {
598 // NOTE: this is actually called many times while falling
599 // even after the player has been teleported away
601 if (plrMover->IsAlive())
602 {
603 TC_LOG_DEBUG("entities.player.falldamage", "FALLDAMAGE Below map. Map min height: {} , Player debug info:\n{}", plrMover->GetMap()->GetMinHeight(plrMover->GetPhaseShift(), movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY()), plrMover->GetDebugInfo());
605 plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
606 // player can be alive if GM/etc
607 // change the death state to CORPSE to prevent the death timer from
608 // starting in the next player update
609 if (plrMover->IsAlive())
610 plrMover->KillPlayer();
611 }
612 }
613 }
614 else
616
617 if (opcode == CMSG_MOVE_JUMP)
618 {
621 }
622
623 // Whenever a player stops a movement action, several position based checks and updates are being performed
624 switch (opcode)
625 {
628 case CMSG_MOVE_STOP:
634 plrMover->UpdateZoneAndAreaId();
635 plrMover->UpdateIndoorsOutdoorsAuras();
636 plrMover->UpdateTavernRestingState();
637 break;
638 default:
639 break;
640 }
641 }
642}
643
645{
646 Unit* mover = ValidateAndGetUnitBeingMoved(packet.Ack.Status.guid, packet.GetOpcode(), true);
647 if (!mover)
648 return;
649
650 if (!ValidateMovementInfo(mover, &packet.Ack.Status))
651 return;
652
653 /*----------------*/
654
655 // client ACK send one packet for mounted/run case and need skip all except last from its
656 // in other cases anti-cheat check can be fail in false case
657 UnitMoveType move_type;
658
659 static char const* const move_type_name[MAX_MOVE_TYPE] =
660 {
661 "Walk",
662 "Run",
663 "RunBack",
664 "Swim",
665 "SwimBack",
666 "TurnRate",
667 "Flight",
668 "FlightBack",
669 "PitchRate"
670 };
671
672 OpcodeClient opcode = packet.GetOpcode();
673 switch (opcode)
674 {
675
676 case CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; break;
677 case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; break;
679 case CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; break;
685
686 default:
687 TC_LOG_ERROR("network", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: {}", opcode);
688 return;
689 }
690
691 // skip all forced speed changes except last and unexpected
692 // in run/mounted case used one ACK and it must be skipped. m_forced_speed_changes[MOVE_RUN] store both.
693 if (_player->m_forced_speed_changes[move_type] > 0)
694 {
695 --_player->m_forced_speed_changes[move_type];
696 if (_player->m_forced_speed_changes[move_type] > 0)
697 return;
698 }
699
700 if (!_player->GetTransport() && std::fabs(_player->GetSpeed(move_type) - packet.Speed) > 0.01f)
701 {
702 if (_player->GetSpeed(move_type) > packet.Speed) // must be greater - just correct
703 {
704 TC_LOG_ERROR("network", "{}SpeedChange player {} is NOT correct (must be {} instead {}), force set to correct value",
705 move_type_name[move_type], _player->GetName(), _player->GetSpeed(move_type), packet.Speed);
706 _player->SetSpeedRate(move_type, _player->GetSpeedRate(move_type));
707 }
708 else // must be lesser - cheating
709 {
710 TC_LOG_DEBUG("misc", "Player {} from account id {} kicked for incorrect speed (must be {} instead {})",
711 _player->GetName(), _player->GetSession()->GetAccountId(), _player->GetSpeed(move_type), packet.Speed);
712 _player->GetSession()->KickPlayer("WorldSession::HandleForceSpeedChangeAck Incorrect speed");
713 }
714 }
715}
716
718{
719 Unit* mover = ValidateAndGetUnitBeingMoved(speedAck.Ack.Status.guid, speedAck.GetOpcode(), true);
720 if (!mover)
721 return;
722
723 ValidateMovementInfo(mover, &speedAck.Ack.Status);
724}
725
727{
728 Unit* mover = ValidateAndGetUnitBeingMoved(speedRangeAck.Ack.Status.guid, speedRangeAck.GetOpcode(), true);
729 if (!mover)
730 return;
731
732 ValidateMovementInfo(mover, &speedRangeAck.Ack.Status);
733}
734
736{
737 if (GetPlayer()->IsInWorld())
738 if (_player->GetUnitBeingMoved()->GetGUID() != packet.ActiveMover)
739 TC_LOG_DEBUG("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is {} and should be {}" , packet.ActiveMover.ToString(), _player->GetUnitBeingMoved()->GetGUID().ToString());
740}
741
743{
744 Unit* mover = ValidateAndGetUnitBeingMoved(movementAck.Ack.Status.guid, movementAck.GetOpcode(), true);
745 if (!mover)
746 return;
747
748 if (!ValidateMovementInfo(mover, &movementAck.Ack.Status))
749 return;
750
751 movementAck.Ack.Status.time = AdjustClientMovementTime(movementAck.Ack.Status.time);
752 mover->m_movementInfo = movementAck.Ack.Status;
753
755 updateKnockBack.Status = &mover->m_movementInfo;
756 mover->SendMessageToSet(updateKnockBack.Write(), false);
757}
758
760{
761 Unit* mover = ValidateAndGetUnitBeingMoved(movementAck.Ack.Status.guid, movementAck.GetOpcode(), true);
762 if (!mover)
763 return;
764
765 ValidateMovementInfo(mover, &movementAck.Ack.Status);
766}
767
775
777{
778 Unit* mover = ValidateAndGetUnitBeingMoved(setCollisionHeightAck.Data.Status.guid, setCollisionHeightAck.GetOpcode(), true);
779 if (!mover)
780 return;
781
782 ValidateMovementInfo(mover, &setCollisionHeightAck.Data.Status);
783}
784
786{
787 Unit* mover = ValidateAndGetUnitBeingMoved(moveApplyMovementForceAck.Ack.Status.guid, moveApplyMovementForceAck.GetOpcode(), true);
788 if (!mover)
789 return;
790
791 if (!ValidateMovementInfo(mover, &moveApplyMovementForceAck.Ack.Status))
792 return;
793
794 moveApplyMovementForceAck.Ack.Status.time = AdjustClientMovementTime(moveApplyMovementForceAck.Ack.Status.time);
795
797 updateApplyMovementForce.Status = &moveApplyMovementForceAck.Ack.Status;
798 updateApplyMovementForce.Force = &moveApplyMovementForceAck.Force;
799 mover->SendMessageToSet(updateApplyMovementForce.Write(), false);
800}
801
803{
804 Unit* mover = ValidateAndGetUnitBeingMoved(moveRemoveMovementForceAck.Ack.Status.guid, moveRemoveMovementForceAck.GetOpcode(), true);
805 if (!mover)
806 return;
807
808 if (!ValidateMovementInfo(mover, &moveRemoveMovementForceAck.Ack.Status))
809 return;
810
811 moveRemoveMovementForceAck.Ack.Status.time = AdjustClientMovementTime(moveRemoveMovementForceAck.Ack.Status.time);
812
814 updateRemoveMovementForce.Status = &moveRemoveMovementForceAck.Ack.Status;
815 updateRemoveMovementForce.TriggerGUID = moveRemoveMovementForceAck.ID;
816 mover->SendMessageToSet(updateRemoveMovementForce.Write(), false);
817}
818
820{
821 Unit* mover = ValidateAndGetUnitBeingMoved(setModMovementForceMagnitudeAck.Ack.Status.guid, setModMovementForceMagnitudeAck.GetOpcode(), true);
822 if (!mover)
823 return;
824
825 if (!ValidateMovementInfo(mover, &setModMovementForceMagnitudeAck.Ack.Status))
826 return;
827
828 // skip all except last
830 {
833 {
834 float expectedModMagnitude = 1.0f;
835 if (MovementForces const* movementForces = mover->GetMovementForces())
836 expectedModMagnitude = movementForces->GetModMagnitude();
837
838 if (std::fabs(expectedModMagnitude - setModMovementForceMagnitudeAck.Speed) > 0.01f)
839 {
840 TC_LOG_DEBUG("misc", "Player {} from account id {} kicked for incorrect movement force magnitude (must be {} instead {})",
841 _player->GetName(), _player->GetSession()->GetAccountId(), expectedModMagnitude, setModMovementForceMagnitudeAck.Speed);
842 _player->GetSession()->KickPlayer("WorldSession::HandleMoveSetModMovementForceMagnitudeAck Incorrect magnitude");
843 return;
844 }
845 }
846 }
847
848 setModMovementForceMagnitudeAck.Ack.Status.time = AdjustClientMovementTime(setModMovementForceMagnitudeAck.Ack.Status.time);
849
851 updateModMovementForceMagnitude.Status = &setModMovementForceMagnitudeAck.Ack.Status;
852 updateModMovementForceMagnitude.Speed = setModMovementForceMagnitudeAck.Speed;
853 mover->SendMessageToSet(updateModMovementForceMagnitude.Write(), false);
854}
855
857{
858 Unit* mover = ValidateAndGetUnitBeingMoved(moveApplyInertiaAck.Ack.Status.guid, moveApplyInertiaAck.GetOpcode(), true);
859 if (!mover)
860 return;
861
862 if (!ValidateMovementInfo(mover, &moveApplyInertiaAck.Ack.Status))
863 return;
864
865 moveApplyInertiaAck.Ack.Status.time = AdjustClientMovementTime(moveApplyInertiaAck.Ack.Status.time);
866 mover->m_movementInfo = moveApplyInertiaAck.Ack.Status;
867
869 updateApplyInertia.Status = &mover->m_movementInfo;
870 updateApplyInertia.InertiaID = moveApplyInertiaAck.InertiaID;
871 updateApplyInertia.LifetimeMs = moveApplyInertiaAck.LifetimeMs;
872 mover->SendMessageToSet(updateApplyInertia.Write(), false);
873}
874
876{
877 Unit* mover = ValidateAndGetUnitBeingMoved(moveRemoveInertiaAck.Ack.Status.guid, moveRemoveInertiaAck.GetOpcode(), true);
878 if (!mover)
879 return;
880
881 if (!ValidateMovementInfo(mover, &moveRemoveInertiaAck.Ack.Status))
882 return;
883
884 moveRemoveInertiaAck.Ack.Status.time = AdjustClientMovementTime(moveRemoveInertiaAck.Ack.Status.time);
885 mover->m_movementInfo = moveRemoveInertiaAck.Ack.Status;
886
888 updateRemoveInertia.Status = &mover->m_movementInfo;
889 updateRemoveInertia.InertiaID = moveRemoveInertiaAck.InertiaID;
890 mover->SendMessageToSet(updateRemoveInertia.Write(), false);
891}
892
894{
895 Unit* mover = ValidateAndGetUnitBeingMoved(moveForceGravityModifierChangeAck.Ack.Status.guid, moveForceGravityModifierChangeAck.GetOpcode(), true);
896 if (!mover)
897 return;
898
899 if (!ValidateMovementInfo(mover, &moveForceGravityModifierChangeAck.Ack.Status))
900 return;
901
902 moveForceGravityModifierChangeAck.Ack.Status.time = AdjustClientMovementTime(moveForceGravityModifierChangeAck.Ack.Status.time);
903 mover->m_movementInfo = moveForceGravityModifierChangeAck.Ack.Status;
904 mover->m_movementInfo.gravityModifier = moveForceGravityModifierChangeAck.Ack.Status.gravityModifier;
905
907 updateSetGravityModifier.Status = &mover->m_movementInfo;
908 updateSetGravityModifier.GravityModifier = moveForceGravityModifierChangeAck.GravityModifier;
909 mover->SendMessageToSet(updateSetGravityModifier.Write(), false);
910}
911
913{
914 Unit* mover = ValidateAndGetUnitBeingMoved(moveSplineDone.Status.guid, moveSplineDone.GetOpcode(), false);
915 if (!mover)
916 return;
917
918 if (!ValidateMovementInfo(mover, &moveSplineDone.Status))
919 return;
920
921 // in taxi flight packet received in 2 case:
922 // 1) end taxi path in far (multi-node) flight
923 // 2) switch from one map to other in case multim-map taxi path
924 // we need process only (1)
925
927 if (curDest)
928 {
929 TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
930
931 // far teleport case
932 if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
933 {
934 if (FlightPathMovementGenerator* flight = dynamic_cast<FlightPathMovementGenerator*>(GetPlayer()->GetMotionMaster()->GetCurrentMovementGenerator()))
935 {
936 bool shouldTeleport = curDestNode && curDestNode->ContinentID != GetPlayer()->GetMapId();
937 if (!shouldTeleport)
938 {
939 TaxiPathNodeEntry const* currentNode = flight->GetPath()[flight->GetCurrentNode()];
940 shouldTeleport = currentNode->Flags & TAXI_PATH_NODE_FLAG_TELEPORT;
941 }
942
943 if (shouldTeleport)
944 {
945 // short preparations to continue flight
946 flight->SetCurrentNodeAfterTeleport();
947 TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()];
948 flight->SkipCurrentNode();
949
950 GetPlayer()->TeleportTo(curDestNode->ContinentID, node->Loc.X, node->Loc.Y, node->Loc.Z, GetPlayer()->GetOrientation());
951 }
952 }
953 }
954
955 return;
956 }
957
958 // at this point only 1 node is expected (final destination)
959 if (GetPlayer()->m_taxi.GetPath().size() != 1)
960 return;
961
963 GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ());
964 if (GetPlayer()->pvpInfo.IsHostile)
965 GetPlayer()->CastSpell(GetPlayer(), 2479, true);
966}
967
969{
970 Unit* mover = ValidateAndGetUnitBeingMoved(moveTimeSkipped.MoverGUID, moveTimeSkipped.GetOpcode(), false);
971 if (!mover)
972 return;
973
974 mover->m_movementInfo.time += moveTimeSkipped.TimeSkipped;
975
977 moveSkipTime.MoverGUID = moveTimeSkipped.MoverGUID;
978 moveSkipTime.TimeSkipped = moveTimeSkipped.TimeSkipped;
979 mover->SendMessageToSet(moveSkipTime.Write(), _player);
980}
981
982void WorldSession::HandleTimeSync(uint32 counter, int64 clientTime, TimePoint responseReceiveTime)
983{
984 auto serverTimeAtSent = _pendingTimeSyncRequests.extract(counter);
985 if (!serverTimeAtSent)
986 return;
987
988 // time it took for the request to travel to the client, for the client to process it and reply and for response to travel back to the server.
989 // we are going to make 2 assumptions:
990 // 1) we assume that the request processing time equals 0.
991 // 2) we assume that the packet took as much time to travel from server to client than it took to travel from client to server.
992 uint32 roundTripDuration = getMSTimeDiff(serverTimeAtSent.mapped(), responseReceiveTime);
993 int64 lagDelay = roundTripDuration / 2;
994
995 /*
996 clockDelta = serverTime - clientTime
997 where
998 serverTime: time that was displayed on the clock of the SERVER at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
999 clientTime: time that was displayed on the clock of the CLIENT at the moment when the client processed the SMSG_TIME_SYNC_REQUEST packet.
1000
1001 Once clockDelta has been computed, we can compute the time of an event on server clock when we know the time of that same event on the client clock,
1002 using the following relation:
1003 serverTime = clockDelta + clientTime
1004 */
1005 int64 clockDelta = serverTimeAtSent.mapped() + lagDelay - clientTime;
1006 _timeSyncClockDeltaQueue->push_back(std::pair<int64, uint32>(clockDelta, roundTripDuration));
1008}
1009
1011{
1012 HandleTimeSync(timeSyncResponse.SequenceIndex, timeSyncResponse.ClientTime, timeSyncResponse.GetReceivedTime());
1013}
1014
1019
1021{
1022 HandleTimeSync(SPECIAL_INIT_ACTIVE_MOVER_TIME_SYNC_COUNTER, moveInitActiveMoverComplete.Ticks, moveInitActiveMoverComplete.GetRawPacket()->GetReceivedTime());
1023
1025}
1026
1028{
1029 // implementation of the technique described here: https://web.archive.org/web/20180430214420/http://www.mine-control.com/zack/timesync/timesync.html
1030 // to reduce the skew induced by dropped TCP packets that get resent.
1031
1032 using namespace boost::accumulators;
1033
1034 accumulator_set<uint32, features<tag::mean, tag::median, tag::variance(lazy)> > latencyAccumulator;
1035
1036 for (auto [_, roundTripDuration] : *_timeSyncClockDeltaQueue)
1037 latencyAccumulator(roundTripDuration);
1038
1039 uint32 latencyMedian = static_cast<uint32>(std::round(median(latencyAccumulator)));
1040 uint32 latencyStandardDeviation = static_cast<uint32>(std::round(sqrt(variance(latencyAccumulator))));
1041
1042 accumulator_set<int64, features<tag::mean> > clockDeltasAfterFiltering;
1043 uint32 sampleSizeAfterFiltering = 0;
1044 for (auto [clockDelta, roundTripDuration] : *_timeSyncClockDeltaQueue)
1045 {
1046 if (roundTripDuration < latencyStandardDeviation + latencyMedian) {
1047 clockDeltasAfterFiltering(clockDelta);
1048 sampleSizeAfterFiltering++;
1049 }
1050 }
1051
1052 if (sampleSizeAfterFiltering != 0)
1053 {
1054 int64 meanClockDelta = static_cast<int64>(std::round(mean(clockDeltasAfterFiltering)));
1055 if (std::abs(meanClockDelta - _timeSyncClockDelta) > 25)
1056 _timeSyncClockDelta = meanClockDelta;
1057 }
1058 else if (_timeSyncClockDelta == 0)
1060
1061 if (_player)
1062 {
1065 }
1066}
@ SEC_PLAYER
Definition Common.h:43
DB2Storage< MapEntry > sMapStore("Map.db2", &MapLoadInfo::Instance)
DB2Storage< TaxiNodesEntry > sTaxiNodesStore("TaxiNodes.db2", &TaxiNodesLoadInfo::Instance)
@ VEHICLE_SEAT_FLAG_ALLOW_TURNING
Definition DBCEnums.h:3122
@ TAXI_PATH_NODE_FLAG_TELEPORT
Definition DBCEnums.h:2836
int64_t int64
Definition Define.h:149
#define SI64LIT(N)
Definition Define.h:142
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
Definition Duration.h:40
#define SIZE_OF_GRIDS
Definition GridDefines.h:40
#define sInstanceLockMgr
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:173
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:182
#define TC_LOG_WARN(filterType__, message__,...)
Definition Log.h:179
#define TC_LOG_TRACE(filterType__, message__,...)
Definition Log.h:170
#define sMapMgr
Definition MapManager.h:186
@ FLIGHT_MOTION_TYPE
#define REMOVE_VIOLATING_FLAGS(check, maskToRemove)
@ MOVEMENTFLAG_DESCENDING
@ MOVEMENTFLAG_PITCH_DOWN
@ MOVEMENTFLAG_PITCH_UP
@ MOVEMENTFLAG_RIGHT
@ MOVEMENTFLAG_FORWARD
@ MOVEMENTFLAG_STRAFE_LEFT
@ MOVEMENTFLAG_BACKWARD
@ MOVEMENTFLAG_WATERWALKING
@ MOVEMENTFLAG_MASK_MOVING
@ MOVEMENTFLAG_DISABLE_GRAVITY
@ MOVEMENTFLAG_FLYING
@ MOVEMENTFLAG_FALLING_SLOW
@ MOVEMENTFLAG_CAN_FLY
@ MOVEMENTFLAG_ROOT
@ MOVEMENTFLAG_MASK_TURNING
@ MOVEMENTFLAG_FALLING
@ MOVEMENTFLAG_LEFT
@ MOVEMENTFLAG_STRAFE_RIGHT
@ MOVEMENTFLAG_ASCENDING
@ MOVEMENTFLAG_HOVER
@ MOVEMENTFLAG_SPLINE_ELEVATION
@ SMSG_MOVE_UPDATE_MOD_MOVEMENT_FORCE_MAGNITUDE
Definition Opcodes.h:2000
constexpr FormattedOpcodeName< OpcodeClient > GetOpcodeNameForLogging(OpcodeClient opcode)
Lookup opcode name for human understandable logging.
Definition Opcodes.h:2639
OpcodeClient
Definition Opcodes.h:38
@ CMSG_MOVE_SET_ADV_FLY
Definition Opcodes.h:647
@ CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK
Definition Opcodes.h:629
@ CMSG_MOVE_STOP_SWIM
Definition Opcodes.h:695
@ CMSG_MOVE_START_SWIM
Definition Opcodes.h:688
@ CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK
Definition Opcodes.h:630
@ CMSG_MOVE_STOP_TURN
Definition Opcodes.h:696
@ CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK
Definition Opcodes.h:632
@ CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK
Definition Opcodes.h:622
@ CMSG_MOVE_STOP_STRAFE
Definition Opcodes.h:694
@ CMSG_MOVE_STOP_ASCEND
Definition Opcodes.h:692
@ CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK
Definition Opcodes.h:627
@ CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:626
@ CMSG_MOVE_STOP
Definition Opcodes.h:691
@ CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:628
@ CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK
Definition Opcodes.h:624
@ CMSG_MOVE_FALL_LAND
Definition Opcodes.h:618
@ CMSG_MOVE_STOP_PITCH
Definition Opcodes.h:693
@ CMSG_MOVE_JUMP
Definition Opcodes.h:642
@ CMSG_MOVE_SET_FLY
Definition Opcodes.h:670
@ CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK
Definition Opcodes.h:621
@ DAMAGE_FALL_TO_VOID
Definition Player.h:930
@ NEW_WORLD_NORMAL
Definition Player.h:868
@ NEW_WORLD_SEAMLESS
Definition Player.h:869
@ TELE_TO_SEAMLESS
Definition Player.h:916
@ TELE_REVIVE_AT_TELEPORT
Definition Player.h:915
@ PLAYER_FLAGS_IN_PVP
Definition Player.h:521
@ PLAYER_FLAGS_IS_OUT_OF_BOUNDS
Definition Player.h:526
@ PLAYER_LOCAL_FLAG_OVERRIDE_TRANSPORT_SERVER_TIME
Definition Player.h:577
@ RAID_INSTANCE_WELCOME
Definition Player.h:874
@ WaitingForSuspendTokenResponse
@ EMOTE_ONESHOT_NONE
constexpr BattlegroundQueueTypeId BATTLEGROUND_QUEUE_NONE
@ TEAM_OTHER
@ BATTLEGROUND_TYPE_NONE
@ SPELL_AURA_FEATHER_FALL
@ SPELL_AURA_FLY
@ SPELL_AURA_GHOST
@ SPELL_AURA_WATER_WALK
@ SPELL_AURA_HOVER
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
@ SPELL_AURA_ADV_FLYING
@ PROC_SPELL_PHASE_NONE
Definition SpellMgr.h:223
@ PROC_SPELL_TYPE_MASK_ALL
Definition SpellMgr.h:216
@ PROC_FLAG_JUMP
Definition SpellMgr.h:133
@ PROC_FLAG_NONE
Definition SpellMgr.h:92
@ PROC_HIT_NONE
Definition SpellMgr.h:234
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition Timer.h:40
UnitMoveType
@ MOVE_FLIGHT
@ MOVE_SWIM
@ MOVE_TURN_RATE
@ MOVE_FLIGHT_BACK
@ MOVE_SWIM_BACK
@ MOVE_RUN
@ MOVE_PITCH_RATE
@ MOVE_RUN_BACK
@ MOVE_WALK
@ UNIT_STAND_STATE_STAND
Definition UnitDefines.h:42
#define MAX_MOVE_TYPE
@ VEHICLE_FLAG_FIXED_POSITION
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
bool IsInWorld() const
Definition BaseEntity.h:158
virtual bool HandlePlayerUnderMap(Player *)
static bool IsValidMapCoord(uint32 mapid, float x, float y)
Definition MapManager.h:83
Definition Map.h:227
virtual void RemovePlayerFromMap(Player *, bool)
Definition Map.cpp:923
virtual bool AddPlayerToMap(Player *player, bool initPlayer=true)
Definition Map.cpp:392
virtual TransferAbortParams CannotEnter(Player *)
Definition Map.h:359
float GetMinHeight(PhaseShift const &phaseShift, float x, float y)
Definition Map.cpp:1725
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:3588
Difficulty GetDifficultyID() const
Definition Map.h:363
uint32 GetId() const
Definition Map.cpp:3288
char const * GetMapName() const
Definition Map.cpp:1854
Transport * GetTransport(ObjectGuid const &guid)
Definition Map.cpp:3598
MovementGenerator * GetCurrentMovementGenerator() const
virtual bool Initialize(Unit *owner)=0
bool IsEmpty() const
Definition ObjectGuid.h:362
std::string ToString() const
Player * ToPlayer()
Definition Object.h:126
uint32 GetTaxiDestination() const
Definition PlayerTaxi.h:78
void SendInitialPacketsAfterAddToMap()
Definition Player.cpp:25024
WorldLocation const & GetCorpseLocation() const
Definition Player.h:2323
void UpdateFallInformationIfNeed(MovementInfo const &minfo, uint32 opcode)
Definition Player.cpp:27880
bool m_InstanceValid
Definition Player.h:2748
void SetPlayerFlag(PlayerFlags flags)
Definition Player.h:2896
void SetBGTeam(Team team)
Definition Player.cpp:24271
void SetPlayerLocalFlag(PlayerLocalFlags flags)
Definition Player.h:2992
void RemovePlayerFlag(PlayerFlags flags)
Definition Player.h:2897
uint32 EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
Definition Player.cpp:618
void KillPlayer()
Definition Player.cpp:4355
void SetBattlegroundId(uint32 val, BattlegroundTypeId bgTypeId, BattlegroundQueueTypeId queueId)
Definition Player.cpp:25704
uint8 m_movementForceModMagnitudeChanges
Definition Player.h:2707
void HandleFall()
Definition Player.cpp:27443
bool InBattleground() const
Definition Player.h:2570
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4453
void UpdateZone(uint32 newZone, uint32 newArea)
Definition Player.cpp:7492
void SetFallInformation(uint32 time, float z)
Definition Player.cpp:27437
void SendInitialPacketsBeforeAddToMap()
Definition Player.cpp:24905
void ResetMap() override
Definition Player.cpp:28390
WorldLocation m_homebind
Definition Player.h:2679
int32 GetNewWorldCounter() const
Definition Player.h:2384
WorldSession * GetSession() const
Definition Player.h:2256
bool IsInvitedForBattlegroundInstance(uint32 instanceId) const
Definition Player.cpp:25757
void UnsummonPetTemporaryIfAny()
Definition Player.cpp:27929
TeleportState GetTeleportState() const
Definition Player.h:2381
TeleportLocation m_teleport_dest
Definition Player.h:3361
void UpdateVisibilityForPlayer()
Definition Player.cpp:24787
void ResummonBattlePetTemporaryUnSummonedIfAny()
Definition Player.cpp:27978
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options=TELE_TO_NONE, Optional< uint32 > instanceId={}, uint32 teleportSpellId=0)
Definition Player.cpp:1181
void FinishTaxiFlight()
Definition Player.cpp:23302
Battleground * GetBattleground() const
Definition Player.cpp:25650
void ProcessDelayedOperations()
Definition Player.cpp:1446
void UpdateIndoorsOutdoorsAuras()
Definition Player.cpp:6340
bool UpdatePosition(float x, float y, float z, float orientation, bool teleport=false) override
Definition Player.cpp:6142
PvPInfo pvpInfo
Definition Player.h:2107
void SummonIfPossible(bool agree)
Definition Player.cpp:26040
PlayerTaxi m_taxi
Definition Player.h:1277
std::array< uint8, MAX_MOVE_TYPE > m_forced_speed_changes
Definition Player.h:2706
void SetTransportServerTime(int32 transportServerTime)
Definition Player.h:3004
bool CheckInstanceValidity(bool)
Definition Player.cpp:20140
Garrison * GetGarrison() const
Definition Player.h:2868
void UnsummonBattlePetTemporaryIfAny(bool onFlyingMount=false)
Definition Player.cpp:27963
uint32 GetBattlegroundId() const
Definition Player.h:2572
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:2895
TeleportLocation & GetTeleportDest()
Definition Player.h:2380
void UpdateObjectVisibility(bool forced=true) override
Definition Player.cpp:24772
void SetMap(Map *map) override
Definition Player.cpp:28402
std::string GetDebugInfo() const override
Definition Player.cpp:31388
void ResummonPetTemporaryUnSummonedIfAny()
Definition Player.cpp:27944
void SetTeleportState(TeleportState state)
Definition Player.h:2382
void UpdatePvP(bool state, bool override=false)
Definition Player.cpp:24056
void CleanupAfterTaxiFlight()
Definition Player.cpp:23311
void UpdateTavernRestingState()
Definition Player.cpp:6346
BGData m_bgData
Definition Player.h:3081
void UpdateZoneAndAreaId()
Definition Player.cpp:6324
bool IsBeingTeleported() const
Definition Player.h:2385
EnumFlag< TeleportToOptions > GetTeleportOptions() const
Definition Player.h:2383
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4269
virtual ObjectGuid GetTransportGUID() const =0
virtual void AddPassenger(WorldObject *passenger, Position const &offset)=0
virtual TransportBase * RemovePassenger(WorldObject *passenger)=0
Definition Unit.h:647
Vehicle * GetVehicle() const
Definition Unit.h:1800
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:8951
void SetStandState(UnitStandStateType state, uint32 animKitID=0)
Definition Unit.cpp:10804
Emote GetEmoteState() const
Definition Unit.h:879
bool IsPvP() const
Definition Unit.h:901
MotionMaster * GetMotionMaster()
Definition Unit.h:1750
MovementForces const * GetMovementForces() const
Definition Unit.h:1189
bool IsAlive() const
Definition Unit.h:1205
uint32 m_movementCounter
Incrementing counter used in movement packets.
Definition Unit.h:2023
void SetEmoteState(Emote emote)
Definition Unit.h:880
virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport=false)
Definition Unit.cpp:13123
bool IsInFlight() const
Definition Unit.h:1042
Unit * GetUnitBeingMoved() const
Definition Unit.h:1271
float GetHoverOffset() const
Definition Unit.h:1828
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4832
void RemoveAurasWithInterruptFlags(InterruptFlags flag, SpellInfo const *source=nullptr)
Definition Unit.cpp:4259
float GetSpeedRate(UnitMoveType mtype) const
Definition Unit.h:1734
void SetSpeedRate(UnitMoveType mtype, float rate)
Definition Unit.cpp:8961
std::unique_ptr< Movement::MoveSpline > movespline
Definition Unit.h:1854
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)
Definition Unit.cpp:5589
bool IsInCombat() const
Definition Unit.h:1073
bool IsSitState() const
Definition Unit.cpp:10789
constexpr uint32 GetMapId() const
Definition Position.h:216
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:1099
Map * GetMap() const
Definition Object.h:411
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
PhaseShift & GetPhaseShift()
Definition Object.h:310
TransportBase * GetTransport() const
Definition Object.h:537
std::string const & GetName() const
Definition Object.h:342
void UpdatePositionData()
Definition Object.cpp:344
uint32 GetZoneId() const
Definition Object.h:332
MovementInfo m_movementInfo
Definition Object.h:548
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.h:334
TimePoint GetReceivedTime() const
Definition WorldPacket.h:67
OpcodeClient GetOpcode() const
Definition Packet.h:68
Duration< Milliseconds, uint32 > LifetimeMs
WorldPacket const * Write() override
Duration< Milliseconds, uint32 > LifetimeMs
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * GetRawPacket() const
Definition Packet.h:38
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 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)
Player * _player
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
uint32 GetGameTimeMS()
Definition GameTime.cpp:57
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
bool IsValidMapCoord(float c)
BattlegroundQueueTypeId queueId
Definition Player.h:1136
bool IsBattlegroundOrArena() const
bool IsDungeon() const
bool HasMovementFlag(MovementFlags flag) const
ObjectGuid guid
void ResetTransport()
float gravityModifier
void AddMovementFlag(MovementFlags flag)
float stepUpStartElevation
struct MovementInfo::TransportInfo transport
MovementFlags flags
constexpr void SetOrientation(float orientation)
Definition Position.h:82
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
float GetExactDist2d(const float x, const float y) const
Definition Position.h:117
bool IsPositionValid() const
Definition Position.cpp:42
constexpr void Relocate(float x, float y)
Definition Position.h:74
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
bool IsHostile
Definition Player.h:438
DBCPosition3D Loc
Optional< uint32 > InstanceId
Definition Player.h:1212
WorldLocation Location
Definition Player.h:1210
Optional< uint32 > LfgDungeonsId
Definition Player.h:1213
Optional< ObjectGuid > TransportGuid
Definition Player.h:1211
TaggedPosition< Position::XYZO > Pos