[8389] Implement check really read received packet size and warning it not all data read.

* This let more easy catch packet structure chnages at client switch.
* Fixed structure CMSG_GUILD_BANK_SWAP_ITEMS
* Fixed structure CMSG_SPLIT_ITEM, CMSG_SELL_ITEM
* Added read data amount fixes for some other packets.

Thanks to TOM_RUS in help check correct packets structure.

Note: not all packets possible fixed. Please report for not fixed cases at errors:
"opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)"
This commit is contained in:
VladimirMangos 2009-08-18 23:11:11 +04:00
parent 17b94e1e09
commit 35121cdd34
12 changed files with 82 additions and 41 deletions

View file

@ -141,7 +141,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet)
}
/// Logging helper for unexpected opcodes
void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason)
void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char *reason)
{
sLog.outError( "SESSION: received unexpected opcode %s (0x%.4X) %s",
LookupOpcodeName(packet->GetOpcode()),
@ -149,6 +149,15 @@ void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason)
reason);
}
/// Logging helper for unexpected opcodes
void WorldSession::LogUnprocessedTail(WorldPacket *packet)
{
sLog.outError( "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
LookupOpcodeName(packet->GetOpcode()),
packet->GetOpcode(),
packet->rpos(),packet->wpos());
}
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(uint32 /*diff*/)
{
@ -182,30 +191,40 @@ bool WorldSession::Update(uint32 /*diff*/)
{
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
if(!m_playerRecentlyLogout)
logUnexpectedOpcode(packet, "the player has not logged in yet");
LogUnexpectedOpcode(packet, "the player has not logged in yet");
}
else if(_player->IsInWorld())
{
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
}
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
break;
case STATUS_TRANSFER:
if(!_player)
logUnexpectedOpcode(packet, "the player has not logged in yet");
LogUnexpectedOpcode(packet, "the player has not logged in yet");
else if(_player->IsInWorld())
logUnexpectedOpcode(packet, "the player is still in world");
LogUnexpectedOpcode(packet, "the player is still in world");
else
{
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
}
break;
case STATUS_AUTHED:
// prevent cheating with skip queue wait
if(m_inQueue)
{
logUnexpectedOpcode(packet, "the player not pass queue yet");
LogUnexpectedOpcode(packet, "the player not pass queue yet");
break;
}
m_playerRecentlyLogout = false;
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
break;
case STATUS_NEVER:
sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)",
@ -214,7 +233,7 @@ bool WorldSession::Update(uint32 /*diff*/)
break;
}
}
catch(ByteBufferException &exception)
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());