void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket)
{
	sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_MOVE_TELEPORT_ACK");
    ObjectGuid guid;
    uint32 ackCount = recvPacket.read<uint32>();
    recvPacket.read_skip<uint32>(); // should be new position in kind of struction

    guid[5] = recvPacket.ReadBit();
    guid[0] = recvPacket.ReadBit();
    guid[1] = recvPacket.ReadBit();
    guid[6] = recvPacket.ReadBit();
    guid[3] = recvPacket.ReadBit();
    guid[7] = recvPacket.ReadBit();
    guid[2] = recvPacket.ReadBit();
    guid[4] = recvPacket.ReadBit();

    recvPacket.ReadByteSeq(guid[4]);
    recvPacket.ReadByteSeq(guid[2]);
    recvPacket.ReadByteSeq(guid[7]);
    recvPacket.ReadByteSeq(guid[6]);
    recvPacket.ReadByteSeq(guid[5]);
    recvPacket.ReadByteSeq(guid[1]);
    recvPacket.ReadByteSeq(guid[3]);
    recvPacket.ReadByteSeq(guid[0]);

    // Skip old result
    if (_player->m_movement_ack[ACK_TELEPORT] != ackCount)
        return;

    Player* plMover = _player->m_mover->ToPlayer();

    if (!plMover || !plMover->IsBeingTeleportedNear() || guid != plMover->GetGUID())
        return;

    plMover->SetSemaphoreTeleportNear(false);

    uint32 old_zone = plMover->GetZoneId();

    WorldLocation const& dest = plMover->GetTeleportDest();
    plMover->UpdatePosition(dest, true);

    WorldPacket data(SMSG_MOVE_UPDATE_TELEPORT);
    MovementInfo info = MovementInfo(plMover->m_movementInfo);
    info.pos.Relocate(dest.m_positionX, dest.m_positionY, dest.m_positionZ, dest.m_orientation);
    info.guid = plMover->GetGUID();
    info.time = getMSTime();
    info.WriteToPacket(data);
    _player->SendMessageToSet(&data, _player);

    uint32 newzone, newarea;
    plMover->GetZoneAndAreaId(newzone, newarea);
    plMover->UpdateZone(newzone, newarea);

    if (old_zone != newzone)
    {
        if (plMover->pvpInfo.inHostileArea)
            plMover->CastSpell(plMover, 2479, true); // honorless target
        else if (plMover->IsPvP() && !plMover->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP))
            plMover->UpdatePvP(false, false);
    }

    GetPlayer()->ResummonPetTemporaryUnSummonedIfAny();
    GetPlayer()->ProcessDelayedOperations();
}
Exemple #2
0
void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
{
    uint32 opcode = recv_data.GetOpcode();
    DEBUG_LOG("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);

    Unit *mover = _player->GetMover();
    if (mover->GetObjectGuid() != _clientMoverGuid)
        return;
    Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL;

    // ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
    if (plMover && plMover->IsBeingTeleported())
    {
        recv_data.rpos(recv_data.wpos());                   // prevent warnings spam
        return;
    }

    /* extract packet */
    MovementInfo movementInfo = plMover ? plMover->m_movementInfo : MovementInfo();
    recv_data >> movementInfo;
    movementInfo.UpdateTime(recv_data.GetPacketTime());

    /*----------------*/

    if (!VerifyMovementInfo(movementInfo))
        return;

    if (plMover && !plMover->GetCheatData()->HandleAnticheatTests(movementInfo, this, &recv_data))
        return;

    // this must be called after HandleAnticheatTests because that function will update order counters (for things like slow fall, water walk, etc.)
    if (plMover && !plMover->GetCheatData()->CheckTeleport(opcode, movementInfo))
        return;

    // Interrupt spell cast at move
    if (movementInfo.HasMovementFlag(MOVEFLAG_MASK_MOVING))
        mover->InterruptSpellsWithInterruptFlags(SPELL_INTERRUPT_FLAG_MOVEMENT);

    HandleMoverRelocation(movementInfo);

    // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
    if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->IsTaxiFlying())
        plMover->HandleFall(movementInfo);

    // TODO: remove it
    // reset knockback state when fall to ground or water
    if (plMover)
    {
        if ((opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM) && plMover->IsLaunched())
        {
            plMover->SetLaunched(false);
            plMover->SetXYSpeed(0.0f);
        }
    }

    if (plMover)
        plMover->UpdateFallInformationIfNeed(movementInfo, opcode);

    WorldPacket data(opcode, recv_data.size());
    data << _clientMoverGuid.WriteAsPacked();             // write guid
    movementInfo.Write(data);                               // write data

    mover->SendMovementMessageToSet(std::move(data), true, _player);
}