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);
    }
}
Example #2
0
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
}