aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp595
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp2
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp499
-rw-r--r--src/server/game/Handlers/TaxiHandler.cpp2
-rw-r--r--src/server/game/Handlers/VehicleHandler.cpp2
-rw-r--r--src/server/game/Movement/MovementStructures.h85
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h3
9 files changed, 647 insertions, 545 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 860bf13ca8a..aeef0a87535 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -59,6 +59,7 @@
#include "Vehicle.h"
#include "World.h"
#include "WorldPacket.h"
+#include "MovementStructures.h"
#include "WorldSession.h"
#include <math.h>
@@ -16686,71 +16687,563 @@ void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool cas
}
}
-void Unit::SendTeleportPacket(Position& pos)
+void Unit::ReadMovementInfo(WorldPacket& data, MovementInfo* mi)
{
- Position oldPos = {GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), GetOrientation()};
+ if (GetTypeId() != TYPEID_PLAYER)
+ return;
- if (GetTypeId() == TYPEID_UNIT)
- Relocate(&pos);
+ 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 = GetGUID();
- ObjectGuid transGuid = GetTransGUID();
+ ObjectGuid guid;
+ ObjectGuid tguid;
- WorldPacket data(MSG_MOVE_TELEPORT, 38);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[2]);
- data.WriteBit(0); // unknown
- data.WriteBit(uint64(transGuid));
- data.WriteBit(guid[1]);
- if (transGuid)
+ for (uint32 i = 0; i < MSE_COUNT; ++i)
{
- data.WriteBit(transGuid[1]);
- data.WriteBit(transGuid[3]);
- data.WriteBit(transGuid[2]);
- data.WriteBit(transGuid[5]);
- data.WriteBit(transGuid[0]);
- data.WriteBit(transGuid[7]);
- data.WriteBit(transGuid[6]);
- data.WriteBit(transGuid[4]);
+ 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;
+ }
}
- data.WriteBit(guid[4]);
- data.WriteBit(guid[7]);
- data.WriteBit(guid[5]);
- data.FlushBits();
- if (transGuid)
+ mi->guid = guid;
+ mi->t_guid = tguid;
+
+ if (hasTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX)
+ if (GetTransport())
+ 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(), 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) && !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) && !HasAuraType(SPELL_AURA_WATER_WALK),
+ MOVEMENTFLAG_WATERWALKING);
+
+ //! Cannot feather fall without SPELL_AURA_FEATHER_FALL
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !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) && ToPlayer()->GetSession()->GetSecurity() == SEC_PLAYER &&
+ !ToPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) &&
+ !ToPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
+ MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
+
+ #undef REMOVE_VIOLATING_FLAGS
+}
+
+void Unit::WriteMovementInfo(WorldPacket& data)
+{
+ Unit* mover = GetCharmerGUID() ? GetCharmer() : this;
+
+ bool hasMovementFlags = mover->GetUnitMovementFlags() != 0;
+ bool hasMovementFlags2 = mover->GetExtraUnitMovementFlags() != 0;
+ bool hasTimestamp = GetTypeId() == TYPEID_PLAYER ? (mover->m_movementInfo.time != 0) : true;
+ bool hasOrientation = !G3D::fuzzyEq(mover->GetOrientation(), 0.0f);
+ bool hasTransportData = mover->GetTransport() != NULL;
+ bool hasTransportTime2 = mover->HasExtraUnitMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT);
+ bool hasTransportTime3 = false;
+ bool hasPitch = mover->HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mover->HasExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
+ bool hasFallData = mover->HasExtraUnitMovementFlag(MOVEMENTFLAG2_INTERPOLATED_TURNING);
+ bool hasFallDirection = mover->HasUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ bool hasSplineElevation = mover->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
+ bool hasSpline = false;
+
+ MovementStatusElements* sequence = GetMovementStatusElementsSequence(data.GetOpcode());
+ if (!sequence)
{
- data.WriteByteSeq(transGuid[6]);
- data.WriteByteSeq(transGuid[5]);
- data.WriteByteSeq(transGuid[1]);
- data.WriteByteSeq(transGuid[7]);
- data.WriteByteSeq(transGuid[0]);
- data.WriteByteSeq(transGuid[2]);
- data.WriteByteSeq(transGuid[4]);
- data.WriteByteSeq(transGuid[3]);
+ sLog->outError(LOG_FILTER_NETWORKIO, "WorldSession::WriteMovementInfo: No movement sequence found for opcode 0x%04X", uint32(data.GetOpcode()));
+ return;
}
- data << uint32(0); // counter
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[5]);
- data << float(GetPositionX());
- data.WriteByteSeq(guid[4]);
- data << float(GetOrientation());
- data.WriteByteSeq(guid[7]);
- data << float(GetPositionZMinusOffset());
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[6]);
- data << float(GetPositionY());
+ ObjectGuid guid = mover->GetGUID();
+ ObjectGuid tguid = hasTransportData ? GetTransport()->GetGUID() : 0;
+
+ 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(mover->GetUnitMovementFlags(), 30);
+ break;
+ case MSEMovementFlags2:
+ if (hasMovementFlags2)
+ data.WriteBits(mover->GetExtraUnitMovementFlags(), 12);
+ break;
+ case MSETimestamp:
+ if (hasTimestamp)
+ data << getMSTime();
+ break;
+ case MSEPositionX:
+ data << mover->GetPositionX();
+ break;
+ case MSEPositionY:
+ data << mover->GetPositionY();
+ break;
+ case MSEPositionZ:
+ data << mover->GetPositionZ();
+ break;
+ case MSEOrientation:
+ if (hasOrientation)
+ data << mover->GetOrientation();
+ break;
+ case MSETransportPositionX:
+ if (hasTransportData)
+ data << mover->GetTransport()->GetPositionX();
+ break;
+ case MSETransportPositionY:
+ if (hasTransportData)
+ data << mover->GetTransport()->GetPositionY();
+ break;
+ case MSETransportPositionZ:
+ if (hasTransportData)
+ data << mover->GetTransport()->GetPositionZ();
+ break;
+ case MSETransportOrientation:
+ if (hasTransportData)
+ data << mover->GetTransport()->GetOrientation();
+ break;
+ case MSETransportSeat:
+ if (hasTransportData)
+ data << mover->GetTransSeat();
+ break;
+ case MSETransportTime:
+ if (hasTransportData)
+ data << mover->GetTransTime();
+ break;
+ case MSETransportTime2:
+ if (hasTransportData && hasTransportTime2)
+ data << mover->m_movementInfo.t_time2;
+ break;
+ case MSETransportTime3:
+ if (hasTransportData && hasTransportTime3)
+ data << mover->m_movementInfo.t_time3;
+ break;
+ case MSEPitch:
+ if (hasPitch)
+ data << mover->m_movementInfo.pitch;
+ break;
+ case MSEFallTime:
+ if (hasFallData)
+ data << mover->m_movementInfo.fallTime;
+ break;
+ case MSEFallVerticalSpeed:
+ if (hasFallData)
+ data << mover->m_movementInfo.j_zspeed;
+ break;
+ case MSEFallCosAngle:
+ if (hasFallData && hasFallDirection)
+ data << mover->m_movementInfo.j_cosAngle;
+ break;
+ case MSEFallSinAngle:
+ if (hasFallData && hasFallDirection)
+ data << mover->m_movementInfo.j_sinAngle;
+ break;
+ case MSEFallHorizontalSpeed:
+ if (hasFallData && hasFallDirection)
+ data << mover->m_movementInfo.j_xyspeed;
+ break;
+ case MSESplineElevation:
+ if (hasSplineElevation)
+ data << mover->m_movementInfo.splineElevation;
+ break;
+ case MSEZeroBit:
+ data.WriteBit(0);
+ break;
+ case MSEOneBit:
+ data.WriteBit(1);
+ break;
+ default:
+ ASSERT(false && "Incorrect sequence element detected at ReadMovementInfo");
+ break;
+ }
+ }
+}
+
+void Unit::SendTeleportPacket(Position& pos)
+{
+ // MSG_MOVE_UPDATE_TELEPORT is sent to nearby players to signal the teleport
+ // MSG_MOVE_TELEPORT is sent to self in order to trigger MSG_MOVE_TELEPORT_ACK and update the position server side
+ // This oldPos actually contains the destination position if the Unit is a Player.
+ Position oldPos = {GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), GetOrientation()};
+
+ if (GetTypeId() == TYPEID_UNIT)
+ Relocate(&pos); // Relocate the unit to its new position in order to build the packets correctly.
+
+ ObjectGuid guid = GetGUID();
+ ObjectGuid transGuid = GetTransGUID();
+
+ WorldPacket data(MSG_MOVE_UPDATE_TELEPORT, 38);
+ WriteMovementInfo(data);
+
+ if (GetTypeId() == TYPEID_PLAYER)
+ {
+ WorldPacket data2(MSG_MOVE_TELEPORT, 38);
+ data2.WriteBit(guid[6]);
+ data2.WriteBit(guid[0]);
+ data2.WriteBit(guid[3]);
+ data2.WriteBit(guid[2]);
+ data2.WriteBit(0); // unknown
+ data2.WriteBit(uint64(transGuid));
+ data2.WriteBit(guid[1]);
+ if (transGuid)
+ {
+ data2.WriteBit(transGuid[1]);
+ data2.WriteBit(transGuid[3]);
+ data2.WriteBit(transGuid[2]);
+ data2.WriteBit(transGuid[5]);
+ data2.WriteBit(transGuid[0]);
+ data2.WriteBit(transGuid[7]);
+ data2.WriteBit(transGuid[6]);
+ data2.WriteBit(transGuid[4]);
+ }
+ data2.WriteBit(guid[4]);
+ data2.WriteBit(guid[7]);
+ data2.WriteBit(guid[5]);
+ data2.FlushBits();
+
+ if (transGuid)
+ {
+ data2.WriteByteSeq(transGuid[6]);
+ data2.WriteByteSeq(transGuid[5]);
+ data2.WriteByteSeq(transGuid[1]);
+ data2.WriteByteSeq(transGuid[7]);
+ data2.WriteByteSeq(transGuid[0]);
+ data2.WriteByteSeq(transGuid[2]);
+ data2.WriteByteSeq(transGuid[4]);
+ data2.WriteByteSeq(transGuid[3]);
+ }
+
+ data2 << uint32(0); // counter
+ data2.WriteByteSeq(guid[1]);
+ data2.WriteByteSeq(guid[2]);
+ data2.WriteByteSeq(guid[3]);
+ data2.WriteByteSeq(guid[5]);
+ data2 << float(GetPositionX());
+ data2.WriteByteSeq(guid[4]);
+ data2 << float(GetOrientation());
+ data2.WriteByteSeq(guid[7]);
+ data2 << float(GetPositionZMinusOffset());
+ data2.WriteByteSeq(guid[0]);
+ data2.WriteByteSeq(guid[6]);
+ data2 << float(GetPositionY());
+ ToPlayer()->SendDirectMessage(&data2); // Send the MSG_MOVE_TELEPORT packet to self.
+ }
+
+ // Relocate the player/creature to its old position, so we can broadcast to nearby players correctly
if (GetTypeId() == TYPEID_PLAYER)
- Relocate(&pos);
+ Relocate(&pos);
else
Relocate(&oldPos);
- SendMessageToSet(&data, true);
+
+ // Broadcast the packet to everyone except self.
+ SendMessageToSet(&data, false);
}
bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 053876d0532..0dda9db464c 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -2169,6 +2169,8 @@ class Unit : public WorldObject
void _EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp = NULL);
void BuildMovementPacket(ByteBuffer *data) const;
+ void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
+ void WriteMovementInfo(WorldPacket& data);
bool isMoving() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING); }
bool isTurning() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_TURNING); }
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 2d34727bfbe..29af54f195f 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1666,7 +1666,7 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData)
MovementInfo movementInfo;
movementInfo.guid = guid;
- ReadMovementInfo(recvData, &movementInfo);
+ _player->ReadMovementInfo(recvData, &movementInfo);
recvData.read_skip<float>(); // unk2
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
diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index e86c71bd3e0..ceee74fb3d6 100644
--- a/src/server/game/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -202,7 +202,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData)
recvData.read_skip<uint32>(); // unk
MovementInfo movementInfo; // used only for proper packet read
- ReadMovementInfo(recvData, &movementInfo);
+ _player->ReadMovementInfo(recvData, &movementInfo);
// in taxi flight packet received in 2 case:
// 1) end taxi path in far (multi-node) flight
diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp
index 6c1a7607e46..ad8edff6589 100644
--- a/src/server/game/Handlers/VehicleHandler.cpp
+++ b/src/server/game/Handlers/VehicleHandler.cpp
@@ -36,7 +36,7 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recvData)
}
MovementInfo mi;
- ReadMovementInfo(recvData, &mi);
+ _player->ReadMovementInfo(recvData, &mi);
_player->m_movementInfo = mi;
diff --git a/src/server/game/Movement/MovementStructures.h b/src/server/game/Movement/MovementStructures.h
index d2a6e8ea8f6..29b7fb5dfe6 100644
--- a/src/server/game/Movement/MovementStructures.h
+++ b/src/server/game/Movement/MovementStructures.h
@@ -2094,6 +2094,89 @@ MovementStatusElements DismissControlledVehicle[] =
MSEEnd,
};
+// 4.3.4
+MovementStatusElements MoveUpdateTeleport[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSEPositionX,
+ MSEHasOrientation,
+
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasFallData,
+ MSEHasGuidByte0,
+ MSEHasTransportData,
+ MSEHasGuidByte5,
+
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte2,
+
+ MSEZeroBit,
+
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasPitch,
+ MSEHasMovementFlags2,
+ MSEHasTimestamp,
+
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEHasSplineElevation,
+ MSEMovementFlags,
+ MSEHasGuidByte1,
+
+ MSEGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportTime3,
+ MSETransportGuidByte1,
+ MSETransportTime2,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportGuidByte0,
+ MSETransportGuidByte6,
+ MSETransportGuidByte5,
+ MSETransportGuidByte2,
+ MSETransportSeat,
+ MSETransportTime,
+ MSETransportPositionY,
+ MSETransportPositionX,
+
+ MSEGuidByte6,
+ MSEPitch,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte1,
+
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSETimestamp,
+ MSEGuidByte0,
+
+ MSEEnd,
+};
+
MovementStatusElements* GetMovementStatusElementsSequence(Opcodes opcode)
{
switch (opcode)
@@ -2152,6 +2235,8 @@ MovementStatusElements* GetMovementStatusElementsSequence(Opcodes opcode)
return MoveNotActiveMover;
case CMSG_DISMISS_CONTROLLED_VEHICLE:
return DismissControlledVehicle;
+ case MSG_MOVE_UPDATE_TELEPORT:
+ return MoveUpdateTeleport;
default:
break;
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 46a795f8194..7a939526cf7 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -597,7 +597,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_RUN_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_TELEPORT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_UPDATE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(MSG_MOVE_WORLDPORT_ACK, STATUS_TRANSFER, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode );
DEFINE_OPCODE_HANDLER(MSG_NOTIFY_PARTY_SQUELCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER(MSG_PARTY_ASSIGNMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode );
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index fccb60bf472..60ebb3543af 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -209,9 +209,6 @@ class WorldSession
void SendAddonsInfo();
bool IsAddonRegistered(const std::string& prefix) const;
- void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
- void WriteMovementInfo(WorldPacket& data, MovementInfo* mi);
-
void SendPacket(WorldPacket const* packet, bool forced = false);
void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3);
void SendNotification(uint32 string_id, ...);