Core/Movement: Do not process server side relocation if reading movementinfo from client resulted in violations (= hacking).

This commit is contained in:
Machiavelli
2012-03-16 18:15:08 +01:00
parent cca93c7a22
commit 65453620e8
5 changed files with 68 additions and 13 deletions
+4
View File
@@ -482,6 +482,9 @@ struct MovementInfo
// spline
float splineElevation;
//! Server side only:
bool Violated;
MovementInfo()
{
pos.Relocate(0, 0, 0, 0);
@@ -494,6 +497,7 @@ struct MovementInfo
t_guid = 0;
t_pos.Relocate(0, 0, 0, 0);
t_seat = -1;
Violated = false;
}
uint32 GetMovementFlags() { return flags; }
+6
View File
@@ -1621,6 +1621,12 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket & recv_data)
recv_data.read_skip<float>(); // unk2
if (movementInfo.Violated)
{
recv_data.rfinish();
return;
}
_player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags();
}
+24 -1
View File
@@ -278,6 +278,14 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data)
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 */
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
{
@@ -485,9 +493,16 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
recv_data.readPackGUID(old_mover_guid);
MovementInfo mi;
mi.guid = old_mover_guid;
ReadMovementInfo(recv_data, &mi);
if (mi.Violated)
{
recv_data.rfinish();
return;
}
mi.guid = old_mover_guid;
_player->m_movementInfo = mi;
}
@@ -513,6 +528,13 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket & recv_data)
MovementInfo movementInfo;
ReadMovementInfo(recv_data, &movementInfo);
if (movementInfo.Violated)
{
recv_data.rfinish();
return;
}
_player->m_movementInfo = movementInfo;
WorldPacket data(MSG_MOVE_KNOCK_BACK, 66);
@@ -571,3 +593,4 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recv_data)
_player->SummonIfPossible(agree);
}
#undef IF_VIOLATED_RETURN
+16 -1
View File
@@ -43,6 +43,12 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
mi.guid = guid;
ReadMovementInfo(recv_data, &mi);
if (mi.Violated)
{
recv_data.rfinish();
return;
}
_player->m_movementInfo = mi;
_player->ExitVehicle();
@@ -81,7 +87,16 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recv_data)
uint64 guid; // current vehicle 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
recv_data.readPackGUID(accessory);
+18 -11
View File
@@ -807,48 +807,53 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
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,
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;
VIOLATE_AND_RETURN;
//! Cannot hover and jump at the same time
if (mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && mi->HasMovementFlag(MOVEMENTFLAG_JUMPING))
mi->flags &= ~MOVEMENTFLAG_JUMPING;
VIOLATE_AND_RETURN;
//! Cannot ascend and descend at the same time
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
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
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
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
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
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
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
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.
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 &&
!GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) &&
!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)