aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Handlers/MovementHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Handlers/MovementHandler.cpp')
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp499
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