aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMachiavelli <machiavelli.trinity@gmail.com>2011-12-16 15:36:03 +0100
committerMachiavelli <machiavelli.trinity@gmail.com>2011-12-16 15:36:03 +0100
commit829be0b82b2ecdb054e4059d0d2dc39f3df6ded6 (patch)
tree430e98e174a782458449a93671e66d0095e1f26e /src
parentdb8c10c7bfcf2bbd5d36d18f56f2279a29ef5b97 (diff)
Core/Netcode: Re-enqueue packets with STATUS_LOGGEDIN requirement that are sent before the server recognizes the player as logged in. They will be processed later.
Fixes #208 Fixes #1434 Fixes #2338
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/CharacterHandler.cpp2
-rwxr-xr-xsrc/server/game/Server/WorldSession.cpp23
2 files changed, 20 insertions, 5 deletions
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
index 3d33e506655..9ad07685900 100755
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
@@ -791,7 +791,7 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket & recv_data)
_charLoginCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder);
}
-void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
+void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
{
uint64 playerGuid = holder->GetGuid();
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 14c86286718..ceb3c5acc0f 100755
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -222,6 +222,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
///- Retrieve packets from the receive queue and call the appropriate handlers
/// not process packets if socket already closed
WorldPacket* packet = NULL;
+ //! Delete packet after processing by default
+ bool deletePacket = true;
while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater))
{
if (packet->GetOpcode() >= NUM_MSG_TYPES)
@@ -240,8 +242,19 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!_player)
{
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
+ //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize
+ //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
if (!m_playerRecentlyLogout)
- LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN", "the player has not logged in yet");
+ {
+ //! Because checking a bool is faster than reallocating memory
+ deletePacket = false;
+ //! Re-enqueue
+ QueuePacket(packet);
+ //! Log
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. "
+ "Player is currently not in world yet.", opHandle.name, packet->GetOpcode());
+ }
+
}
else if (_player->IsInWorld())
{
@@ -258,7 +271,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
"the player has not logged in yet and not recently logout");
else
{
- // not expected _player or must checked in packet hanlder
+ // not expected _player or must checked in packet handler
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
(this->*opHandle.handler)(*packet);
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
@@ -308,7 +321,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
}
- catch(ByteBufferException &)
+ catch (ByteBufferException &)
{
sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
@@ -320,7 +333,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
}
}
- delete packet;
+ if (deletePacket)
+ delete packet;
}
ProcessQueryCallbacks();
@@ -344,6 +358,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!m_Socket)
return false; //Will remove this session from the world session map
}
+
return true;
}