void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) { sLog.outDebug( "WORLD: Received CMSG_MOVE_SPLINE_DONE" ); uint64 guid; // used only for proper packet read if(!recv_data.readPackGUID(guid)) return; MovementInfo movementInfo(recv_data); // used only for proper packet read recv_data.read_skip<uint32>(); // unk // in taxi flight packet received in 2 case: // 1) end taxi path in far (multi-node) flight // 2) switch from one map to other in case multi-map taxi path // we need process only (1) uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination(); if(!curDest) return; TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest); // far teleport case if(curDestNode && curDestNode->map_id != GetPlayer()->GetMapId()) { if(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE) { // short preparations to continue flight FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->Interrupt(*GetPlayer()); // will reset at map landing flight->SetCurrentNodeAfterTeleport(); Path::PathNode const& node = flight->GetPath()[flight->GetCurrentNode()]; flight->SkipCurrentNode(); GetPlayer()->TeleportTo(curDestNode->map_id,node.x,node.y,node.z,GetPlayer()->GetOrientation()); } return; } uint32 destinationnode = GetPlayer()->m_taxi.NextTaxiDestination(); if ( destinationnode > 0 ) // if more destinations to go { // current source node for next destination uint32 sourcenode = GetPlayer()->m_taxi.GetTaxiSource(); // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path) if (GetPlayer()->isTaxiCheater()) { if(GetPlayer()->m_taxi.SetTaximaskNode(sourcenode)) { WorldPacket data(SMSG_NEW_TAXI_PATH, 0); _player->GetSession()->SendPacket( &data ); } } sLog.outDebug( "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode ); uint32 mountDisplayId = sObjectMgr.GetTaxiMountDisplayId(sourcenode, GetPlayer()->GetTeam()); uint32 path, cost; sObjectMgr.GetTaxiPath( sourcenode, destinationnode, path, cost); if(path && mountDisplayId) SendDoFlight( mountDisplayId, path, 1 ); // skip start fly node else GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next } else GetPlayer()->m_taxi.ClearTaxiDestinations(); // not destinations, clear source node }
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { uint32 spellId; uint8 cast_count, unk_flags; recvPacket >> cast_count; recvPacket >> spellId; recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received) // ignore for remote control state (for player case) Unit* mover = _player->m_mover; if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } // vehicle spells are handled by CMSG_PET_CAST_SPELL, // but player is still able to cast own spells if(_player->GetCharmGUID() && _player->GetCharmGUID() == _player->GetVehicleGUID()) mover = _player; sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i", spellId, cast_count, unk_flags, (uint32)recvPacket.size()); SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); if(!spellInfo) { sLog.outError("WORLD: unknown spell id %u", spellId); recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } if(mover->GetTypeId()==TYPEID_PLAYER) { // not have spell in spellbook or spell passive and not casted by client if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(spellId) ) { sLog.outError("World: Player %u casts spell %u which he shouldn't have", mover->GetGUIDLow(), spellId); //cheater? kick? ban? recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } } else { // not have spell in spellbook or spell passive and not casted by client if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellId) ) { //cheater? kick? ban? recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } } // client provided targets SpellCastTargets targets; if(!targets.read(&recvPacket,mover)) { recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet return; } // some spell cast packet including more data (for projectiles?) if (unk_flags & 0x02) { recvPacket.read_skip<float>(); // unk1, coords? recvPacket.read_skip<float>(); // unk1, coords? uint8 unk1; recvPacket >> unk1; // >> 1 or 0 if(unk1) { recvPacket.read_skip<uint32>(); // >> MSG_MOVE_STOP uint64 guid; // guid - unused if(!recvPacket.readPackGUID(guid)) return; MovementInfo movementInfo(recvPacket); } }