aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp29
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp30
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp23
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h32
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp6
-rw-r--r--src/server/game/Server/WorldSession.cpp4
-rw-r--r--src/server/game/Server/WorldSession.h2
7 files changed, 103 insertions, 23 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 4499d5473fb..1dd3f63097a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -1220,7 +1220,7 @@ void Player::Update(uint32 p_time)
m_zoneUpdateTimer -= p_time;
}
- if (m_timeSyncTimer > 0)
+ if (m_timeSyncTimer > 0 && !IsBeingTeleportedFar())
{
if (p_time >= m_timeSyncTimer)
SendTimeSync();
@@ -1635,18 +1635,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
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 = static_cast<Position>(m_teleport_dest);
- packet.Reason = !(options & TELE_TO_SEAMLESS) ? NEW_WORLD_NORMAL : NEW_WORLD_SEAMLESS;
- SendDirectMessage(packet.Write());
+ WorldPackets::Movement::SuspendToken suspendToken;
+ suspendToken.SequenceIndex = m_movementCounter; // not incrementing
+ suspendToken.Reason = options & TELE_TO_SEAMLESS ? 2 : 1;
+ SendDirectMessage(suspendToken.Write());
}
// move packet sent by client always after far teleport
@@ -22222,6 +22214,14 @@ void Player::SetGroup(Group* group, int8 subgroup)
void Player::SendInitialPacketsBeforeAddToMap()
{
+ if (!(m_teleport_options & TELE_TO_SEAMLESS))
+ {
+ m_movementCounter = 0;
+ ResetTimeSync();
+ }
+
+ SendTimeSync();
+
/// Pass 'this' as argument because we're not stored in ObjectAccessor yet
GetSocial()->SendSocialList(this, SOCIAL_FLAG_ALL);
@@ -22313,9 +22313,6 @@ void Player::SendInitialPacketsAfterAddToMap()
GetZoneAndAreaId(newzone, newarea);
UpdateZone(newzone, newarea); // also call SendInitWorldStates();
- ResetTimeSync();
- SendTimeSync();
-
GetSession()->SendLoadCUFProfiles();
CastSpell(this, 836, true); // LOGINEFFECT
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 6464dd1838a..d8943099a93 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -31,6 +31,7 @@
#include "InstanceSaveMgr.h"
#include "ObjectMgr.h"
#include "Vehicle.h"
+#include "InstancePackets.h"
#include "MovementPackets.h"
#define MOVEMENT_PACKET_TIME_DELAY 0
@@ -95,6 +96,11 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->ResetMap();
GetPlayer()->SetMap(newMap);
+ WorldPackets::Movement::ResumeToken resumeToken;
+ resumeToken.SequenceIndex = _player->m_movementCounter;
+ resumeToken.Reason = seamlessTeleport ? 2 : 1;
+ SendPacket(resumeToken.Write());
+
if (!seamlessTeleport)
GetPlayer()->SendInitialPacketsBeforeAddToMap();
@@ -214,6 +220,30 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->ProcessDelayedOperations();
}
+void WorldSession::HandleSuspendTokenResponse(WorldPackets::Movement::SuspendTokenResponse& /*suspendTokenResponse*/)
+{
+ if (!_player->IsBeingTeleportedFar())
+ return;
+
+ WorldLocation const& loc = GetPlayer()->GetTeleportDest();
+
+ if (sMapStore.AssertEntry(loc.GetMapId())->IsDungeon())
+ {
+ WorldPackets::Instance::UpdateLastInstance updateLastInstance;
+ updateLastInstance.MapID = loc.GetMapId();
+ SendPacket(updateLastInstance.Write());
+ }
+
+ WorldPackets::Movement::NewWorld packet;
+ packet.MapID = loc.GetMapId();
+ packet.Pos.Relocate(loc);
+ packet.Reason = !_player->IsBeingTeleportedSeamlessly() ? NEW_WORLD_NORMAL : NEW_WORLD_SEAMLESS;
+ SendPacket(packet.Write());
+
+ if (_player->IsBeingTeleportedSeamlessly())
+ HandleMoveWorldportAckOpcode();
+}
+
void WorldSession::HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck& packet)
{
TC_LOG_DEBUG("network", "CMSG_MOVE_TELEPORT_ACK: Guid: %s, Sequence: %u, Time: %u", packet.MoverGUID.ToString().c_str(), packet.AckIndex, packet.MoveTime);
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 582a057e09f..6fdad7553a3 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -715,3 +715,26 @@ WorldPacket const* WorldPackets::Movement::SummonRequest::Write()
return &_worldPacket;
}
+
+WorldPacket const* WorldPackets::Movement::SuspendToken::Write()
+{
+ _worldPacket << uint32(SequenceIndex);
+ _worldPacket.WriteBits(Reason, 2);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Movement::SuspendTokenResponse::Read()
+{
+ _worldPacket >> SequenceIndex;
+}
+
+WorldPacket const* WorldPackets::Movement::ResumeToken::Write()
+{
+ _worldPacket << uint32(SequenceIndex);
+ _worldPacket.WriteBits(Reason, 2);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index 6d97161d9c9..3bce8ed665c 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -461,6 +461,38 @@ namespace WorldPackets
int32 AreaID = 0;
bool SkipStartingArea = false;
};
+
+ class SuspendToken final : public ServerPacket
+ {
+ public:
+ SuspendToken() : ServerPacket(SMSG_SUSPEND_TOKEN, 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 SequenceIndex = 1;
+ uint32 Reason = 1;
+ };
+
+ class SuspendTokenResponse final : public ClientPacket
+ {
+ public:
+ SuspendTokenResponse(WorldPacket&& packet) : ClientPacket(CMSG_SUSPEND_TOKEN_RESPONSE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 SequenceIndex = 0;
+ };
+
+ class ResumeToken final : public ServerPacket
+ {
+ public:
+ ResumeToken() : ServerPacket(SMSG_RESUME_TOKEN, 4 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 SequenceIndex = 1;
+ uint32 Reason = 1;
+ };
}
ByteBuffer& operator<<(ByteBuffer& data, Movement::MonsterSplineFilterKey const& monsterSplineFilterKey);
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 7dd7b2dc3e9..a2e4bfe6321 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -732,7 +732,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_SUPPORT_TICKET_SUBMIT_COMPLAINT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::SupportTicketSubmitComplaint, &WorldSession::HandleSupportTicketSubmitComplaint);
DEFINE_HANDLER(CMSG_SUPPORT_TICKET_SUBMIT_SUGGESTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Ticket::SupportTicketSubmitSuggestion, &WorldSession::HandleSupportTicketSubmitSuggestion);
DEFINE_HANDLER(CMSG_SUSPEND_COMMS_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
- DEFINE_HANDLER(CMSG_SUSPEND_TOKEN_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_SUSPEND_TOKEN_RESPONSE, STATUS_TRANSFER, PROCESS_THREADUNSAFE, WorldPackets::Movement::SuspendTokenResponse, &WorldSession::HandleSuspendTokenResponse);
DEFINE_HANDLER(CMSG_SWAP_INV_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapInvItem, &WorldSession::HandleSwapInvItemOpcode);
DEFINE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::SwapItem, &WorldSession::HandleSwapItem);
DEFINE_HANDLER(CMSG_SWAP_SUB_GROUPS, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Party::SwapSubGroups, &WorldSession::HandleSwapSubGroupsOpcode);
@@ -1534,7 +1534,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_CAST_BAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_COMMS, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_TOKEN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_CHANGED_INFORM, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1641,7 +1641,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPERCEDED_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TAXI_NODE_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 59f18bc79b0..8e1a912623e 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -336,10 +336,6 @@ 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;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index b65a8b30d56..26e8329ee9c 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -442,6 +442,7 @@ namespace WorldPackets
class MoveTimeSkipped;
class SummonResponse;
class MoveSplineDone;
+ class SuspendTokenResponse;
}
namespace NPC
@@ -1243,6 +1244,7 @@ class TC_GAME_API WorldSession
void HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortResponse& packet);
void HandleMoveWorldportAckOpcode(); // for server-side calls
+ void HandleSuspendTokenResponse(WorldPackets::Movement::SuspendTokenResponse& suspendTokenResponse);
void HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMovement& packet);
void HandleSetActiveMoverOpcode(WorldPackets::Movement::SetActiveMover& packet);