diff options
Diffstat (limited to 'src/game/WorldSession.cpp')
-rw-r--r-- | src/game/WorldSession.cpp | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 2c4476199ef..6b4653c4263 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -179,44 +179,57 @@ bool WorldSession::Update(uint32 /*diff*/) else { OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()]; - switch (opHandle.status) + try { - 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) + 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); + // 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"); - } - else if(_player->IsInWorld()) - (this->*opHandle.handler)(*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"); - else if(_player->IsInWorld()) - logUnexpectedOpcode(packet, "the player is still in world"); - else + else if(_player->IsInWorld()) + logUnexpectedOpcode(packet, "the player is still in world"); + else + (this->*opHandle.handler)(*packet); + break; + case STATUS_AUTHED: + // prevent cheating with skip queue wait + if(m_inQueue) + { + logUnexpectedOpcode(packet, "the player not pass queue yet"); + break; + } + + m_playerRecentlyLogout = false; (this->*opHandle.handler)(*packet); - break; - case STATUS_AUTHED: - // prevent cheating with skip queue wait - if(m_inQueue) - { - logUnexpectedOpcode(packet, "the player not pass queue yet"); break; - } - - m_playerRecentlyLogout = false; - (this->*opHandle.handler)(*packet); - break; - case STATUS_NEVER: - break; - sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)", - LookupOpcodeName(packet->GetOpcode()), - packet->GetOpcode()); - break; + case STATUS_NEVER: + break; + sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)", + LookupOpcodeName(packet->GetOpcode()), + packet->GetOpcode()); + break; + } + } + catch(ByteBufferException &exception) + { + 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(); + } } } @@ -630,7 +643,6 @@ void WorldSession::SaveTutorialsData() void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) { - CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4); data >> mi->flags; data >> mi->unk1; data >> mi->time; @@ -644,7 +656,6 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) if(!data.readPackGUID(mi->t_guid)) return; - CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4+4+1); data >> mi->t_x; data >> mi->t_y; data >> mi->t_z; @@ -655,16 +666,13 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->unk1 & 0x20)) { - CHECK_PACKET_SIZE(data, data.rpos()+4); data >> mi->s_pitch; } - CHECK_PACKET_SIZE(data, data.rpos()+4); data >> mi->fallTime; if(mi->flags & MOVEMENTFLAG_JUMPING) { - CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4); data >> mi->j_zspeed; data >> mi->j_sinAngle; data >> mi->j_cosAngle; @@ -673,7 +681,6 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) if(mi->flags & MOVEMENTFLAG_SPLINE) { - CHECK_PACKET_SIZE(data, data.rpos()+4); data >> mi->u_unk1; } } @@ -688,6 +695,12 @@ void WorldSession::ReadAddonsInfo(WorldPacket &data) if(!size) return; + if(size > 0xFFFFF) + { + sLog.outError("WorldSession::ReadAddonsInfo addon info too big, size %u", size); + return; + } + uLongf uSize = size; uint32 pos = data.rpos(); @@ -712,10 +725,6 @@ void WorldSession::ReadAddonsInfo(WorldPacket &data) addonInfo >> addonName; - // recheck next addon data format correctness - if(addonInfo.rpos()+1+4+4 > addonInfo.size()) - return; - addonInfo >> enabled >> crc >> unk1; sLog.outDebug("ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk1); |