/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 /*diff*/) { ///- Retrieve packets from the receive queue and call the appropriate handlers /// not proccess packets if socket already closed while (!_recvQueue.empty() && m_Socket && !m_Socket->IsClosed ()) { WorldPacket *packet = _recvQueue.next(); /*#if 1 sLog.outError( "MOEP: %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); #endif*/ if(packet->GetOpcode() >= NUM_MSG_TYPES) { sLog.outError( "SESSION: received non-existed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); } else { OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()]; 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_PENDING: 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); 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: sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; } } delete packet; } ///- Cleanup socket pointer if need if (m_Socket && m_Socket->IsClosed ()) { m_Socket->RemoveReference (); m_Socket = NULL; } ///- If necessary, log the player out time_t currTime = time(NULL); if (!m_Socket || (ShouldLogOut(currTime) && !m_playerLoading)) LogoutPlayer(true); if (!m_Socket) return false; //Will remove this session from the world session map return true; }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 /*diff*/) { if (m_Socket) if (m_Socket->IsClosed ()) { m_Socket->RemoveReference (); m_Socket = NULL; } WorldPacket *packet; ///- Retrieve packets from the receive queue and call the appropriate handlers /// \todo Is there a way to consolidate the OpcondeHandlerTable and the g_worldOpcodeNames to only maintain 1 list? /// answer : there is a way, but this is better, because it would use redundant RAM while (!_recvQueue.empty()) { packet = _recvQueue.next(); /*#if 1 sLog.outError( "MOEP: %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); #endif*/ if(packet->GetOpcode() >= NUM_MSG_TYPES) { sLog.outError( "SESSION: received non-existed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); } else { OpcodeHandler& opHandle = opcodeTable[packet->GetOpcode()]; 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_PENDING: 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); break; case STATUS_AUTHED: m_playerRecentlyLogout = false; (this->*opHandle.handler)(*packet); break; case STATUS_NEVER: sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)", LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode()); break; } } delete packet; } ///- If necessary, log the player out time_t currTime = time(NULL); if (!m_Socket || (ShouldLogOut(currTime) && !m_playerLoading)) LogoutPlayer(true); if (!m_Socket) return false; //Will remove this session from the world session map return true; }