void WorldSession::HandleMoverRelocation(MovementInfo& movementInfo) { if (m_clientTimeDelay == 0) m_clientTimeDelay = WorldTimer::getMSTime() - movementInfo.GetTime(); movementInfo.UpdateTime(movementInfo.GetTime() + m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY); Unit* mover = _player->GetMover(); if (Player* plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : nullptr) { if (movementInfo.HasMovementFlag(MOVEFLAG_ONTRANSPORT)) { if (!plMover->m_transport) { // elevators also cause the client to send MOVEFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list for (MapManager::TransportSet::const_iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter) { if ((*iter)->GetObjectGuid() == movementInfo.GetTransportGuid()) { plMover->m_transport = (*iter); (*iter)->AddPassenger(plMover); break; } } } } else if (plMover->m_transport) // if we were on a transport, leave { plMover->m_transport->RemovePassenger(plMover); plMover->m_transport = nullptr; movementInfo.ClearTransportData(); } if (movementInfo.HasMovementFlag(MOVEFLAG_SWIMMING) != plMover->IsInWater()) { // now client not include swimming flag in case jumping under water plMover->SetInWater(!plMover->IsInWater() || plMover->GetTerrain()->IsUnderWater(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z)); } plMover->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o); plMover->m_movementInfo = movementInfo; if (movementInfo.GetPos()->z < -500.0f) { if (plMover->GetBattleGround() && plMover->GetBattleGround()->HandlePlayerUnderMap(_player)) { // do nothing, the handle already did if returned true } else { // NOTE: this is actually called many times while falling // even after the player has been teleported away // TODO: discard movement packets after the player is rooted if (plMover->isAlive()) { plMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, plMover->GetMaxHealth()); // pl can be alive if GM/etc if (!plMover->isAlive()) { // change the death state to CORPSE to prevent the death timer from // starting in the next player update plMover->KillPlayer(); plMover->BuildPlayerRepop(); } } // cancel the death timer here if started plMover->RepopAtGraveyard(); } } } else // creature charmed { if (mover->IsInWorld()) mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o); } }
void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) { DEBUG_LOG( "WORLD: Received CMSG_MOVE_SPLINE_DONE" ); ObjectGuid guid; // used only for proper packet read MovementInfo movementInfo; // used only for proper packet read recv_data >> guid.ReadAsPacked(); recv_data >> movementInfo; recv_data >> Unused<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) { //movement anticheat code GetPlayer()->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o); GetPlayer()->m_movementInfo = movementInfo; //GetPlayer()->SetUnitMovementFlags(movementInfo.moveFlags); //calc time deltas int32 cClientTimeDelta = 0; if (GetPlayer()->m_anti_LastClientTime !=0) { cClientTimeDelta = movementInfo.GetTime() - GetPlayer()->m_anti_LastClientTime; GetPlayer()->m_anti_DeltaClientTime += cClientTimeDelta; GetPlayer()->m_anti_LastClientTime = movementInfo.GetTime(); } else { GetPlayer()->m_anti_LastClientTime = movementInfo.GetTime(); } uint32 cServerTime = WorldTimer::getMSTime(); uint32 cServerTimeDelta = 0; if (GetPlayer()->m_anti_LastServerTime != 0) { cServerTimeDelta = cServerTime - GetPlayer()->m_anti_LastServerTime; GetPlayer()->m_anti_DeltaServerTime += cServerTimeDelta; GetPlayer()->m_anti_LastServerTime = cServerTime; } else { GetPlayer()->m_anti_LastServerTime = cServerTime; } GetPlayer()->m_anti_JustTeleported = true; //end movement anticheat return; } //movment anticheat uint32 curloc = sObjectMgr.GetNearestTaxiNode(movementInfo.GetPos()->x,movementInfo.GetPos()->y,movementInfo.GetPos()->z, GetPlayer()->GetMapId(),GetPlayer( )->GetTeam()); //end movement anticheat TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest); //movement anticheat code GetPlayer()->SetPosition(movementInfo.GetPos()->x, movementInfo.GetPos()->y, movementInfo.GetPos()->z, movementInfo.GetPos()->o); GetPlayer()->m_movementInfo = movementInfo; //GetPlayer()->SetUnitMovementFlags(movementInfo.moveFlags); //calc time deltas int32 cClientTimeDelta = 0; if (GetPlayer()->m_anti_LastClientTime !=0) { cClientTimeDelta = movementInfo.GetTime() - GetPlayer()->m_anti_LastClientTime; GetPlayer()->m_anti_DeltaClientTime += cClientTimeDelta; GetPlayer()->m_anti_LastClientTime = movementInfo.GetTime(); } else { GetPlayer()->m_anti_LastClientTime = movementInfo.GetTime(); } uint32 cServerTime = WorldTimer::getMSTime(); uint32 cServerTimeDelta = 0; if (GetPlayer()->m_anti_LastServerTime != 0) { cServerTimeDelta = cServerTime - GetPlayer()->m_anti_LastServerTime; GetPlayer()->m_anti_DeltaServerTime += cServerTimeDelta; GetPlayer()->m_anti_LastServerTime = cServerTime; } else { GetPlayer()->m_anti_LastServerTime = cServerTime; } //<< end movement anticheat // 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(); TaxiPathNodeEntry 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 ); } } DEBUG_LOG( "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 }