feat(Core/Anticheat): Preparation to implement new passive anticheat … (#5516)

This commit is contained in:
UltraNix
2021-05-07 18:10:44 +02:00
committed by GitHub
parent 0e8e21b812
commit 2189ac0b08
13 changed files with 406 additions and 64 deletions

View File

@@ -13,6 +13,7 @@
#include "Corpse.h"
#include "GameGraveyard.h"
#include "InstanceSaveMgr.h"
#include "Language.h"
#include "Log.h"
#include "MathUtil.h"
#include "MapManager.h"
@@ -26,6 +27,7 @@
#include "WaypointMovementGenerator.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Vehicle.h"
#define MOVEMENT_PACKET_TIME_DELAY 0
@@ -328,8 +330,8 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
return;
}
// pussywizard: typical check for incomming movement packets
if (!mover || !(mover->IsInWorld()) || mover->IsDuringRemoveFromWorld() || !(mover->movespline->Finalized()))
// pussywizard: typical check for incomming movement packets | prevent tampered movement data
if (!mover || !(mover->IsInWorld()) || mover->IsDuringRemoveFromWorld() || guid != mover->GetGUID())
{
recvData.rfinish(); // prevent warnings spam
return;
@@ -341,30 +343,69 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
if (!movementInfo.pos.IsPositionValid())
{
if (plrMover)
{
sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
}
recvData.rfinish(); // prevent warnings spam
return;
}
recvData.rfinish(); // prevent warnings spam
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
if (!mover->movespline->Finalized())
{
// T_POS ON VEHICLES!
if (mover->GetVehicle())
movementInfo.transport.pos = mover->m_movementInfo.transport.pos;
recvData.rfinish(); // prevent warnings spam
return;
}
// transports size limited
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
if (movementInfo.transport.pos.GetPositionX() > 75.0f || movementInfo.transport.pos.GetPositionY() > 75.0f || movementInfo.transport.pos.GetPositionZ() > 75.0f ||
movementInfo.transport.pos.GetPositionX() < -75.0f || movementInfo.transport.pos.GetPositionY() < -75.0f || movementInfo.transport.pos.GetPositionZ() < -75.0f)
// Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
if (mover->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
{
// Xinef: skip moving packets
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
{
recvData.rfinish(); // prevent warnings spam
if (plrMover)
{
sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
}
return;
}
movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
if (mover->GetTypeId() == TYPEID_UNIT)
{
movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
movementInfo.transport.pos.Relocate(mover->m_movementInfo.transport.pos.GetPositionX(), mover->m_movementInfo.transport.pos.GetPositionY(), mover->m_movementInfo.transport.pos.GetPositionZ());
movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
}
}
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
{
// We were teleported, skip packets that were broadcast before teleport
if (movementInfo.pos.GetExactDist2d(mover) > SIZE_OF_GRIDS)
{
if (plrMover)
{
sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
//TC_LOG_INFO("anticheat", "MovementHandler:: 2 We were teleported, skip packets that were broadcast before teleport");
}
recvData.rfinish(); // prevent warnings spam
return;
}
if (!acore::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
{
if (plrMover)
{
sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
sScriptMgr->AnticheatUpdateMovementInfo(plrMover, movementInfo);
}
recvData.rfinish(); // prevent warnings spam
return;
}
@@ -382,6 +423,8 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
}
else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
{
sScriptMgr->AnticheatSetSkipOnePacketForASH(plrMover, true);
bool foundNewTransport = false;
plrMover->m_transport->RemovePassenger(plrMover);
if (Transport* transport = plrMover->GetMap()->GetTransport(movementInfo.transport.guid))
@@ -400,42 +443,66 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
}
if (!mover->GetTransport() && !mover->GetVehicle())
movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
{
GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
{
movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
}
}
}
else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
{
sScriptMgr->AnticheatSetUnderACKmount(plrMover); // just for safe
plrMover->m_transport->RemovePassenger(plrMover);
plrMover->m_transport = nullptr;
movementInfo.transport.Reset();
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight())
{
plrMover->HandleFall(movementInfo);
sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
}
// interrupt parachutes upon falling or landing in water
if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM)
{
mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // Parachutes
if (plrMover)
{
sScriptMgr->AnticheatSetJumpingbyOpcode(plrMover, false);
}
}
if (plrMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plrMover->IsInWater())
{
// now client not include swimming flag in case jumping under water
plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
}
if (plrMover)//Hook for OnPlayerMove
sScriptMgr->OnPlayerMove(plrMover, movementInfo, opcode);
// Dont allow to turn on walking if charming other player
if (mover->GetGUID() != _player->GetGUID())
movementInfo.flags &= ~MOVEMENTFLAG_WALKING;
// Xinef: do not allow to move with UNIT_FLAG_DISABLE_MOVE
if (mover->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
bool jumpopcode = false;
if (opcode == MSG_MOVE_JUMP)
{
// Xinef: skip moving packets
if (movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING))
return;
movementInfo.pos.Relocate(mover->GetPositionX(), mover->GetPositionY(), mover->GetPositionZ());
if (mover->GetTypeId() == TYPEID_UNIT)
jumpopcode = true;
if (plrMover && !sScriptMgr->AnticheatHandleDoubleJump(plrMover, mover))
{
movementInfo.transport.guid = mover->m_movementInfo.transport.guid;
movementInfo.transport.pos.Relocate(mover->m_movementInfo.transport.pos.GetPositionX(), mover->m_movementInfo.transport.pos.GetPositionY(), mover->m_movementInfo.transport.pos.GetPositionZ());
movementInfo.transport.seat = mover->m_movementInfo.transport.seat;
plrMover->GetSession()->KickPlayer();
return;
}
}
/* start some hack detection */
if (plrMover && !sScriptMgr->AnticheatCheckMovementInfo(plrMover, movementInfo, mover, jumpopcode))
{
plrMover->GetSession()->KickPlayer();
return;
}
/* process position-change */
WorldPacket data(opcode, recvData.size());
int64 movementTime = (int64)movementInfo.time + _timeSyncClockDelta;
@@ -455,32 +522,22 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
mover->m_movementInfo = movementInfo;
// this is almost never true (pussywizard: only one packet when entering vehicle), normally use mover->IsVehicle()
if (mover->GetVehicle())
// Some vehicles allow the passenger to turn by himself
if (Vehicle* vehicle = mover->GetVehicle())
{
mover->SetOrientation(movementInfo.pos.GetOrientation());
mover->UpdatePosition(movementInfo.pos);
if (VehicleSeatEntry const* seat = vehicle->GetSeatForPassenger(mover))
{
if (seat->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING && movementInfo.pos.GetOrientation() != mover->GetOrientation())
{
mover->SetOrientation(movementInfo.pos.GetOrientation());
mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TURNING);
}
}
return;
}
// pussywizard: previously always mover->UpdatePosition(movementInfo.pos);
if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT && mover->GetTransport())
{
float x, y, z, o;
movementInfo.transport.pos.GetPosition(x, y, z, o);
mover->GetTransport()->CalculatePassengerPosition(x, y, z, &o);
mover->UpdatePosition(x, y, z, o);
}
else
mover->UpdatePosition(movementInfo.pos);
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
// Xinef: moved it here, previously StopMoving function called when player died relocated him to last saved coordinates (which were in air)
if (opcode == MSG_MOVE_FALL_LAND && plrMover && !plrMover->IsInFlight() && (!plrMover->GetTransport() || plrMover->GetTransport()->IsStaticTransport()))
plrMover->HandleFall(movementInfo);
// Xinef: interrupt parachutes upon falling or landing in water
if (opcode == MSG_MOVE_FALL_LAND || opcode == MSG_MOVE_START_SWIM)
mover->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // Parachutes
mover->UpdatePosition(movementInfo.pos);
if (plrMover) // nothing is charmed, or player charmed
{
@@ -597,6 +654,8 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket& recvData)
return;
}
sScriptMgr->AnticheatSetUnderACKmount(_player);
// skip all forced speed changes except last and unexpected
// in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both.
if (_player->m_forced_speed_changes[force_move_type] > 0)