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:
Rat committed 2011-11-29 17:57:38 +01:00
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");
}
}
}
+22
View File
@@ -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);
-105
View File
@@ -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())
+1 -1
View File
@@ -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);