mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 02:20:27 +00:00
feat(Core/Anticheat): Preparation to implement new passive anticheat … (#5516)
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user