diff options
-rw-r--r-- | src/server/game/DataStores/DBCStructure.h | 2 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCfmt.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 86 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 5 | ||||
-rw-r--r-- | src/server/game/Handlers/MovementHandler.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 14 | ||||
-rw-r--r-- | src/server/game/Maps/Map.h | 6 | ||||
-rw-r--r-- | src/server/game/Server/Packets/InstancePackets.cpp | 32 | ||||
-rw-r--r-- | src/server/game/Server/Packets/InstancePackets.h | 52 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 11 |
12 files changed, 160 insertions, 87 deletions
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 178ab097d81..2fdc6ba1e3e 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1235,7 +1235,7 @@ struct MapEntry uint32 RaidOffset; // 17 uint32 MaxPlayers; // 18 int32 ParentMapID; // 19 related to phasing - //uint32 CosmeticParentMapID // 20 + int32 CosmeticParentMapID; // 20 //uint32 TimeOffset // 21 // Helpers diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 8c067dabb27..5e07065a122 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -113,7 +113,7 @@ char const LiquidTypefmt[] = "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx char const LockEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; char const PhaseEntryfmt[] = "ni"; char const MailTemplateEntryfmt[] = "nxs"; -char const MapEntryfmt[] = "nxiixxsixxixiffxiiiixx"; +char const MapEntryfmt[] = "nxiixxsixxixiffxiiiiix"; char const MapDifficultyEntryfmt[] = "diisiiii"; char const MinorTalentEntryfmt[] = "niii"; char const MovieEntryfmt[] = "nxxxx"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d7e48947600..c23d0988fb8 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -31,16 +31,17 @@ #include "ChannelMgr.h" #include "CharacterDatabaseCleaner.h" #include "CharacterPackets.h" -#include "TalentPackets.h" #include "Chat.h" +#include "ChatPackets.h" #include "CombatLogPackets.h" #include "CombatPackets.h" #include "Common.h" #include "ConditionMgr.h" #include "CreatureAI.h" -#include "DatabaseEnv.h" #include "DB2Stores.h" +#include "DatabaseEnv.h" #include "DisableMgr.h" +#include "DuelPackets.h" #include "EquipmentSetPackets.h" #include "Formulas.h" #include "GameEventMgr.h" @@ -52,14 +53,19 @@ #include "GroupMgr.h" #include "Guild.h" #include "GuildMgr.h" +#include "InstancePackets.h" #include "InstanceSaveMgr.h" #include "InstanceScript.h" +#include "ItemPackets.h" #include "LFGMgr.h" #include "Language.h" #include "Log.h" +#include "LootPackets.h" #include "MailPackets.h" #include "MapInstanced.h" #include "MapManager.h" +#include "MiscPackets.h" +#include "MovementPackets.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Opcodes.h" @@ -67,6 +73,7 @@ #include "OutdoorPvPMgr.h" #include "Pet.h" #include "QuestDef.h" +#include "QuestPackets.h" #include "ReputationMgr.h" #include "revision.h" #include "SkillDiscovery.h" @@ -77,27 +84,21 @@ #include "SpellHistory.h" #include "SpellMgr.h" #include "SpellPackets.h" +#include "TalentPackets.h" +#include "TradePackets.h" #include "Transport.h" #include "UpdateData.h" #include "UpdateFieldFlags.h" #include "UpdateMask.h" #include "Util.h" #include "Vehicle.h" +#include "VehiclePackets.h" #include "Weather.h" #include "WeatherMgr.h" #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" #include "WorldStatePackets.h" -#include "MiscPackets.h" -#include "ChatPackets.h" -#include "DuelPackets.h" -#include "MovementPackets.h" -#include "ItemPackets.h" -#include "QuestPackets.h" -#include "LootPackets.h" -#include "TradePackets.h" -#include "VehiclePackets.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -2057,6 +2058,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // this will be used instead of the current location in SaveToDB m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_options = options; SetFallInformation(0, z); // code for finish transfer called in WorldSession::HandleMovementOpcodes() @@ -2086,6 +2088,12 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!sMapMgr->CanPlayerEnter(mapid, this, false)) return false; + // Seamless teleport can happen only if cosmetic maps match + if (!oldmap || + (oldmap->GetEntry()->CosmeticParentMapID != mapid && GetMapId() != mEntry->CosmeticParentMapID && + !(oldmap->GetEntry()->CosmeticParentMapID != -1 ^ oldmap->GetEntry()->CosmeticParentMapID != mEntry->CosmeticParentMapID))) + options &= ~TELE_TO_SEAMLESS; + //I think this always returns true. Correct me if I am wrong. // If the map is not created, assume it is possible to enter it. // It will be created in the WorldPortAck. @@ -2148,7 +2156,7 @@ 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); - if (!GetSession()->PlayerLogout()) + if (!GetSession()->PlayerLogout() && !(options & TELE_TO_SEAMLESS)) { // send transfer packets WorldPackets::Movement::TransferPending transferPending; @@ -2168,19 +2176,25 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati oldmap->RemovePlayerFromMap(this, false); m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_options = options; SetFallInformation(0, z); // if the player is saved before worldportack (at logout for example) // this will be used instead of the current location in SaveToDB if (!GetSession()->PlayerLogout()) { + if (mEntry->IsDungeon()) + { + WorldPackets::Instance::UpdateLastInstance updateLastInstance; + updateLastInstance.MapID = mapid; + SendDirectMessage(updateLastInstance.Write()); + } + WorldPackets::Movement::NewWorld packet; packet.MapID = mapid; packet.Pos = m_teleport_dest; - packet.Reason = NEW_WORLD_NORMAL; - + packet.Reason = !(options & TELE_TO_SEAMLESS) ? NEW_WORLD_NORMAL : NEW_WORLD_SEAMLESS; SendDirectMessage(packet.Write()); - SendSavedInstances(); } // move packet sent by client always after far teleport @@ -18548,48 +18562,6 @@ void Player::SendRaidInfo() GetSession()->SendPacket(&data); } -/* -- called on every successful teleportation to a map -*/ -void Player::SendSavedInstances() -{ - bool hasBeenSaved = false; - WorldPacket data; - - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - { - for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) - { - if (itr->second.perm) // only permanent binds are sent - { - hasBeenSaved = true; - break; - } - } - } - - //Send opcode SMSG_UPDATE_INSTANCE_OWNERSHIP. true or false means, whether you have current raid/heroic instances - data.Initialize(SMSG_UPDATE_INSTANCE_OWNERSHIP, 4); - data << uint32(hasBeenSaved); - GetSession()->SendPacket(&data); - - if (!hasBeenSaved) - return; - - for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) - { - for (BoundInstancesMap::iterator itr = m_boundInstances[i].begin(); itr != m_boundInstances[i].end(); ++itr) - { - if (itr->second.perm) - { - data.Initialize(SMSG_UPDATE_LAST_INSTANCE, 4); - data << uint32(itr->second.save->GetMapId()); - GetSession()->SendPacket(&data); - } - } - } -} - /// convert the player's binds to the group void Player::ConvertInstancesToGroup(Player* player, Group* group, bool switchLeader) { diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index d61b7845abf..439a19ecbdf 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -918,7 +918,8 @@ enum TeleportToOptions TELE_TO_NOT_LEAVE_TRANSPORT = 0x02, TELE_TO_NOT_LEAVE_COMBAT = 0x04, TELE_TO_NOT_UNSUMMON_PET = 0x08, - TELE_TO_SPELL = 0x10 + TELE_TO_SPELL = 0x10, + TELE_TO_SEAMLESS = 0x20 }; /// Type of environmental damages @@ -2188,6 +2189,7 @@ class Player : public Unit, public GridObject<Player> bool IsBeingTeleported() const { return mSemaphoreTeleport_Near || mSemaphoreTeleport_Far; } bool IsBeingTeleportedNear() const { return mSemaphoreTeleport_Near; } bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; } + bool IsBeingTeleportedSeamlessly() const { return IsBeingTeleportedFar() && m_teleport_options & TELE_TO_SEAMLESS; } void SetSemaphoreTeleportNear(bool semphsetting) { mSemaphoreTeleport_Near = semphsetting; } void SetSemaphoreTeleportFar(bool semphsetting) { mSemaphoreTeleport_Far = semphsetting; } void ProcessDelayedOperations(); @@ -2493,7 +2495,6 @@ class Player : public Unit, public GridObject<Player> void SetPendingBind(uint32 instanceId, uint32 bindTimer); bool HasPendingBind() const { return _pendingBindId > 0; } void SendRaidInfo(); - void SendSavedInstances(); static void ConvertInstancesToGroup(Player* player, Group* group, bool switchLeader); bool Satisfy(AccessRequirement const* ar, uint32 target_map, bool report = false); bool CheckInstanceLoginValid(); diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 3835a0642f9..0cedc1b239c 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -46,6 +46,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() if (!GetPlayer()->IsBeingTeleportedFar()) return; + bool seamlessTeleport = GetPlayer()->IsBeingTeleportedSeamlessly(); GetPlayer()->SetSemaphoreTeleportFar(false); // get the teleport destination @@ -88,13 +89,16 @@ void WorldSession::HandleMoveWorldportAckOpcode() float z = loc.GetPositionZ(); if (GetPlayer()->HasUnitMovementFlag(MOVEMENTFLAG_HOVER)) z += GetPlayer()->GetFloatValue(UNIT_FIELD_HOVERHEIGHT); + GetPlayer()->Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation()); GetPlayer()->ResetMap(); GetPlayer()->SetMap(newMap); - GetPlayer()->SendInitialPacketsBeforeAddToMap(); - if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer())) + if (!seamlessTeleport) + GetPlayer()->SendInitialPacketsBeforeAddToMap(); + + if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer(), !seamlessTeleport)) { TC_LOG_ERROR("network", "WORLD: failed to teleport player %s (%s) to map %d (%s) because of unknown reason!", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str(), loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown"); @@ -124,16 +128,22 @@ void WorldSession::HandleMoveWorldportAckOpcode() } } - GetPlayer()->SendInitialPacketsAfterAddToMap(); + if (!seamlessTeleport) + GetPlayer()->SendInitialPacketsAfterAddToMap(); + else + GetPlayer()->UpdateVisibilityForPlayer(); // flight fast teleport case if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { if (!_player->InBattleground()) { - // short preparations to continue flight - FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); - flight->Initialize(GetPlayer()); + if (!seamlessTeleport) + { + // short preparations to continue flight + FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); + flight->Initialize(GetPlayer()); + } return; } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index ebfdaaf3b73..44517427e0a 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -473,7 +473,7 @@ void Map::LoadGrid(float x, float y) EnsureGridLoaded(Cell(x, y)); } -bool Map::AddPlayerToMap(Player* player) +bool Map::AddPlayerToMap(Player* player, bool initPlayer /*= true*/) { CellCoord cellCoord = Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY()); if (!cellCoord.IsCoordValid()) @@ -491,7 +491,9 @@ bool Map::AddPlayerToMap(Player* player) player->SetMap(this); player->AddToWorld(); - SendInitSelf(player); + if (initPlayer) + SendInitSelf(player); + SendInitTransports(player); SendZoneDynamicInfo(player); @@ -2955,7 +2957,7 @@ bool InstanceMap::CanEnter(Player* player) /* Do map specific checks and add the player to the map if successful. */ -bool InstanceMap::AddPlayerToMap(Player* player) +bool InstanceMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/) { /// @todo Not sure about checking player level: already done in HandleAreaTriggerOpcode // GMs still can teleport player in instance. @@ -3065,7 +3067,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) } // this will acquire the same mutex so it cannot be in the previous block - Map::AddPlayerToMap(player); + Map::AddPlayerToMap(player, initPlayer); if (i_data) i_data->OnPlayerEnter(player); @@ -3323,7 +3325,7 @@ bool BattlegroundMap::CanEnter(Player* player) return Map::CanEnter(player); } -bool BattlegroundMap::AddPlayerToMap(Player* player) +bool BattlegroundMap::AddPlayerToMap(Player* player, bool initPlayer /*= true*/) { { std::lock_guard<std::mutex> lock(_mapLock); @@ -3333,7 +3335,7 @@ bool BattlegroundMap::AddPlayerToMap(Player* player) // reset instance validity, battleground maps do not homebind player->m_InstanceValid = true; } - return Map::AddPlayerToMap(player); + return Map::AddPlayerToMap(player, initPlayer); } void BattlegroundMap::RemovePlayerFromMap(Player* player, bool remove) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 1394808b2cc..02a8292777a 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -274,7 +274,7 @@ class Map : public GridRefManager<NGridType> return false; } - virtual bool AddPlayerToMap(Player*); + virtual bool AddPlayerToMap(Player* player, bool initPlayer = true); virtual void RemovePlayerFromMap(Player*, bool); template<class T> bool AddToMap(T *); template<class T> void RemoveFromMap(T *, bool); @@ -725,7 +725,7 @@ class InstanceMap : public Map public: InstanceMap(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent); ~InstanceMap(); - bool AddPlayerToMap(Player*) override; + bool AddPlayerToMap(Player* player, bool initPlayer = true) override; void RemovePlayerFromMap(Player*, bool) override; void Update(const uint32) override; void CreateInstanceData(bool load); @@ -755,7 +755,7 @@ class BattlegroundMap : public Map BattlegroundMap(uint32 id, time_t, uint32 InstanceId, Map* _parent, uint8 spawnMode); ~BattlegroundMap(); - bool AddPlayerToMap(Player*) override; + bool AddPlayerToMap(Player* player, bool initPlayer = true) override; void RemovePlayerFromMap(Player*, bool) override; bool CanEnter(Player* player) override; void SetUnload(); diff --git a/src/server/game/Server/Packets/InstancePackets.cpp b/src/server/game/Server/Packets/InstancePackets.cpp new file mode 100644 index 00000000000..50b2a66a8b8 --- /dev/null +++ b/src/server/game/Server/Packets/InstancePackets.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "InstancePackets.h" + +WorldPacket const* WorldPackets::Instance::UpdateLastInstance::Write() +{ + _worldPacket << uint32(MapID); + + return &_worldPacket; +} + +WorldPacket const* WorldPackets::Instance::UpdateInstanceOwnership::Write() +{ + _worldPacket << int32(IOwnInstance); + + return &_worldPacket; +} diff --git a/src/server/game/Server/Packets/InstancePackets.h b/src/server/game/Server/Packets/InstancePackets.h new file mode 100644 index 00000000000..09f6c1efdcb --- /dev/null +++ b/src/server/game/Server/Packets/InstancePackets.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef InstancePackets_h__ +#define InstancePackets_h__ + +#include "Packet.h" +#include "ObjectGuid.h" + +namespace WorldPackets +{ + namespace Instance + { + class UpdateLastInstance final : public ServerPacket + { + public: + UpdateLastInstance() : ServerPacket(SMSG_UPDATE_LAST_INSTANCE, 4) { } + + WorldPacket const* Write() override; + + uint32 MapID = 0; + }; + + // This packet is no longer sent - it is only here for documentation purposes + class UpdateInstanceOwnership final : public ServerPacket + { + public: + UpdateInstanceOwnership() : ServerPacket(SMSG_UPDATE_INSTANCE_OWNERSHIP, 4) { } + + WorldPacket const* Write() override; + + int32 IOwnInstance = 0; // Used to control whether "Reset all instances" button appears on the UI - Script_CanShowResetInstances() + // but it has been deperecated in favor of simply checking group leader, being inside an instance or using dungeon finder + }; + } +} + +#endif // InstancePackets_h__ diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 7805ea84147..82af7f986f6 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -23,8 +23,8 @@ #include "Packets/BankPackets.h" #include "Packets/BattlegroundPackets.h" #include "Packets/BlackMarketPackets.h" -#include "Packets/CharacterPackets.h" #include "Packets/ChannelPackets.h" +#include "Packets/CharacterPackets.h" #include "Packets/ChatPackets.h" #include "Packets/ClientConfigPackets.h" #include "Packets/CombatPackets.h" @@ -33,6 +33,7 @@ #include "Packets/GameObjectPackets.h" #include "Packets/GuildPackets.h" #include "Packets/InspectPackets.h" +#include "Packets/InstancePackets.h" #include "Packets/ItemPackets.h" #include "Packets/LootPackets.h" #include "Packets/MailPackets.h" @@ -47,9 +48,9 @@ #include "Packets/ScenePackets.h" #include "Packets/SocialPackets.h" #include "Packets/TalentPackets.h" +#include "Packets/TicketPackets.h" #include "Packets/TokenPackets.h" #include "Packets/TradePackets.h" -#include "Packets/TicketPackets.h" #include "Packets/VehiclePackets.h" #include "Packets/VoidStoragePackets.h" #include "Packets/WhoPackets.h" @@ -1709,8 +1710,8 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CHARACTER_FLAGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_EXPANSION_LEVEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_NEVER, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_TALENT_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index db4ec66ea00..fa557616450 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -322,6 +322,10 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) if (IsConnectionIdle()) m_Socket[CONNECTION_TYPE_REALM]->CloseSocket(); + if (updater.ProcessUnsafe()) + while (_player && _player->IsBeingTeleportedSeamlessly()) + HandleMoveWorldportAckOpcode(); + ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed WorldPacket* packet = NULL; @@ -453,7 +457,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) //check if we are safe to proceed with logout //logout procedure should happen only in World::UpdateSessions() method!!! - if (updater.ProcessLogout()) + if (updater.ProcessUnsafe()) { time_t currTime = time(NULL); ///- If necessary, log the player out diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index a506c050181..a4b268dc6b9 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -638,8 +638,8 @@ public: explicit PacketFilter(WorldSession* pSession) : m_pSession(pSession) { } virtual ~PacketFilter() { } - virtual bool Process(WorldPacket* /*packet*/) { return true; } - virtual bool ProcessLogout() const { return true; } + virtual bool Process(WorldPacket* /*packet*/) = 0; + virtual bool ProcessUnsafe() const { return false; } protected: WorldSession* const m_pSession; @@ -656,9 +656,7 @@ public: explicit MapSessionFilter(WorldSession* pSession) : PacketFilter(pSession) { } ~MapSessionFilter() { } - virtual bool Process(WorldPacket* packet) override; - //in Map::Update() we do not process player logout! - virtual bool ProcessLogout() const override { return false; } + bool Process(WorldPacket* packet) override; }; //class used to filer only thread-unsafe packets from queue @@ -669,7 +667,8 @@ public: explicit WorldSessionFilter(WorldSession* pSession) : PacketFilter(pSession) { } ~WorldSessionFilter() { } - virtual bool Process(WorldPacket* packet) override; + bool Process(WorldPacket* packet) override; + bool ProcessUnsafe() const override { return true; } }; struct PacketCounter |