diff options
author | Subv <s.v.h21@hotmail.com> | 2012-12-29 15:20:57 -0500 |
---|---|---|
committer | Subv <s.v.h21@hotmail.com> | 2012-12-29 15:22:37 -0500 |
commit | 9a9fbb87de5ac67b2004fe3fe0b5e7c4aeab5422 (patch) | |
tree | eb28ee53c7e2f5c8584d3330633a43330cfc7050 /src/server/game/Handlers/MovementHandler.cpp | |
parent | ae47b641e10a5af32ba7858504ebeac1915f6841 (diff) |
Entities/Movement: Correctly send MSG_MOVE_TELEPORT to the player when it is teleported, send MSG_MOVE_UPDATE_TELEPORT to nearby players when such thing happens.
Allow the usage of WriteMovementInfo on non-player units.
Diffstat (limited to 'src/server/game/Handlers/MovementHandler.cpp')
-rw-r--r-- | src/server/game/Handlers/MovementHandler.cpp | 499 |
1 files changed, 12 insertions, 487 deletions
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index b3a5c9fac82..b1ae0f8dbd5 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -30,7 +30,6 @@ #include "WaypointMovementGenerator.h" #include "InstanceSaveMgr.h" #include "ObjectMgr.h" -#include "MovementStructures.h" void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket& /*recvPacket*/) { @@ -276,7 +275,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket) /* extract packet */ MovementInfo movementInfo; - ReadMovementInfo(recvPacket, &movementInfo); + GetPlayer()->ReadMovementInfo(recvPacket, &movementInfo); // prevent tampered movement data if (movementInfo.guid != mover->GetGUID()) @@ -375,17 +374,16 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket) plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ())); } - /*----------------------*/ + movementInfo.time = getMSTime(); + movementInfo.guid = mover->GetGUID(); + mover->m_movementInfo = movementInfo; + /*----------------------*/ /* process position-change */ WorldPacket data(SMSG_PLAYER_MOVE, recvPacket.size()); - movementInfo.time = getMSTime(); - movementInfo.guid = mover->GetGUID(); - WriteMovementInfo(data, &movementInfo); + _player->WriteMovementInfo(data); mover->SendMessageToSet(&data, _player); - mover->m_movementInfo = movementInfo; - // this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle() if (mover->GetVehicle()) { @@ -446,7 +444,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData) MovementInfo movementInfo; movementInfo.guid = guid; - ReadMovementInfo(recvData, &movementInfo); + GetPlayer()->ReadMovementInfo(recvData, &movementInfo); recvData >> newspeed; /*----------------*/ @@ -536,7 +534,7 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER"); MovementInfo mi; - ReadMovementInfo(recvData, &mi); + GetPlayer()->ReadMovementInfo(recvData, &mi); _player->m_movementInfo = mi; } @@ -553,7 +551,7 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket& recvData) sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_MOVE_KNOCK_BACK_ACK"); MovementInfo movementInfo; - ReadMovementInfo(recvData, &movementInfo); + GetPlayer()->ReadMovementInfo(recvData, &movementInfo); if (_player->m_mover->GetGUID() != movementInfo.guid) return; @@ -583,7 +581,7 @@ void WorldSession::HandleMoveHoverAck(WorldPacket& recvData) recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; - ReadMovementInfo(recvData, &movementInfo); + GetPlayer()->ReadMovementInfo(recvData, &movementInfo); recvData.read_skip<uint32>(); // unk2 } @@ -598,7 +596,7 @@ void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recvData) recvData.read_skip<uint32>(); // unk MovementInfo movementInfo; - ReadMovementInfo(recvData, &movementInfo); + GetPlayer()->ReadMovementInfo(recvData, &movementInfo); recvData.read_skip<uint32>(); // unk2 } @@ -614,477 +612,4 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData) recvData >> agree; _player->SummonIfPossible(agree); -} - -void WorldSession::ReadMovementInfo(WorldPacket& data, MovementInfo* mi) -{ - bool hasMovementFlags = false; - bool hasMovementFlags2 = false; - bool hasTimestamp = false; - bool hasOrientation = false; - bool hasTransportData = false; - bool hasTransportTime2 = false; - bool hasTransportTime3 = false; - bool hasPitch = false; - bool hasFallData = false; - bool hasFallDirection = false; - bool hasSplineElevation = false; - bool hasSpline = false; - - MovementStatusElements* sequence = GetMovementStatusElementsSequence(data.GetOpcode()); - if (sequence == NULL) - { - sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::ReadMovementInfo: No movement sequence found for opcode 0x%04X", uint32(data.GetOpcode())); - return; - } - - ObjectGuid guid; - ObjectGuid tguid; - - for (uint32 i = 0; i < MSE_COUNT; ++i) - { - MovementStatusElements element = sequence[i]; - if (element == MSEEnd) - break; - - if (element >= MSEHasGuidByte0 && element <= MSEHasGuidByte7) - { - guid[element - MSEHasGuidByte0] = data.ReadBit(); - continue; - } - - if (element >= MSEHasTransportGuidByte0 && - element <= MSEHasTransportGuidByte7) - { - if (hasTransportData) - tguid[element - MSEHasTransportGuidByte0] = data.ReadBit(); - continue; - } - - if (element >= MSEGuidByte0 && element <= MSEGuidByte7) - { - data.ReadByteSeq(guid[element - MSEGuidByte0]); - continue; - } - - if (element >= MSETransportGuidByte0 && - element <= MSETransportGuidByte7) - { - if (hasTransportData) - data.ReadByteSeq(tguid[element - MSETransportGuidByte0]); - continue; - } - - switch (element) - { - case MSEHasMovementFlags: - hasMovementFlags = !data.ReadBit(); - break; - case MSEHasMovementFlags2: - hasMovementFlags2 = !data.ReadBit(); - break; - case MSEHasTimestamp: - hasTimestamp = !data.ReadBit(); - break; - case MSEHasOrientation: - hasOrientation = !data.ReadBit(); - break; - case MSEHasTransportData: - hasTransportData = data.ReadBit(); - break; - case MSEHasTransportTime2: - if (hasTransportData) - hasTransportTime2 = data.ReadBit(); - break; - case MSEHasTransportTime3: - if (hasTransportData) - hasTransportTime3 = data.ReadBit(); - break; - case MSEHasPitch: - hasPitch = !data.ReadBit(); - break; - case MSEHasFallData: - hasFallData = data.ReadBit(); - break; - case MSEHasFallDirection: - if (hasFallData) - hasFallDirection = data.ReadBit(); - break; - case MSEHasSplineElevation: - hasSplineElevation = !data.ReadBit(); - break; - case MSEHasSpline: - hasSpline = data.ReadBit(); - break; - case MSEMovementFlags: - if (hasMovementFlags) - mi->flags = data.ReadBits(30); - break; - case MSEMovementFlags2: - if (hasMovementFlags2) - mi->flags2 = data.ReadBits(12); - break; - case MSETimestamp: - if (hasTimestamp) - data >> mi->time; - break; - case MSEPositionX: - data >> mi->pos.m_positionX; - break; - case MSEPositionY: - data >> mi->pos.m_positionY; - break; - case MSEPositionZ: - data >> mi->pos.m_positionZ; - break; - case MSEOrientation: - if (hasOrientation) - mi->pos.SetOrientation(data.read<float>()); - break; - case MSETransportPositionX: - if (hasTransportData) - data >> mi->t_pos.m_positionX; - break; - case MSETransportPositionY: - if (hasTransportData) - data >> mi->t_pos.m_positionY; - break; - case MSETransportPositionZ: - if (hasTransportData) - data >> mi->t_pos.m_positionZ; - break; - case MSETransportOrientation: - if (hasTransportData) - mi->pos.SetOrientation(data.read<float>()); - break; - case MSETransportSeat: - if (hasTransportData) - data >> mi->t_seat; - break; - case MSETransportTime: - if (hasTransportData) - data >> mi->t_time; - break; - case MSETransportTime2: - if (hasTransportData && hasTransportTime2) - data >> mi->t_time2; - break; - case MSETransportTime3: - if (hasTransportData && hasTransportTime3) - data >> mi->t_time3; - break; - case MSEPitch: - if (hasPitch) - data >> mi->pitch; - break; - case MSEFallTime: - if (hasFallData) - data >> mi->fallTime; - break; - case MSEFallVerticalSpeed: - if (hasFallData) - data >> mi->j_zspeed; - break; - case MSEFallCosAngle: - if (hasFallData && hasFallDirection) - data >> mi->j_cosAngle; - break; - case MSEFallSinAngle: - if (hasFallData && hasFallDirection) - data >> mi->j_sinAngle; - break; - case MSEFallHorizontalSpeed: - if (hasFallData && hasFallDirection) - data >> mi->j_xyspeed; - break; - case MSESplineElevation: - if (hasSplineElevation) - data >> mi->splineElevation; - break; - case MSEZeroBit: - case MSEOneBit: - data.ReadBit(); - break; - default: - ASSERT(false && "Incorrect sequence element detected at ReadMovementInfo"); - break; - } - } - - mi->guid = guid; - mi->t_guid = tguid; - - if (hasTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX) - if (GetPlayer()->GetTransport()) - GetPlayer()->GetTransport()->UpdatePosition(mi); - - //! Anti-cheat checks. Please keep them in seperate if() blocks to maintain a clear overview. - //! Might be subject to latency, so just remove improper flags. - #ifdef TRINITY_DEBUG - #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \ - { \ - if (check) \ - { \ - sLog->outDebug(LOG_FILTER_UNITS, "WorldSession::ReadMovementInfo: Violation of MovementFlags found (%s). " \ - "MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \ - STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUIDLow(), maskToRemove); \ - mi->RemoveMovementFlag((maskToRemove)); \ - } \ - } - #else - #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \ - if (check) \ - mi->RemoveMovementFlag((maskToRemove)); - #endif - - - /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid - in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. - It will freeze clients that receive this player's movement info. - */ - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), - MOVEMENTFLAG_ROOT); - - //! Cannot hover without SPELL_AURA_HOVER - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER), - MOVEMENTFLAG_HOVER); - - //! Cannot ascend and descend at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING), - MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING); - - //! Cannot move left and right at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT), - MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT); - - //! Cannot strafe left and right at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT), - MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT); - - //! Cannot pitch up and down at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN), - MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN); - - //! Cannot move forwards and backwards at the same time - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD), - MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD); - - //! Cannot walk on water without SPELL_AURA_WATER_WALK - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) && !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK), - MOVEMENTFLAG_WATERWALKING); - - //! Cannot feather fall without SPELL_AURA_FEATHER_FALL - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL), - MOVEMENTFLAG_FALLING_SLOW); - - /*! Cannot fly if no fly auras present. Exception is being a GM. - Note that we check for account level instead of Player::IsGameMaster() because in some - situations it may be feasable to use .gm fly on as a GM without having .gm on, - e.g. aerial combat. - */ - - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSecurity() == SEC_PLAYER && - !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) && - !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED), - MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY); - - #undef REMOVE_VIOLATING_FLAGS -} - -void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi) -{ - bool hasMovementFlags = mi->GetMovementFlags() != 0; - bool hasMovementFlags2 = mi->GetExtraMovementFlags() != 0; - bool hasTimestamp = mi->time != 0; - bool hasOrientation = !G3D::fuzzyEq(mi->pos.GetOrientation(), 0.0f); - bool hasTransportData = mi->t_guid != 0; - bool hasTransportTime2 = mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT); - bool hasTransportTime3 = false; - bool hasPitch = mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING); - bool hasFallData = mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_TURNING); - bool hasFallDirection = mi->HasMovementFlag(MOVEMENTFLAG_FALLING); - bool hasSplineElevation = mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION); - bool hasSpline = false; - - MovementStatusElements* sequence = GetMovementStatusElementsSequence(data.GetOpcode()); - if (!sequence) - { - sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::WriteMovementInfo: No movement sequence found for opcode 0x%04X", uint32(data.GetOpcode())); - return; - } - - ObjectGuid guid = mi->guid; - ObjectGuid tguid = mi->t_guid; - - for(uint32 i = 0; i < MSE_COUNT; ++i) - { - MovementStatusElements element = sequence[i]; - if (element == MSEEnd) - break; - - if (element >= MSEHasGuidByte0 && element <= MSEHasGuidByte7) - { - data.WriteBit(guid[element - MSEHasGuidByte0]); - continue; - } - - if (element >= MSEHasTransportGuidByte0 && - element <= MSEHasTransportGuidByte7) - { - if (hasTransportData) - data.WriteBit(tguid[element - MSEHasTransportGuidByte0]); - continue; - } - - if (element >= MSEGuidByte0 && element <= MSEGuidByte7) - { - data.WriteByteSeq(guid[element - MSEGuidByte0]); - continue; - } - - if (element >= MSETransportGuidByte0 && - element <= MSETransportGuidByte7) - { - if (hasTransportData) - data.WriteByteSeq(tguid[element - MSETransportGuidByte0]); - continue; - } - - switch (element) - { - case MSEHasMovementFlags: - data.WriteBit(!hasMovementFlags); - break; - case MSEHasMovementFlags2: - data.WriteBit(!hasMovementFlags2); - break; - case MSEHasTimestamp: - data.WriteBit(!hasTimestamp); - break; - case MSEHasOrientation: - data.WriteBit(!hasOrientation); - break; - case MSEHasTransportData: - data.WriteBit(hasTransportData); - break; - case MSEHasTransportTime2: - if (hasTransportData) - data.WriteBit(hasTransportTime2); - break; - case MSEHasTransportTime3: - if (hasTransportData) - data.WriteBit(hasTransportTime3); - break; - case MSEHasPitch: - data.WriteBit(!hasPitch); - break; - case MSEHasFallData: - data.WriteBit(hasFallData); - break; - case MSEHasFallDirection: - if (hasFallData) - data.WriteBit(hasFallDirection); - break; - case MSEHasSplineElevation: - data.WriteBit(!hasSplineElevation); - break; - case MSEHasSpline: - data.WriteBit(hasSpline); - break; - case MSEMovementFlags: - if (hasMovementFlags) - data.WriteBits(mi->flags, 30); - break; - case MSEMovementFlags2: - if (hasMovementFlags2) - data.WriteBits(mi->flags2, 12); - break; - case MSETimestamp: - if (hasTimestamp) - data << mi->time; - break; - case MSEPositionX: - data << mi->pos.m_positionX; - break; - case MSEPositionY: - data << mi->pos.m_positionY; - break; - case MSEPositionZ: - data << mi->pos.m_positionZ; - break; - case MSEOrientation: - if (hasOrientation) - data << mi->pos.GetOrientation(); - break; - case MSETransportPositionX: - if (hasTransportData) - data << mi->t_pos.m_positionX; - break; - case MSETransportPositionY: - if (hasTransportData) - data << mi->t_pos.m_positionY; - break; - case MSETransportPositionZ: - if (hasTransportData) - data << mi->t_pos.m_positionZ; - break; - case MSETransportOrientation: - if (hasTransportData) - data << mi->t_pos.GetOrientation(); - break; - case MSETransportSeat: - if (hasTransportData) - data << mi->t_seat; - break; - case MSETransportTime: - if (hasTransportData) - data << mi->t_time; - break; - case MSETransportTime2: - if (hasTransportData && hasTransportTime2) - data << mi->t_time2; - break; - case MSETransportTime3: - if (hasTransportData && hasTransportTime3) - data << mi->t_time3; - break; - case MSEPitch: - if (hasPitch) - data << mi->pitch; - break; - case MSEFallTime: - if (hasFallData) - data << mi->fallTime; - break; - case MSEFallVerticalSpeed: - if (hasFallData) - data << mi->j_zspeed; - break; - case MSEFallCosAngle: - if (hasFallData && hasFallDirection) - data << mi->j_cosAngle; - break; - case MSEFallSinAngle: - if (hasFallData && hasFallDirection) - data << mi->j_sinAngle; - break; - case MSEFallHorizontalSpeed: - if (hasFallData && hasFallDirection) - data << mi->j_xyspeed; - break; - case MSESplineElevation: - if (hasSplineElevation) - data << mi->splineElevation; - break; - case MSEZeroBit: - data.WriteBit(0); - break; - case MSEOneBit: - data.WriteBit(1); - break; - default: - ASSERT(false && "Incorrect sequence element detected at ReadMovementInfo"); - break; - } - } -} +}
\ No newline at end of file |