mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 16:38:42 +01:00
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
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user