/* This function handles the packet sent from the client when we leave a vehicle, it removes us server side from our current vehicle*/ void WorldSession::HandleVehicleDismiss(WorldPacket & recv_data) { if(GetPlayer() == NULL || !GetPlayer()->m_CurrentVehicle) return; if(recv_data.rpos() != recv_data.wpos()) HandleMovementOpcodes(recv_data); GetPlayer()->m_CurrentVehicle->RemovePassenger(GetPlayer()); }
void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) { DEBUG_LOG("WORLD: Received CMSG_MOVE_SPLINE_DONE"); MovementInfo movementInfo; // used only for proper packet read recv_data >> movementInfo; recv_data >> Unused<uint32>(); // unk recv_data >> Unused<uint32>(); // unk2 // Forward packet to near players recv_data.SetOpcode(MSG_MOVE_STOP); recv_data.rpos(0); HandleMovementOpcodes(recv_data); }
void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets& targets) { // some spell cast packet including more data (for projectiles?) if (castFlags & 0x02) { // not sure about these two float elevation, speed; recvPacket >> elevation; recvPacket >> speed; targets.SetElevation(elevation); targets.SetSpeed(speed); uint8 hasMovementData; recvPacket >> hasMovementData; if (hasMovementData) HandleMovementOpcodes(recvPacket); }
/// Update the WorldSession (triggered by World update) bool WorldSession::Update(uint32 diff, PacketFilter& updater) { if (updater.ProcessLogout()) { UpdateTimeOutTime(diff); if (IsConnectionIdle()) m_Socket->CloseSocket(); } HandleTeleportTimeout(updater.ProcessLogout()); uint32 _startMSTime = getMSTime(); WorldPacket* packet = NULL; WorldPacket* movementPacket = NULL; bool deletePacket = true; WorldPacket* firstDelayedPacket = NULL; uint32 processedPackets = 0; while (m_Socket && !m_Socket->IsClosed() && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) { if (packet->GetOpcode() < NUM_MSG_TYPES) { OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()]; try { switch (opHandle.status) { case STATUS_LOGGEDIN: if (!_player) { // pussywizard: such packets were sent to do something for a character that has already logged out, skip them } else if (!_player->IsInWorld()) { // pussywizard: such packets may do something important and the player is just being teleported, move to the end of the queue // pussywizard: previously such were skipped, so leave it as it is xD proper code below if we wish to change that // pussywizard: requeue only important packets not related to maps (PROCESS_THREADUNSAFE) /*if (opHandle.packetProcessing == PROCESS_THREADUNSAFE) { if (!firstDelayedPacket) firstDelayedPacket = packet; deletePacket = false; QueuePacket(packet); }*/ } else { if (opHandle.isGrouppedMovementOpcode) { if (movementPacket) delete movementPacket; movementPacket = new WorldPacket(packet->GetOpcode(), 0); movementPacket->append(*((ByteBuffer*)packet)); } else { if (movementPacket) { HandleMovementOpcodes(*movementPacket); delete movementPacket; movementPacket = NULL; } sScriptMgr->OnPacketReceive(this, *packet); #ifdef ELUNA if (!sEluna->OnPacketReceive(this, *packet)) break; #endif (this->*opHandle.handler)(*packet); } } break; case STATUS_TRANSFER: if (_player && !_player->IsInWorld()) { if (movementPacket) { delete movementPacket; movementPacket = NULL; } sScriptMgr->OnPacketReceive(this, *packet); #ifdef ELUNA if (!sEluna->OnPacketReceive(this, *packet)) break; #endif (this->*opHandle.handler)(*packet); } break; case STATUS_AUTHED: if (m_inQueue) // prevent cheating break; sScriptMgr->OnPacketReceive(this, *packet); #ifdef ELUNA if (!sEluna->OnPacketReceive(this, *packet)) break; #endif (this->*opHandle.handler)(*packet); break; case STATUS_NEVER: break; case STATUS_UNHANDLED: break; } } 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->outDebug(LOG_FILTER_NETWORKIO, "Dumping error causing packet:"); packet->hexlike(); } } } if (deletePacket) delete packet; else deletePacket = true; if (++processedPackets >= 150) // limit (by count) packets processed in one update, prevent DDoS break; if (getMSTimeDiff(_startMSTime, getMSTime()) >= 3) // limit (by time) packets processed in one update, prevent DDoS break; } if (movementPacket) { if (_player && _player->IsInWorld()) HandleMovementOpcodes(*movementPacket); delete movementPacket; } if (m_Socket && !m_Socket->IsClosed()) ProcessQueryCallbacks(); if (updater.ProcessLogout()) { time_t currTime = time(NULL); if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); if (m_Socket && !m_Socket->IsClosed() && _warden) _warden->Update(); if (m_Socket && m_Socket->IsClosed()) { m_Socket->RemoveReference(); m_Socket = NULL; } if (!m_Socket) return false; } return true; }