mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-02-14 05:59:29 +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);
|
_charLoginCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
|
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
|
||||||
{
|
{
|
||||||
uint64 playerGuid = holder->GetGuid();
|
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
|
///- Retrieve packets from the receive queue and call the appropriate handlers
|
||||||
/// not process packets if socket already closed
|
/// not process packets if socket already closed
|
||||||
WorldPacket* packet = NULL;
|
WorldPacket* packet = NULL;
|
||||||
|
//! Delete packet after processing by default
|
||||||
|
bool deletePacket = true;
|
||||||
while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater))
|
while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater))
|
||||||
{
|
{
|
||||||
if (packet->GetOpcode() >= NUM_MSG_TYPES)
|
if (packet->GetOpcode() >= NUM_MSG_TYPES)
|
||||||
@@ -240,8 +242,19 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
|||||||
if (!_player)
|
if (!_player)
|
||||||
{
|
{
|
||||||
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
|
// 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)
|
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())
|
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");
|
"the player has not logged in yet and not recently logout");
|
||||||
else
|
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));
|
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
|
||||||
(this->*opHandle.handler)(*packet);
|
(this->*opHandle.handler)(*packet);
|
||||||
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
if (sLog->IsOutDebug() && packet->rpos() < packet->wpos())
|
||||||
@@ -308,7 +321,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(ByteBufferException &)
|
catch (ByteBufferException &)
|
||||||
{
|
{
|
||||||
sLog->outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
|
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());
|
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
|
||||||
@@ -320,7 +333,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete packet;
|
if (deletePacket)
|
||||||
|
delete packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessQueryCallbacks();
|
ProcessQueryCallbacks();
|
||||||
@@ -344,6 +358,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
|||||||
if (!m_Socket)
|
if (!m_Socket)
|
||||||
return false; //Will remove this session from the world session map
|
return false; //Will remove this session from the world session map
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user