Core/MovementHandler: added new packet handler for movement
(it is using 4.2.0 struct so not useable, but can be updated, use it as a base)
This commit is contained in:
1 parent
a2f6e169e2
commit
309fd11fb9
5 files changed
+1722
-116
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -30,6 +30,7 @@
|
||||
#include "WaypointMovementGenerator.h"
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "MovementStructures.h"
|
||||
|
||||
void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recv_data*/)
|
||||
{
|
||||
@@ -257,21 +258,14 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
|
||||
return;
|
||||
}
|
||||
|
||||
return; //temp to prevent spamming of bytebuffer exceptions until correct structure is found
|
||||
|
||||
/* extract packet */
|
||||
uint64 guid;
|
||||
|
||||
recv_data.readPackGUID(guid);
|
||||
|
||||
MovementInfo movementInfo;
|
||||
movementInfo.guid = guid;
|
||||
ReadMovementInfo(recv_data, &movementInfo);
|
||||
|
||||
recv_data.rfinish(); // prevent warnings spam
|
||||
|
||||
// prevent tampered movement data
|
||||
if (guid != mover->GetGUID())
|
||||
if (movementInfo.guid != mover->GetGUID())
|
||||
return;
|
||||
|
||||
if (!movementInfo.pos.IsPositionValid())
|
||||
@@ -342,10 +336,10 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
|
||||
/*----------------------*/
|
||||
|
||||
/* process position-change */
|
||||
WorldPacket data(Opcodes(opcode), recv_data.size());
|
||||
WorldPacket data(SMSG_PLAYER_MOVE, recv_data.size());
|
||||
movementInfo.time = getMSTime();
|
||||
movementInfo.guid = mover->GetGUID();
|
||||
WriteMovementInfo(&data, &movementInfo);
|
||||
WriteMovementInfo(data, &movementInfo);
|
||||
mover->SendMessageToSet(&data, _player);
|
||||
|
||||
mover->m_movementInfo = movementInfo;
|
||||
@@ -587,3 +581,324 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recv_data)
|
||||
_player->SummonIfPossible(agree);
|
||||
}
|
||||
|
||||
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
|
||||
{
|
||||
bool HaveTransportData = false,
|
||||
HaveTransportTime2 = false,
|
||||
HaveTransportTime3 = false,
|
||||
HavePitch = false,
|
||||
HaveFallData = false,
|
||||
HaveFallDirection = false,
|
||||
HaveSplineElevation = false,
|
||||
HaveSpline = false;
|
||||
|
||||
MovementStatusElements *sequence = GetMovementStatusElementsSequence(data.GetOpcode());
|
||||
if(sequence == NULL)
|
||||
return;
|
||||
uint8 guid[8];
|
||||
uint8 tguid[8];
|
||||
*(uint64*)guid = 0;
|
||||
*(uint64*)tguid = 0;
|
||||
for(uint32 i=0; i < MSE_COUNT; i++)
|
||||
{
|
||||
MovementStatusElements element = sequence[i];
|
||||
|
||||
if (element >= MSEGuidByte0 && element <= MSEGuidByte7)
|
||||
{
|
||||
data.ReadByteMask(guid[element - MSEGuidByte0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element >= MSETransportGuidByte0 &&
|
||||
element <= MSETransportGuidByte7)
|
||||
{
|
||||
if (HaveTransportData)
|
||||
data.ReadByteMask(tguid[element - MSETransportGuidByte0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element >= MSEGuidByte0_2 && element <= MSEGuidByte7_2)
|
||||
{
|
||||
data.ReadByteSeq(guid[element - MSEGuidByte0_2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element >= MSETransportGuidByte0_2 &&
|
||||
element <= MSETransportGuidByte7_2)
|
||||
{
|
||||
if (HaveTransportData)
|
||||
data.ReadByteSeq(tguid[element - MSETransportGuidByte0_2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (element)
|
||||
{
|
||||
case MSEFlags:
|
||||
mi->flags = data.ReadBits(30);
|
||||
break;
|
||||
case MSEFlags2:
|
||||
mi->flags2 = data.ReadBits(12);
|
||||
break;
|
||||
case MSETimestamp:
|
||||
data >> mi->time;
|
||||
break;
|
||||
case MSEHavePitch:
|
||||
HavePitch = data.ReadBit();
|
||||
break;
|
||||
case MSEHaveFallData:
|
||||
HaveFallData = data.ReadBit();
|
||||
break;
|
||||
case MSEHaveFallDirection:
|
||||
if (HaveFallData)
|
||||
HaveFallDirection = data.ReadBit();
|
||||
break;
|
||||
case MSEHaveTransportData:
|
||||
HaveTransportData = data.ReadBit();
|
||||
break;
|
||||
case MSETransportHaveTime2:
|
||||
if (HaveTransportData)
|
||||
HaveTransportTime2 = data.ReadBit();
|
||||
break;
|
||||
case MSETransportHaveTime3:
|
||||
if (HaveTransportData)
|
||||
HaveTransportTime3 = data.ReadBit();
|
||||
break;
|
||||
case MSEHaveSpline:
|
||||
HaveSpline = data.ReadBit();
|
||||
break;
|
||||
case MSEHaveSplineElev:
|
||||
HaveSplineElevation = data.ReadBit();
|
||||
break;
|
||||
case MSEPositionX:
|
||||
data >> mi->pos.PositionXYZStream();
|
||||
break;
|
||||
case MSEPositionY:
|
||||
case MSEPositionZ:
|
||||
break; // assume they always go as vector of 3
|
||||
case MSEPositionO:
|
||||
data >> mi->pos.m_orientation;
|
||||
break;
|
||||
case MSEPitch:
|
||||
if (HavePitch)
|
||||
data >> mi->pitch;
|
||||
break;
|
||||
case MSEFallTime:
|
||||
if (HaveFallData)
|
||||
data >> mi->fallTime;
|
||||
break;
|
||||
case MSESplineElev:
|
||||
if (HaveSplineElevation)
|
||||
data >> mi->splineElevation;
|
||||
break;
|
||||
case MSEFallHorizontalSpeed:
|
||||
if (HaveFallDirection)
|
||||
data >> mi->j_xyspeed;
|
||||
break;
|
||||
case MSEFallVerticalSpeed:
|
||||
if (HaveFallData)
|
||||
data >> mi->j_zspeed;
|
||||
break;
|
||||
case MSEFallCosAngle:
|
||||
if (HaveFallDirection)
|
||||
data >> mi->j_cosAngle;
|
||||
break;
|
||||
case MSEFallSinAngle:
|
||||
if (HaveFallDirection)
|
||||
data >> mi->j_sinAngle;
|
||||
break;
|
||||
case MSETransportSeat:
|
||||
if (HaveTransportData)
|
||||
data >> mi->t_seat;
|
||||
break;
|
||||
case MSETransportPositionO:
|
||||
if (HaveTransportData)
|
||||
data >> mi->t_pos.m_orientation;
|
||||
break;
|
||||
case MSETransportPositionX:
|
||||
if (HaveTransportData)
|
||||
data >> mi->t_pos.PositionXYZStream();
|
||||
break;
|
||||
case MSETransportPositionY:
|
||||
case MSETransportPositionZ:
|
||||
break; // assume they always go as vector of 3
|
||||
case MSETransportTime:
|
||||
if (HaveTransportData)
|
||||
data >> mi->t_time;
|
||||
break;
|
||||
case MSETransportTime2:
|
||||
if (HaveTransportTime2)
|
||||
data >> mi->t_time2;
|
||||
break;
|
||||
case MSETransportTime3:
|
||||
if (HaveTransportTime3)
|
||||
data >> mi->t_time3;
|
||||
break;
|
||||
default:
|
||||
WPError(false, "Incorrect sequence element detected at ReadMovementInfo");
|
||||
}
|
||||
}
|
||||
|
||||
mi->guid = *(uint64*)guid;
|
||||
mi->t_guid = *(uint64*)tguid;
|
||||
|
||||
if (HaveTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX)
|
||||
if (GetPlayer()->GetTransport())
|
||||
GetPlayer()->GetTransport()->UpdatePosition(mi);
|
||||
}
|
||||
|
||||
void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi)
|
||||
{
|
||||
bool HaveTransportData = mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT),
|
||||
HaveTransportTime2 = (mi->flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT) != 0,
|
||||
HaveTransportTime3 = false,
|
||||
HavePitch = (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)))
|
||||
|| (mi->flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING),
|
||||
HaveFallData = mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_TURNING),
|
||||
HaveFallDirection = mi->HasMovementFlag(MOVEMENTFLAG_JUMPING),
|
||||
HaveSplineElevation = mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION),
|
||||
HaveSpline = false;
|
||||
|
||||
MovementStatusElements *sequence = GetMovementStatusElementsSequence(data.GetOpcode());
|
||||
if(!sequence)
|
||||
return;
|
||||
uint8 *guid = (uint8 *)&mi->guid;
|
||||
uint8 *tguid = (uint8 *)&mi->t_guid;
|
||||
for(uint32 i=0; i < MSE_COUNT; i++)
|
||||
{
|
||||
MovementStatusElements element = sequence[i];
|
||||
|
||||
if (element >= MSEGuidByte0 && element <= MSEGuidByte7)
|
||||
{
|
||||
data.WriteByteMask(guid[element - MSEGuidByte0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element >= MSETransportGuidByte0 &&
|
||||
element <= MSETransportGuidByte7)
|
||||
{
|
||||
if (HaveTransportData)
|
||||
data.WriteByteMask(tguid[element - MSETransportGuidByte0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element >= MSEGuidByte0_2 && element <= MSEGuidByte7_2)
|
||||
{
|
||||
data.WriteByteSeq(guid[element - MSEGuidByte0_2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element >= MSETransportGuidByte0_2 &&
|
||||
element <= MSETransportGuidByte7_2)
|
||||
{
|
||||
if (HaveTransportData)
|
||||
data.WriteByteSeq(tguid[element - MSETransportGuidByte0_2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (element)
|
||||
{
|
||||
case MSEFlags:
|
||||
data.WriteBits(mi->flags, 30);
|
||||
break;
|
||||
case MSEFlags2:
|
||||
data.WriteBits(mi->flags2, 12);
|
||||
break;
|
||||
case MSETimestamp:
|
||||
data << mi->time;
|
||||
break;
|
||||
case MSEHavePitch:
|
||||
data.WriteBit(HavePitch);
|
||||
break;
|
||||
case MSEHaveFallData:
|
||||
data.WriteBit(HaveFallData);
|
||||
break;
|
||||
case MSEHaveFallDirection:
|
||||
if (HaveFallData)
|
||||
data.WriteBit(HaveFallDirection);
|
||||
break;
|
||||
case MSEHaveTransportData:
|
||||
data.WriteBit(HaveTransportData);
|
||||
break;
|
||||
case MSETransportHaveTime2:
|
||||
if (HaveTransportData)
|
||||
data.WriteBit(HaveTransportTime2);
|
||||
break;
|
||||
case MSETransportHaveTime3:
|
||||
if (HaveTransportData)
|
||||
data.WriteBit(HaveTransportTime3);
|
||||
break;
|
||||
case MSEHaveSpline:
|
||||
data.WriteBit(HaveSpline);
|
||||
break;
|
||||
case MSEHaveSplineElev:
|
||||
data.WriteBit(HaveSplineElevation);
|
||||
break;
|
||||
case MSEPositionX:
|
||||
data << mi->pos.PositionXYZStream();
|
||||
break;
|
||||
case MSEPositionY:
|
||||
case MSEPositionZ:
|
||||
break; // assume they always go as vector of 3
|
||||
case MSEPositionO:
|
||||
data << mi->pos.m_orientation;
|
||||
break;
|
||||
case MSEPitch:
|
||||
if (HavePitch)
|
||||
data << mi->pitch;
|
||||
break;
|
||||
case MSEFallTime:
|
||||
if (HaveFallData)
|
||||
data << mi->fallTime;
|
||||
break;
|
||||
case MSESplineElev:
|
||||
if (HaveSplineElevation)
|
||||
data << mi->splineElevation;
|
||||
break;
|
||||
case MSEFallHorizontalSpeed:
|
||||
if (HaveFallDirection)
|
||||
data << mi->j_xyspeed;
|
||||
break;
|
||||
case MSEFallVerticalSpeed:
|
||||
if (HaveFallData)
|
||||
data << mi->j_zspeed;
|
||||
break;
|
||||
case MSEFallCosAngle:
|
||||
if (HaveFallDirection)
|
||||
data << mi->j_cosAngle;
|
||||
break;
|
||||
case MSEFallSinAngle:
|
||||
if (HaveFallDirection)
|
||||
data << mi->j_sinAngle;
|
||||
break;
|
||||
case MSETransportSeat:
|
||||
if (HaveTransportData)
|
||||
data << mi->t_seat;
|
||||
break;
|
||||
case MSETransportPositionO:
|
||||
if (HaveTransportData)
|
||||
data << mi->t_pos.m_orientation;
|
||||
break;
|
||||
case MSETransportPositionX:
|
||||
if (HaveTransportData)
|
||||
data << mi->t_pos.PositionXYZStream();
|
||||
break;
|
||||
case MSETransportPositionY:
|
||||
case MSETransportPositionZ:
|
||||
break; // assume they always go as vector of 3
|
||||
case MSETransportTime:
|
||||
if (HaveTransportData)
|
||||
data << mi->t_time;
|
||||
break;
|
||||
case MSETransportTime2:
|
||||
if (HaveTransportTime2)
|
||||
data << mi->t_time2;
|
||||
break;
|
||||
case MSETransportTime3:
|
||||
if (HaveTransportTime3)
|
||||
data << mi->t_time3;
|
||||
break;
|
||||
default:
|
||||
WPError(false, "Incorrect sequence element detected at ReadMovementInfo");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,28 @@ class WorldPacket : public ByteBuffer
|
||||
void SetOpcode(Opcodes opcode) { m_opcode = opcode; }
|
||||
void Compress(Opcodes opcode);
|
||||
|
||||
void ReadByteMask(uint8& b)
|
||||
{
|
||||
b = ReadBit() ? 1 : 0;
|
||||
}
|
||||
|
||||
void ReadByteSeq(uint8& b)
|
||||
{
|
||||
if (b != 0)
|
||||
b ^= read<uint8>();
|
||||
}
|
||||
|
||||
void WriteByteMask(uint8 b)
|
||||
{
|
||||
WriteBit(b);
|
||||
}
|
||||
|
||||
void WriteByteSeq(uint8 b)
|
||||
{
|
||||
if (b != 0)
|
||||
append<uint8>(b ^ 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
Opcodes m_opcode;
|
||||
void Compress(void* dst, uint32 *dst_size, const void* src, int src_size);
|
||||
|
||||
@@ -728,111 +728,6 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans)
|
||||
m_TutorialsChanged = false;
|
||||
}
|
||||
|
||||
void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
|
||||
{
|
||||
data >> mi->flags;
|
||||
data >> mi->flags2;
|
||||
data >> mi->time;
|
||||
data >> mi->pos.PositionXYZOStream();
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
data.readPackGUID(mi->t_guid);
|
||||
|
||||
data >> mi->t_pos.PositionXYZOStream();
|
||||
data >> mi->t_time;
|
||||
data >> mi->t_seat;
|
||||
|
||||
if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT))
|
||||
data >> mi->t_time2;
|
||||
|
||||
if (mi->pos.m_positionX != mi->t_pos.m_positionX)
|
||||
if (GetPlayer()->GetTransport())
|
||||
GetPlayer()->GetTransport()->UpdatePosition(mi);
|
||||
}
|
||||
|
||||
if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)))
|
||||
data >> mi->pitch;
|
||||
|
||||
data >> mi->fallTime;
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
||||
{
|
||||
data >> mi->j_zspeed;
|
||||
data >> mi->j_sinAngle;
|
||||
data >> mi->j_cosAngle;
|
||||
data >> mi->j_xyspeed;
|
||||
}
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
|
||||
data >> mi->splineElevation;
|
||||
|
||||
// This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid,
|
||||
// and when used in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD
|
||||
// it will freeze clients that receive this player's movement info.
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_ROOT))
|
||||
mi->flags &= ~MOVEMENTFLAG_ROOT;
|
||||
|
||||
// Cannot hover and jump at the same time
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
||||
mi->flags &= ~MOVEMENTFLAG_JUMPING;
|
||||
|
||||
// Cannot ascend and descend at the same time
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING))
|
||||
mi->flags &= ~(MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
|
||||
|
||||
// Cannot move left and right at the same time
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT))
|
||||
mi->flags &= ~(MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
|
||||
|
||||
// Cannot strafe left and right at the same time
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT))
|
||||
mi->flags &= ~(MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
|
||||
|
||||
// Cannot pitch up and down at the same time
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN))
|
||||
mi->flags &= ~(MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
|
||||
|
||||
// Cannot move forwards and backwards at the same time
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD))
|
||||
mi->flags &= ~(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
|
||||
}
|
||||
|
||||
void WorldSession::WriteMovementInfo(WorldPacket* data, MovementInfo* mi)
|
||||
{
|
||||
data->appendPackGUID(mi->guid);
|
||||
|
||||
*data << mi->flags;
|
||||
*data << mi->flags2;
|
||||
*data << mi->time;
|
||||
*data << mi->pos.PositionXYZOStream();
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
|
||||
{
|
||||
data->appendPackGUID(mi->t_guid);
|
||||
|
||||
*data << mi->t_pos.PositionXYZOStream();
|
||||
*data << mi->t_time;
|
||||
*data << mi->t_seat;
|
||||
}
|
||||
|
||||
if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
|
||||
*data << mi->pitch;
|
||||
|
||||
*data << mi->fallTime;
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
||||
{
|
||||
*data << mi->j_zspeed;
|
||||
*data << mi->j_sinAngle;
|
||||
*data << mi->j_cosAngle;
|
||||
*data << mi->j_xyspeed;
|
||||
}
|
||||
|
||||
if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
|
||||
*data << mi->splineElevation;
|
||||
}
|
||||
|
||||
void WorldSession::ReadAddonsInfo(WorldPacket &data)
|
||||
{
|
||||
if (data.rpos() + 4 > data.size())
|
||||
|
||||
@@ -231,7 +231,7 @@ class WorldSession
|
||||
void SendAddonsInfo();
|
||||
|
||||
void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
|
||||
void WriteMovementInfo(WorldPacket* data, MovementInfo* mi);
|
||||
void WriteMovementInfo(WorldPacket &data, MovementInfo* mi);
|
||||
|
||||
void SendPacket(WorldPacket const* packet);
|
||||
void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3);
|
||||
|
||||
Reference in new issue
Block a user