mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[8850] Check packet opcode for >= NUM_MSG_TYPES before queueing.
Also add check for wrong packet status requirement in code.
This commit is contained in:
parent
ab62a11d4e
commit
0011a41003
3 changed files with 86 additions and 83 deletions
|
|
@ -169,97 +169,93 @@ bool WorldSession::Update(uint32 /*diff*/)
|
|||
packet->GetOpcode());
|
||||
#endif*/
|
||||
|
||||
if(packet->GetOpcode() >= NUM_MSG_TYPES)
|
||||
OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];
|
||||
try
|
||||
{
|
||||
sLog.outError( "SESSION: received non-existed opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
}
|
||||
else
|
||||
{
|
||||
OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()];
|
||||
try
|
||||
switch (opHandle.status)
|
||||
{
|
||||
switch (opHandle.status)
|
||||
{
|
||||
case STATUS_LOGGEDIN:
|
||||
if(!_player)
|
||||
{
|
||||
// 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");
|
||||
}
|
||||
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_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
|
||||
if(!_player && !m_playerRecentlyLogout)
|
||||
{
|
||||
LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout");
|
||||
}
|
||||
else
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_TRANSFER:
|
||||
if(!_player)
|
||||
case STATUS_LOGGEDIN:
|
||||
if(!_player)
|
||||
{
|
||||
// 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");
|
||||
else if(_player->IsInWorld())
|
||||
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");
|
||||
break;
|
||||
}
|
||||
|
||||
// single from authed time opcodes send in to after logout time
|
||||
// and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
|
||||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||
m_playerRecentlyLogout = false;
|
||||
|
||||
}
|
||||
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_LOGGEDIN_OR_RECENTLY_LOGGEDOUT:
|
||||
if(!_player && !m_playerRecentlyLogout)
|
||||
{
|
||||
LogUnexpectedOpcode(packet, "the player has not logged in yet and not recently logout");
|
||||
}
|
||||
else
|
||||
{
|
||||
// not expected _player or must checked in packet hanlder
|
||||
(this->*opHandle.handler)(*packet);
|
||||
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
|
||||
LogUnprocessedTail(packet);
|
||||
}
|
||||
break;
|
||||
case STATUS_TRANSFER:
|
||||
if(!_player)
|
||||
LogUnexpectedOpcode(packet, "the player has not logged in yet");
|
||||
else if(_player->IsInWorld())
|
||||
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");
|
||||
break;
|
||||
case STATUS_NEVER:
|
||||
sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
break;
|
||||
case STATUS_UNHANDLED:
|
||||
sLog.outDebug("SESSION: received not handled opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// single from authed time opcodes send in to after logout time
|
||||
// and before other STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes.
|
||||
if (packet->GetOpcode() != CMSG_SET_ACTIVE_VOICE_CHANNEL)
|
||||
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)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
break;
|
||||
case STATUS_UNHANDLED:
|
||||
sLog.outDebug("SESSION: received not handled opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
break;
|
||||
default:
|
||||
sLog.outError("SESSION: received wrong-status-req opcode %s (0x%.4X)",
|
||||
LookupOpcodeName(packet->GetOpcode()),
|
||||
packet->GetOpcode());
|
||||
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());
|
||||
if(sLog.IsOutDebug())
|
||||
{
|
||||
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());
|
||||
if(sLog.IsOutDebug())
|
||||
{
|
||||
sLog.outDebug("Dumping error causing packet:");
|
||||
packet->hexlike();
|
||||
}
|
||||
sLog.outDebug("Dumping error causing packet:");
|
||||
packet->hexlike();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue