Core/Movement: Do not process server side relocation if reading movementinfo from client resulted in violations (= hacking).
This commit is contained in:
@@ -482,6 +482,9 @@ struct MovementInfo
|
|||||||
// spline
|
// spline
|
||||||
float splineElevation;
|
float splineElevation;
|
||||||
|
|
||||||
|
//! Server side only:
|
||||||
|
bool Violated;
|
||||||
|
|
||||||
MovementInfo()
|
MovementInfo()
|
||||||
{
|
{
|
||||||
pos.Relocate(0, 0, 0, 0);
|
pos.Relocate(0, 0, 0, 0);
|
||||||
@@ -494,6 +497,7 @@ struct MovementInfo
|
|||||||
t_guid = 0;
|
t_guid = 0;
|
||||||
t_pos.Relocate(0, 0, 0, 0);
|
t_pos.Relocate(0, 0, 0, 0);
|
||||||
t_seat = -1;
|
t_seat = -1;
|
||||||
|
Violated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetMovementFlags() { return flags; }
|
uint32 GetMovementFlags() { return flags; }
|
||||||
|
|||||||
@@ -1621,6 +1621,12 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket & recv_data)
|
|||||||
|
|
||||||
recv_data.read_skip<float>(); // unk2
|
recv_data.read_skip<float>(); // unk2
|
||||||
|
|
||||||
|
if (movementInfo.Violated)
|
||||||
|
{
|
||||||
|
recv_data.rfinish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
|
_player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -278,6 +278,14 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! If some anti-cheat checks in WorldSession::ReadMovementInfo failed, do not process
|
||||||
|
//! the change of movement server-sided.
|
||||||
|
if (movementInfo.Violated)
|
||||||
|
{
|
||||||
|
recv_data.rfinish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* handle special cases */
|
/* handle special cases */
|
||||||
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
|
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
|
||||||
{
|
{
|
||||||
@@ -485,9 +493,16 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
|
|||||||
recv_data.readPackGUID(old_mover_guid);
|
recv_data.readPackGUID(old_mover_guid);
|
||||||
|
|
||||||
MovementInfo mi;
|
MovementInfo mi;
|
||||||
mi.guid = old_mover_guid;
|
|
||||||
ReadMovementInfo(recv_data, &mi);
|
ReadMovementInfo(recv_data, &mi);
|
||||||
|
|
||||||
|
if (mi.Violated)
|
||||||
|
{
|
||||||
|
recv_data.rfinish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mi.guid = old_mover_guid;
|
||||||
|
|
||||||
_player->m_movementInfo = mi;
|
_player->m_movementInfo = mi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,6 +528,13 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket & recv_data)
|
|||||||
|
|
||||||
MovementInfo movementInfo;
|
MovementInfo movementInfo;
|
||||||
ReadMovementInfo(recv_data, &movementInfo);
|
ReadMovementInfo(recv_data, &movementInfo);
|
||||||
|
|
||||||
|
if (movementInfo.Violated)
|
||||||
|
{
|
||||||
|
recv_data.rfinish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_player->m_movementInfo = movementInfo;
|
_player->m_movementInfo = movementInfo;
|
||||||
|
|
||||||
WorldPacket data(MSG_MOVE_KNOCK_BACK, 66);
|
WorldPacket data(MSG_MOVE_KNOCK_BACK, 66);
|
||||||
@@ -571,3 +593,4 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recv_data)
|
|||||||
_player->SummonIfPossible(agree);
|
_player->SummonIfPossible(agree);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef IF_VIOLATED_RETURN
|
||||||
@@ -43,6 +43,12 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
|
|||||||
mi.guid = guid;
|
mi.guid = guid;
|
||||||
ReadMovementInfo(recv_data, &mi);
|
ReadMovementInfo(recv_data, &mi);
|
||||||
|
|
||||||
|
if (mi.Violated)
|
||||||
|
{
|
||||||
|
recv_data.rfinish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_player->m_movementInfo = mi;
|
_player->m_movementInfo = mi;
|
||||||
|
|
||||||
_player->ExitVehicle();
|
_player->ExitVehicle();
|
||||||
@@ -81,7 +87,16 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data)
|
|||||||
uint64 guid; // current vehicle guid
|
uint64 guid; // current vehicle guid
|
||||||
recv_data.readPackGUID(guid);
|
recv_data.readPackGUID(guid);
|
||||||
|
|
||||||
ReadMovementInfo(recv_data, &vehicle_base->m_movementInfo);
|
MovementInfo movementInfo;
|
||||||
|
ReadMovementInfo(recv_data, &movementInfo);
|
||||||
|
|
||||||
|
if (movementInfo.Violated)
|
||||||
|
{
|
||||||
|
recv_data.rfinish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vehicle_base->m_movementInfo = movementInfo;
|
||||||
|
|
||||||
uint64 accessory; // accessory guid
|
uint64 accessory; // accessory guid
|
||||||
recv_data.readPackGUID(accessory);
|
recv_data.readPackGUID(accessory);
|
||||||
|
|||||||
@@ -807,48 +807,53 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
|
|||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
|
||||||
data >> mi->splineElevation;
|
data >> mi->splineElevation;
|
||||||
|
|
||||||
|
//! Anti-cheat checks. Please keep them in seperate if() blocks to maintain a clear overview.
|
||||||
|
#define VIOLATE_AND_RETURN \
|
||||||
|
mi->Violated = true; \
|
||||||
|
return; \
|
||||||
|
|
||||||
/*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid,
|
/*! 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
|
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.
|
it will freeze clients that receive this player's movement info.
|
||||||
*/
|
*/
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_ROOT))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_ROOT))
|
||||||
mi->flags &= ~MOVEMENTFLAG_ROOT;
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot hover and jump at the same time
|
//! Cannot hover and jump at the same time
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
|
||||||
mi->flags &= ~MOVEMENTFLAG_JUMPING;
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot ascend and descend at the same time
|
//! Cannot ascend and descend at the same time
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING))
|
||||||
mi->flags &= ~(MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot move left and right at the same time
|
//! Cannot move left and right at the same time
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT))
|
||||||
mi->flags &= ~(MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot strafe left and right at the same time
|
//! Cannot strafe left and right at the same time
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT))
|
||||||
mi->flags &= ~(MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot pitch up and down at the same time
|
//! Cannot pitch up and down at the same time
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN))
|
||||||
mi->flags &= ~(MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot move forwards and backwards at the same time
|
//! Cannot move forwards and backwards at the same time
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD))
|
||||||
mi->flags &= ~(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot walk on water without SPELL_AURA_WATER_WALK
|
//! Cannot walk on water without SPELL_AURA_WATER_WALK
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) && !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) && !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||||
mi->flags &= ~MOVEMENTFLAG_WATERWALKING;
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot feather fall without SPELL_AURA_FEATHER_FALL
|
//! Cannot feather fall without SPELL_AURA_FEATHER_FALL
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL))
|
||||||
mi->flags &= ~MOVEMENTFLAG_FALLING_SLOW;
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
//! Cannot hover without SPELL_AURA_HOVER
|
//! Cannot hover without SPELL_AURA_HOVER
|
||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER))
|
if (mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER))
|
||||||
mi->flags &= ~MOVEMENTFLAG_HOVER;
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
/*! Cannot fly if no fly auras present. Exception is being a GM.
|
/*! 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
|
Note that we check for account level instead of Player::IsGameMaster() because in some
|
||||||
@@ -859,7 +864,9 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
|
|||||||
if (mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSecurity() == SEC_PLAYER &&
|
if (mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSecurity() == SEC_PLAYER &&
|
||||||
!GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) &&
|
!GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) &&
|
||||||
!GetPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED))
|
!GetPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED))
|
||||||
mi->flags &= ~(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
|
VIOLATE_AND_RETURN;
|
||||||
|
|
||||||
|
#undef VIOLATE_AND_RETURN
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldSession::WriteMovementInfo(WorldPacket* data, MovementInfo* mi)
|
void WorldSession::WriteMovementInfo(WorldPacket* data, MovementInfo* mi)
|
||||||
|
|||||||
Reference in New Issue
Block a user