예제 #1
0
void WorldSession::HandleDismissControlledVehicle(WorldPacket &recvData)
{
    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE");

    uint64 vehicleGUID = _player->GetCharmGUID();

    if (!vehicleGUID)                                       // something wrong here...
    {
        recvData.rfinish();                                // prevent warnings spam
        return;
    }

    MovementInfo mi;
    mi.ReadFromPacket(recvData);
    mi.Sanitize(_player);

    _player->m_movementInfo = mi;

    _player->ExitVehicle();
}
예제 #2
0
bool WorldSession::HandleMovementInfo(MovementInfo &movementInfo, const uint16 opcode, const size_t packSize, Unit *mover)
{
    ASSERT(mover != NULL);

    if (movementInfo.guid != mover->GetGUID() || !movementInfo.pos.IsPositionValid())
        return false;

    Player* plrMover = mover->ToPlayer();

    if (plrMover && plrMover->IsBeingTeleported())
        return false;

    if (plrMover && plrMover->HasUnitState(UNIT_STATE_CONTROLLED_BY_SERVER) && !CanMovementBeProcessed(opcode))
        return false;

    movementInfo.Sanitize(mover);

    if (movementInfo.t_guid)
    {
        if (movementInfo.t_pos.GetPositionX() > 50.0f || movementInfo.t_pos.GetPositionY() > 50.0f || movementInfo.t_pos.GetPositionZ() > 50.0f)
            return false; // moved out of transport size

        if (!Trinity::IsValidMapCoord(
                movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(),
                movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(),
                movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(),
                movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation())
            )
            return false; // just bad coords

        if (plrMover)
        {
            if (!plrMover->GetTransport()) // didn't have transport. now have
            {
                for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
                {
                    if ((*iter)->GetGUID() == movementInfo.t_guid)
                    {
                        plrMover->m_transport = *iter;
                        (*iter)->AddPassenger(plrMover);
                        break;
                    }
                }
            }
            else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid) // changes transport
            {
                bool foundNewTransport = false;
                plrMover->m_transport->RemovePassenger(plrMover);
                for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
                {
                    if ((*iter)->GetGUID() == movementInfo.t_guid)
                    {
                        foundNewTransport = true;
                        plrMover->m_transport = *iter;
                        (*iter)->AddPassenger(plrMover);
                        break;
                    }
                }

                if (!foundNewTransport)
                {
                    plrMover->m_transport = NULL;
                    movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
                    movementInfo.t_time = 0;
                    movementInfo.t_seat = -1;
                }
            }
            else if (movementInfo.pos.m_positionX != movementInfo.t_pos.m_positionX)
                plrMover->GetTransport()->UpdatePosition(&movementInfo);
        }

        if (!mover->GetTransport() && !mover->GetVehicle())
        {
            GameObject* go = mover->GetMap()->GetGameObject(movementInfo.t_guid);
            if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
                movementInfo.t_guid = 0;
        }
    }
    else if (plrMover && plrMover->GetTransport()) // had transport, no loger have
    {
        plrMover->m_transport->RemovePassenger(plrMover);
        plrMover->m_transport = NULL;
        movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
        movementInfo.t_time = 0;
        movementInfo.t_seat = -1;
    }

    if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->isInFlight())
        plrMover->HandleFall(movementInfo);

    if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
    {
        // now client not include swimming flag in case jumping under water
        plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
    }
	
	if (plrMover)
        sAnticheatMgr->StartHackDetection(plrMover, movementInfo, opcode);

    WorldPacket data(movementInfo.GetSMSGOpcodeForCMSG(Opcodes(opcode)), packSize);
    movementInfo.time = getMSTime();
    movementInfo.guid = mover->GetGUID();
    movementInfo.WriteToPacket(data);
    _player->SendMessageToSet(&data, _player);

    mover->m_movementInfo = movementInfo;

    if (mover->GetVehicle()) // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle()
    {
        mover->SetOrientation(movementInfo.pos.GetOrientation());
        return true;
    }

    // Remove pet when starting to fly
    if (plrMover && plrMover->IsFlying())
        plrMover->UnsummonPetTemporaryIfAny();

    mover->UpdatePosition(movementInfo.pos);

    if (plrMover)
    {
        plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
        float underMapValueZ, upperLimitValueZ;
        bool check = false;
        switch (plrMover->GetMapId())
        {
            case 617: // Dalaran Arena
                underMapValueZ = 3.0f;
                upperLimitValueZ = 30.0f;
                break;
            case 562: // Blades Edge Arena
                underMapValueZ = -1.0f;
                upperLimitValueZ = 22.0f;
                break;
            case 559: // Nagrand Arena
                underMapValueZ = -1.0f;
                upperLimitValueZ = 21.0f;
                break;
            case 572: // Ruins of Lordaeron
                underMapValueZ = -1.0f;
                upperLimitValueZ = 45.0f;
                break;
            case 618: // Ring of Valor
                underMapValueZ = 28.0f;
                upperLimitValueZ = 60.0f;
                break;
            case 566: // Eye of the storm
                underMapValueZ = 1000.0f;
                upperLimitValueZ = MAX_HEIGHT;
                break;
            default:
                AreaTableEntry const* zone = GetAreaEntryByAreaID(plrMover->GetAreaId());
                underMapValueZ = zone ? zone->MaxDepth : -500.0f;
                upperLimitValueZ = MAX_HEIGHT;
                break;
        }

        check = movementInfo.pos.GetPositionZ() < underMapValueZ || movementInfo.pos.GetPositionZ() > upperLimitValueZ;
        if (check && plrMover->isAlive() && !(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player)))
        {
            plrMover->EnvironmentalDamage(DAMAGE_FALL_TO_VOID, GetPlayer()->GetMaxHealth());
            if (!plrMover->isAlive())
                plrMover->KillPlayer(); // prevent death timer
            plrMover->RepopAtGraveyard();
        }
    }

    return true;
}