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(); }
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); }