diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0052f200f..a31e39b1b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -418,7 +418,7 @@ Player::Player(WorldSession* session): Unit(), m_mover(this) sScriptMgr->OnConstructPlayer(this); - m_expectingChangeTransport = false; + _expectingChangeTransport = false; } Player::~Player() @@ -1549,6 +1549,8 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati //remove auras before removing from map... RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); + SetMapChangeOrderCounter(); + if (!GetSession()->PlayerLogout()) { // send transfer packets diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index b7e35ca53..577be3385 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2633,8 +2633,14 @@ public: std::string GetDebugInfo() const override; - bool IsExpectingChangeTransport() const { return m_expectingChangeTransport; } - void SetExpectingChangeTransport(bool state) { m_expectingChangeTransport = state; } + bool IsExpectingChangeTransport() const { return _expectingChangeTransport; } + void SetExpectingChangeTransport(bool state) { _expectingChangeTransport = state; } + + uint32 GetPendingFlightChange() const { return _pendingFlightChangeCounter; } + void SetPendingFlightChange(uint32 counter) { _pendingFlightChangeCounter = counter; } + + void SetMapChangeOrderCounter() { _mapChangeOrderCounter = GetSession()->GetOrderCounter(); } + uint32 GetMapChangeOrderCounter() { return _mapChangeOrderCounter; } /*********************************************************/ /*** SPELL QUEUE SYSTEM ***/ @@ -3017,7 +3023,9 @@ private: Seconds m_creationTime; - bool m_expectingChangeTransport; + bool _expectingChangeTransport; + uint32 _pendingFlightChangeCounter; + uint32 _mapChangeOrderCounter; }; void AddItemsSetItem(Player* player, Item* item); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 7bd1f97f8..19f71e9b1 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -20403,6 +20403,7 @@ void Unit::SetCanFly(bool enable) if (Player const* player = GetClientControlling()) { uint32 const counter = player->GetSession()->GetOrderCounter(); + const_cast(player)->SetPendingFlightChange(counter); WorldPacket data(enable ? SMSG_MOVE_SET_CAN_FLY : SMSG_MOVE_UNSET_CAN_FLY, GetPackGUID().size() + 4); data << GetPackGUID(); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 13ef9ec66..a1c09fb47 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1519,12 +1519,19 @@ void WorldSession::HandleMoveFlagChangeOpcode(WorldPacket& recv_data) mover->m_movementInfo.flags = movementInfo.GetMovementFlags(); + // old map - async processing, ignore + if (counter <= _player->GetMapChangeOrderCounter()) + return; + if (!ProcessMovementInfo(movementInfo, mover, plrMover, recv_data)) { recv_data.rfinish(); // prevent warnings spam return; } + if (_player->GetPendingFlightChange() == counter && opcode == CMSG_MOVE_SET_CAN_FLY_ACK) + _player->SetPendingFlightChange(false); + Opcodes response; switch (recv_data.GetOpcode()) diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 66aa1b590..1be5903bf 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -105,6 +105,13 @@ void WorldSession::HandleMoveWorldportAck() GetPlayer()->UpdatePositionData(); GetPlayer()->SendInitialPacketsBeforeAddToMap(); + + if (GetPlayer()->GetPendingFlightChange() <= GetPlayer()->GetMapChangeOrderCounter()) + { + if (!GetPlayer()->HasIncreaseMountedFlightSpeedAura() && !GetPlayer()->HasFlyAura()) + GetPlayer()->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_CAN_FLY); + } + if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer())) { LOG_ERROR("network.opcode", "WORLD: failed to teleport player {} ({}) to map {} because of unknown reason!", @@ -679,6 +686,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket& recvData) return; } + // old map - async processing, ignore + if (counter <= _player->GetMapChangeOrderCounter()) + return; + if (!ProcessMovementInfo(movementInfo, mover, _player, recvData)) { recvData.rfinish(); // prevent warnings spam @@ -991,6 +1002,10 @@ void WorldSession::HandleMoveRootAck(WorldPacket& recvData) return; } + // old map - async processing, ignore + if (counter <= _player->GetMapChangeOrderCounter()) + return; + if (!ProcessMovementInfo(movementInfo, mover, _player, recvData)) return; diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index d14eee29c..84cbe96ed 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -374,7 +374,7 @@ void OpcodeTable::Initialize() /*0x0F3*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_NORMAL_FALL, STATUS_NEVER); /*0x0F4*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_NEVER); /*0x0F5*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_NEVER); - /*0x0F6*/ DEFINE_HANDLER(CMSG_MOVE_HOVER_ACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveFlagChangeOpcode ); + /*0x0F6*/ DEFINE_HANDLER(CMSG_MOVE_HOVER_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveFlagChangeOpcode ); /*0x0F7*/ DEFINE_SERVER_OPCODE_HANDLER(MSG_MOVE_HOVER, STATUS_NEVER); /*0x0F8*/ DEFINE_HANDLER(CMSG_TRIGGER_CINEMATIC_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x0F9*/ DEFINE_HANDLER(CMSG_OPENING_CINEMATIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -1245,7 +1245,7 @@ void OpcodeTable::Initialize() /*0x45A*/ DEFINE_HANDLER(MSG_MOVE_SET_PITCH_RATE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x45B*/ DEFINE_HANDLER(MSG_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x45C*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_PITCH_RATE_CHANGE, STATUS_NEVER); - /*0x45D*/ DEFINE_HANDLER(CMSG_FORCE_PITCH_RATE_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleForceSpeedChangeAck ); + /*0x45D*/ DEFINE_HANDLER(CMSG_FORCE_PITCH_RATE_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); /*0x45E*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_SET_PITCH_RATE, STATUS_NEVER); /*0x45F*/ DEFINE_HANDLER(CMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x460*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_NEVER); @@ -1359,9 +1359,9 @@ void OpcodeTable::Initialize() /*0x4CC*/ DEFINE_HANDLER(CMSG_END_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x4CD*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_NEVER); /*0x4CE*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_DISABLE, STATUS_NEVER); - /*0x4CF*/ DEFINE_HANDLER(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleMoveFlagChangeOpcode ); + /*0x4CF*/ DEFINE_HANDLER(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveFlagChangeOpcode ); /*0x4D0*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_ENABLE, STATUS_NEVER); - /*0x4D1*/ DEFINE_HANDLER(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleMoveFlagChangeOpcode ); + /*0x4D1*/ DEFINE_HANDLER(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveFlagChangeOpcode ); /*0x4D2*/ DEFINE_SERVER_OPCODE_HANDLER(MSG_MOVE_GRAVITY_CHNG, STATUS_NEVER); /*0x4D3*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER); /*0x4D4*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, STATUS_NEVER); @@ -1431,7 +1431,7 @@ void OpcodeTable::Initialize() /*0x514*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_ALL_COMBAT_LOG, STATUS_NEVER); /*0x515*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_NEVER); /*0x516*/ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HGT, STATUS_NEVER); - /*0x517*/ DEFINE_HANDLER(CMSG_MOVE_SET_COLLISION_HGT_ACK, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleForceSpeedChangeAck ); + /*0x517*/ DEFINE_HANDLER(CMSG_MOVE_SET_COLLISION_HGT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck ); /*0x518*/ DEFINE_HANDLER(MSG_MOVE_SET_COLLISION_HGT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x519*/ DEFINE_HANDLER(CMSG_CLEAR_RANDOM_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); /*0x51A*/ DEFINE_HANDLER(CMSG_CLEAR_HOLIDAY_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );