aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2015-05-01 15:44:43 +0200
committerShauren <shauren.trinity@gmail.com>2015-05-01 15:44:43 +0200
commit68bd33b6549563ac3b719c27aa16cc4ebd33890a (patch)
treef3b12dbac650877fcc2f5cfa3ab714d1de44ddea /src
parent522ae49c6a17e51826ad7f62d2588e0866eb2639 (diff)
Core/Player: Implemented seamless teleporting
Diffstat (limited to 'src')
-rw-r--r--src/server/game/DataStores/DBCStructure.h2
-rw-r--r--src/server/game/DataStores/DBCfmt.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp86
-rw-r--r--src/server/game/Entities/Player/Player.h5
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp22
-rw-r--r--src/server/game/Maps/Map.cpp14
-rw-r--r--src/server/game/Maps/Map.h6
-rw-r--r--src/server/game/Server/Packets/InstancePackets.cpp32
-rw-r--r--src/server/game/Server/Packets/InstancePackets.h52
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp9
-rw-r--r--src/server/game/Server/WorldSession.cpp6
-rw-r--r--src/server/game/Server/WorldSession.h11
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