diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 1a3da37c2..992b0d8af 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1824,6 +1824,8 @@ void Player::Update(uint32 p_time) m_zoneUpdateTimer -= p_time; } + sScriptMgr->OnPlayerUpdate(this, p_time); + if (IsAlive()) { m_regenTimer += p_time; @@ -2221,6 +2223,9 @@ void Player::SendTeleportAckPacket() bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit* target /*= nullptr*/) { + // for except kick by antispeedhack + sScriptMgr->AnticheatSetSkipOnePacketForASH(this, true); + if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) { LOG_ERROR("server", "TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (%s, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).", @@ -28125,6 +28130,8 @@ bool Player::SetDisableGravity(bool disable, bool packetOnly /*= false*/) bool Player::SetCanFly(bool apply, bool packetOnly /*= false*/) { + sScriptMgr->AnticheatSetCanFlybyServer(this, apply); + if (!packetOnly && !Unit::SetCanFly(apply)) return false; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8dadb516b..f9e63895e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12759,6 +12759,8 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) if (Player* player = ToPlayer()) { + sScriptMgr->AnticheatSetUnderACKmount(player); + // mount as a vehicle if (VehicleId) { @@ -12847,6 +12849,8 @@ void Unit::Dismount() // (it could probably happen when logging in after a previous crash) if (Player* player = ToPlayer()) { + sScriptMgr->AnticheatSetUnderACKmount(player); + if (Pet* pPet = player->GetPet()) { if (pPet->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && !pPet->HasUnitState(UNIT_STATE_STUNNED)) @@ -17292,6 +17296,11 @@ void Unit::SetControlled(bool apply, UnitState state) default: break; } + + if (GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetRootACKUpd(ToPlayer()); + } } else { @@ -17383,7 +17392,10 @@ void Unit::SetStunned(bool apply) if (GetTypeId() != TYPEID_PLAYER) StopMoving(); else + { SetStandState(UNIT_STAND_STATE_STAND); + sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true); + } CastStop(); } @@ -17447,6 +17459,8 @@ void Unit::SetRooted(bool apply) data << GetPackGUID(); data << m_rootTimes; SendMessageToSet(&data, true); + + sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true); } else { @@ -17503,6 +17517,11 @@ void Unit::SetFeared(bool apply) if (!caster) caster = getAttackerForHelper(); GetMotionMaster()->MoveFleeing(caster, fearAuras.empty() ? sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY) : 0); // caster == nullptr processed in MoveFleeing + + if (GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true); + } } else { @@ -17535,6 +17554,11 @@ void Unit::SetConfused(bool apply) { SetTarget(); GetMotionMaster()->MoveConfused(); + + if (GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true); + } } else { @@ -17863,6 +17887,11 @@ void Unit::RemoveCharmedBy(Unit* charmer) } } + if (Player* player = ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(player); + } + // xinef: restore threat for (CharmThreatMap::const_iterator itr = _charmThreatInfo.begin(); itr != _charmThreatInfo.end(); ++itr) { @@ -18362,6 +18391,8 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ) if (player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || player->HasAuraType(SPELL_AURA_FLY)) player->SetCanFly(true, true); + + sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true); } } @@ -18796,6 +18827,12 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) void Unit::EnterVehicle(Unit* base, int8 seatId) { CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId + 1, base, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE); + + if (Player* player = ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(player); + sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true); + } } void Unit::EnterVehicleUnattackable(Unit* base, int8 seatId) @@ -18840,6 +18877,9 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a if (vehicle->GetBase()->GetTypeId() == TYPEID_PLAYER && player->IsInCombat()) return; + sScriptMgr->AnticheatSetUnderACKmount(player); + sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true); + InterruptNonMeleeSpells(false); player->StopCastingCharm(); player->StopCastingBindSight(); @@ -18903,6 +18943,12 @@ void Unit::ExitVehicle(Position const* /*exitPosition*/) //! init spline movement based on those coordinates in unapply handlers, and //! relocate exiting passengers based on Unit::moveSpline data. Either way, //! Coming Soon(TM) + + if (Player* player = ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(player); + sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true); + } } bool VehicleDespawnEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) @@ -18958,7 +19004,12 @@ void Unit::_ExitVehicle(Position const* exitPosition) AddUnitState(UNIT_STATE_MOVE); if (player) + { player->SetFallInformation(time(nullptr), GetPositionZ()); + + sScriptMgr->AnticheatSetUnderACKmount(player); + sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true); + } else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT)) { WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index f6e7414f7..4f61395fb 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -500,17 +500,18 @@ enum UnitState | UNIT_STATE_EVADE | UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE | UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_NO_ENVIRONMENT_UPD, - UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT, + UNIT_STATE_UNATTACKABLE = UNIT_STATE_IN_FLIGHT, // for real move using movegen check and stop (except unstoppable flight) - UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE, - UNIT_STATE_CONTROLLED = (UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING), - UNIT_STATE_LOST_CONTROL = (UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING), - UNIT_STATE_SIGHTLESS = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE), - UNIT_STATE_CANNOT_AUTOATTACK = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING), - UNIT_STATE_CANNOT_TURN = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING | UNIT_STATE_ROOT), + UNIT_STATE_MOVING = UNIT_STATE_ROAMING_MOVE | UNIT_STATE_CONFUSED_MOVE | UNIT_STATE_FLEEING_MOVE | UNIT_STATE_CHASE_MOVE | UNIT_STATE_FOLLOW_MOVE, + UNIT_STATE_CONTROLLED = (UNIT_STATE_CONFUSED | UNIT_STATE_STUNNED | UNIT_STATE_FLEEING), + UNIT_STATE_LOST_CONTROL = (UNIT_STATE_CONTROLLED | UNIT_STATE_JUMPING | UNIT_STATE_CHARGING), + UNIT_STATE_SIGHTLESS = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_EVADE), + UNIT_STATE_CANNOT_AUTOATTACK = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_CASTING), + UNIT_STATE_CANNOT_TURN = (UNIT_STATE_LOST_CONTROL | UNIT_STATE_ROTATING | UNIT_STATE_ROOT), // stay by different reasons - UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED, - UNIT_STATE_ALL_STATE = 0xffffffff //(UNIT_STATE_STOPPED | UNIT_STATE_MOVING | UNIT_STATE_IN_COMBAT | UNIT_STATE_IN_FLIGHT) + UNIT_STATE_NOT_MOVE = UNIT_STATE_ROOT | UNIT_STATE_STUNNED | UNIT_STATE_DIED | UNIT_STATE_DISTRACTED, + UNIT_STATE_IGNORE_ANTISPEEDHACK = UNIT_STATE_FLEEING | UNIT_STATE_CONFUSED | UNIT_STATE_CHARGING | UNIT_STATE_DISTRACTED | UNIT_STATE_POSSESSED, + UNIT_STATE_ALL_STATE = 0xffffffff //(UNIT_STATE_STOPPED | UNIT_STATE_MOVING | UNIT_STATE_IN_COMBAT | UNIT_STATE_IN_FLIGHT) }; enum UnitMoveType diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 15d70f4f2..67d9ecdc5 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1623,8 +1623,7 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data) ObjectGuid guid; recv_data >> guid.ReadAsPacked(); - // pussywizard: typical check for incomming movement packets - if (!_player->m_mover || !_player->m_mover->IsInWorld() || _player->m_mover->IsDuringRemoveFromWorld() || guid != _player->m_mover->GetGUID()) + if (!_player) { recv_data.rfinish(); // prevent warnings spam return; @@ -1638,6 +1637,8 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data) recv_data.read_skip(); // unk2 + sScriptMgr->AnticheatSetCanFlybyServer(_player, movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY)); + _player->m_mover->m_movementInfo.flags = movementInfo.GetMovementFlags(); } diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index d30e1458b..6c0992c2d 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -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) diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index 73fdfc18b..1e7e3031b 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -10,6 +10,7 @@ #include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" +#include "ScriptMgr.h" #include "UpdateMask.h" #include "WaypointMovementGenerator.h" #include "WorldPacket.h" @@ -131,6 +132,8 @@ void WorldSession::SendDoFlight(uint32 mountDisplayId, uint32 path, uint32 pathN GetPlayer()->Mount(mountDisplayId); GetPlayer()->GetMotionMaster()->MoveTaxiFlight(path, pathNode); + + sScriptMgr->AnticheatSetSkipOnePacketForASH(GetPlayer(), true); } bool WorldSession::SendLearnNewTaxiNode(Creature* unit) diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index dd7e6d203..faea05c80 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1332,6 +1332,8 @@ enum AcoreStrings LANG_BG_READY_CHECK_ERROR = 30084, LANG_DEBUG_BG_CONF = 30085, - LANG_DEBUG_ARENA_CONF = 30086, + LANG_DEBUG_ARENA_CONF = 30086 + + // 30087-30095 reserved for passive anticheat }; #endif diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 659cccd8a..de2683ae9 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1549,6 +1549,11 @@ void ScriptMgr::OnBeforePlayerUpdate(Player* player, uint32 p_time) FOREACH_SCRIPT(PlayerScript)->OnBeforeUpdate(player, p_time); } +void ScriptMgr::OnPlayerUpdate(Player* player, uint32 p_time) +{ + FOREACH_SCRIPT(PlayerScript)->OnUpdate(player, p_time); +} + void ScriptMgr::OnPlayerLogin(Player* player) { #ifdef ELUNA @@ -2632,6 +2637,58 @@ void ScriptMgr::OnSetServerSideVisibilityDetect(Player* player, ServerSideVisibi FOREACH_SCRIPT(PlayerScript)->OnSetServerSideVisibilityDetect(player, type, sec); } +void ScriptMgr::AnticheatSetSkipOnePacketForASH(Player* player, bool apply) +{ + FOREACH_SCRIPT(PlayerScript)->AnticheatSetSkipOnePacketForASH(player, apply); +} + +void ScriptMgr::AnticheatSetCanFlybyServer(Player* player, bool apply) +{ + FOREACH_SCRIPT(PlayerScript)->AnticheatSetCanFlybyServer(player, apply); +} + +void ScriptMgr::AnticheatSetUnderACKmount(Player* player) +{ + FOREACH_SCRIPT(PlayerScript)->AnticheatSetUnderACKmount(player); +} + +void ScriptMgr::AnticheatSetRootACKUpd(Player* player) +{ + FOREACH_SCRIPT(PlayerScript)->AnticheatSetRootACKUpd(player); +} + +void ScriptMgr::AnticheatSetJumpingbyOpcode(Player* player, bool jump) +{ + FOREACH_SCRIPT(PlayerScript)->AnticheatSetJumpingbyOpcode(player, jump); +} + +void ScriptMgr::AnticheatUpdateMovementInfo(Player* player, MovementInfo const& movementInfo) +{ + FOREACH_SCRIPT(PlayerScript)->AnticheatUpdateMovementInfo(player, movementInfo); +} + +bool ScriptMgr::AnticheatHandleDoubleJump(Player* player, Unit* mover) +{ + bool ret = true; + + FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts + if (!itr->second->AnticheatHandleDoubleJump(player, mover)) + ret = false; // we change ret value only when scripts return true + + return ret; +} + +bool ScriptMgr::AnticheatCheckMovementInfo(Player* player, MovementInfo const& movementInfo, Unit* mover, bool jump) +{ + bool ret = true; + + FOR_SCRIPTS_RET(PlayerScript, itr, end, ret) // return true by default if not scripts + if (!itr->second->AnticheatCheckMovementInfo(player, movementInfo, mover, jump)) + ret = false; // we change ret value only when scripts return true + + return ret; +} + bool ScriptMgr::CanGuildSendBankList(Guild const* guild, WorldSession* session, uint8 tabId, bool sendAllSlots) { bool ret = true; diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index bc4b1391b..598b68c4f 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -732,6 +732,7 @@ public: // Called for player::update virtual void OnBeforeUpdate(Player* /*player*/, uint32 /*p_time*/) { } + virtual void OnUpdate(Player* /*player*/, uint32 /*p_time*/) { } // Called when a player's money is modified (before the modification is done) virtual void OnMoneyChanged(Player* /*player*/, int32& /*amount*/) { } @@ -1014,6 +1015,16 @@ public: virtual void OnSetServerSideVisibility(Player* /*player*/, ServerSideVisibilityType& /*type*/, AccountTypes& /*sec*/) { } virtual void OnSetServerSideVisibilityDetect(Player* /*player*/, ServerSideVisibilityType& /*type*/, AccountTypes& /*sec*/) { } + + // Passive Anticheat System + virtual void AnticheatSetSkipOnePacketForASH(Player* /*player*/, bool /*apply*/) { } + virtual void AnticheatSetCanFlybyServer(Player* /*player*/, bool /*apply*/) { } + virtual void AnticheatSetUnderACKmount(Player* /*player*/) { } + virtual void AnticheatSetRootACKUpd(Player* /*player*/) { } + virtual void AnticheatSetJumpingbyOpcode(Player* /*player*/, bool /*jump*/) { } + virtual void AnticheatUpdateMovementInfo(Player* /*player*/, MovementInfo const& /*movementInfo*/) { } + [[nodiscard]] virtual bool AnticheatHandleDoubleJump(Player* /*player*/, Unit* /*mover*/) { return true; } + [[nodiscard]] virtual bool AnticheatCheckMovementInfo(Player* /*player*/, MovementInfo const& /*movementInfo*/, Unit* /*mover*/, bool /*jump*/) { return true; } }; class AccountScript : public ScriptObject @@ -1542,6 +1553,7 @@ public: /* AchievementCriteriaScript */ public: /* PlayerScript */ void OnBeforePlayerUpdate(Player* player, uint32 p_time); + void OnPlayerUpdate(Player* player, uint32 p_time); void OnSendInitialPacketsBeforeAddToMap(Player* player, WorldPacket& data); void OnPlayerReleasedGhost(Player* player); void OnPVPKill(Player* killer, Player* killed); @@ -1667,6 +1679,14 @@ public: /* PlayerScript */ bool CanInitTrade(Player* player, Player* target); void OnSetServerSideVisibility(Player* player, ServerSideVisibilityType& type, AccountTypes& sec); void OnSetServerSideVisibilityDetect(Player* player, ServerSideVisibilityType& type, AccountTypes& sec); + void AnticheatSetSkipOnePacketForASH(Player* player, bool apply); + void AnticheatSetCanFlybyServer(Player* player, bool apply); + void AnticheatSetUnderACKmount(Player* player); + void AnticheatSetRootACKUpd(Player* player); + void AnticheatUpdateMovementInfo(Player* player, MovementInfo const& movementInfo); + void AnticheatSetJumpingbyOpcode(Player* player, bool jump); + bool AnticheatHandleDoubleJump(Player* player, Unit* mover); + bool AnticheatCheckMovementInfo(Player* player, MovementInfo const& movementInfo, Unit* mover, bool jump); public: /* AccountScript */ void OnAccountLogin(uint32 accountId); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 008b59137..157e7967c 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -2382,6 +2382,11 @@ void AuraEffect::HandleFeignDeath(AuraApplication const* aurApp, uint8 mode, boo if (target->GetTypeId() != TYPEID_PLAYER) return; + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } + if (apply) { /* @@ -2874,6 +2879,11 @@ void AuraEffect::HandleAuraWaterWalk(AuraApplication const* aurApp, uint8 mode, Unit* target = aurApp->GetTarget(); + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } + if (!apply) { // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit @@ -2891,6 +2901,11 @@ void AuraEffect::HandleAuraFeatherFall(AuraApplication const* aurApp, uint8 mode Unit* target = aurApp->GetTarget(); + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } + if (!apply) { // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit @@ -2912,6 +2927,11 @@ void AuraEffect::HandleAuraHover(AuraApplication const* aurApp, uint8 mode, bool Unit* target = aurApp->GetTarget(); + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } + if (!apply) { // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit @@ -3226,6 +3246,11 @@ void AuraEffect::HandleAuraModIncreaseSpeed(AuraApplication const* aurApp, uint8 Unit* target = aurApp->GetTarget(); target->UpdateSpeed(MOVE_RUN, true); + + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } } void AuraEffect::HandleAuraModIncreaseMountedSpeed(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -3266,6 +3291,11 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp, target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 16314); } } + + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } } void AuraEffect::HandleAuraModIncreaseSwimSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const @@ -3276,6 +3306,11 @@ void AuraEffect::HandleAuraModIncreaseSwimSpeed(AuraApplication const* aurApp, u Unit* target = aurApp->GetTarget(); target->UpdateSpeed(MOVE_SWIM, true); + + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } } void AuraEffect::HandleAuraModDecreaseSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const @@ -3291,6 +3326,11 @@ void AuraEffect::HandleAuraModDecreaseSpeed(AuraApplication const* aurApp, uint8 target->UpdateSpeed(MOVE_RUN_BACK, true); target->UpdateSpeed(MOVE_SWIM_BACK, true); target->UpdateSpeed(MOVE_FLIGHT_BACK, true); + + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } } void AuraEffect::HandleAuraModUseNormalSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const @@ -3303,6 +3343,11 @@ void AuraEffect::HandleAuraModUseNormalSpeed(AuraApplication const* aurApp, uint target->UpdateSpeed(MOVE_RUN, true); target->UpdateSpeed(MOVE_SWIM, true); target->UpdateSpeed(MOVE_FLIGHT, true); + + if (Player* targetPlayer = target->ToPlayer()) + { + sScriptMgr->AnticheatSetUnderACKmount(targetPlayer); + } } /*********************************************************/ diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 4da2e908a..1eac37094 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1113,6 +1113,11 @@ void Spell::EffectJump(SpellEffIndex effIndex) float speedXY, speedZ; CalculateJumpSpeeds(effIndex, m_caster->GetExactDist2d(unitTarget), speedXY, speedZ); m_caster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ); + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); + } } void Spell::EffectJumpDest(SpellEffIndex effIndex) @@ -1142,6 +1147,12 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex) { speedXY = pow(speedZ * 10, 8); m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ, 0, ObjectAccessor::GetUnit(*m_caster, m_caster->GetGuidValue(UNIT_FIELD_TARGET))); + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); + } + return; } @@ -1156,6 +1167,11 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex) speedXY = 1.0f; m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ); + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); + } } void Spell::CalculateJumpSpeeds(uint8 i, float dist, float& speedXY, float& speedZ) @@ -1177,6 +1193,11 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) if (!unitTarget || unitTarget->IsInFlight()) return; + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer()); + } + // Pre effects switch (m_spellInfo->Id) { @@ -5056,6 +5077,11 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if (!unitTarget) return; + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true); + } + // charge changes fall time if( m_caster->GetTypeId() == TYPEID_PLAYER ) m_caster->ToPlayer()->SetFallInformation(time(nullptr), m_caster->GetPositionZ()); @@ -5063,6 +5089,13 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if (m_pathFinder) { m_caster->GetMotionMaster()->MoveCharge(m_pathFinder->GetEndPosition().x, m_pathFinder->GetEndPosition().y, m_pathFinder->GetEndPosition().z, 42.0f, EVENT_CHARGE, &m_pathFinder->GetPath()); + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); + } + + m_caster->AddUnitState(UNIT_STATE_CHARGING); } else { @@ -5077,6 +5110,13 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) } m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ + Z_OFFSET_FIND_HEIGHT); + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); + } + + m_caster->AddUnitState(UNIT_STATE_CHARGING); } } @@ -5085,6 +5125,13 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) if (!unitTarget) return; + m_caster->ClearUnitState(UNIT_STATE_CHARGING); + + if (m_caster->ToPlayer()) + { + sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true); + } + // not all charge effects used in negative spells if (!m_spellInfo->IsPositive() && m_caster->GetTypeId() == TYPEID_PLAYER) m_caster->Attack(unitTarget, true); @@ -5096,6 +5143,11 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/) if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH) return; + if (m_caster->ToPlayer()) + { + sScriptMgr->AnticheatSetSkipOnePacketForASH(m_caster->ToPlayer(), true); + } + if (m_targets.HasDst()) { Position pos; @@ -5109,6 +5161,11 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/) } m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ); + + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); + } } } @@ -5162,6 +5219,11 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex) } unitTarget->KnockbackFrom(x, y, speedxy, speedz); + + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer()); + } } void Spell::EffectLeapBack(SpellEffIndex effIndex) @@ -5177,6 +5239,11 @@ void Spell::EffectLeapBack(SpellEffIndex effIndex) //1891: Disengage m_caster->JumpTo(speedxy, speedz, m_spellInfo->SpellFamilyName != SPELLFAMILY_HUNTER); + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer()); + } + // xinef: changes fall time if (m_caster->GetTypeId() == TYPEID_PLAYER) m_caster->ToPlayer()->SetFallInformation(time(nullptr), m_caster->GetPositionZ()); @@ -5262,6 +5329,12 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex) float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity; unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ); + + if (unitTarget->GetTypeId() == TYPEID_PLAYER) + { + sScriptMgr->AnticheatSetSkipOnePacketForASH(unitTarget->ToPlayer(), true); + sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer()); + } } void Spell::EffectDispelMechanic(SpellEffIndex effIndex) diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp index 24e8f2d6e..718c92412 100644 --- a/src/server/scripts/Commands/cs_gm.cpp +++ b/src/server/scripts/Commands/cs_gm.cpp @@ -88,9 +88,15 @@ public: WorldPacket data(12); if (strncmp(args, "on", 3) == 0) + { data.SetOpcode(SMSG_MOVE_SET_CAN_FLY); + sScriptMgr->AnticheatSetCanFlybyServer(target, true); + } else if (strncmp(args, "off", 4) == 0) + { data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY); + sScriptMgr->AnticheatSetCanFlybyServer(target, false); + } else { handler->SendSysMessage(LANG_USE_BOL); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index cfa8da8b0..406d9b182 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -517,10 +517,16 @@ public: pPlayer->SetUnitMovementFlags(MOVEMENTFLAG_NONE); pPlayer->SetDisableGravity(true, true); + + sScriptMgr->AnticheatSetCanFlybyServer(pPlayer, true); + WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8); data << pPlayer->GetPackGUID(); pPlayer->SendMessageToSet(&data, true); + sScriptMgr->AnticheatSetUnderACKmount(pPlayer); + sScriptMgr->AnticheatSetSkipOnePacketForASH(pPlayer, true); + pPlayer->SetGuidValue(PLAYER_FARSIGHT, vp->GetGUID()); c->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } @@ -704,6 +710,9 @@ public: for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) if (Player* pPlayer = i->GetSource()) { + sScriptMgr->AnticheatSetUnderACKmount(pPlayer); + sScriptMgr->AnticheatSetSkipOnePacketForASH(pPlayer, true); + if (!pPlayer->IsAlive() || pPlayer->IsGameMaster()) continue; @@ -884,6 +893,10 @@ public: plr->RemoveAura(SPELL_FREEZE_ANIM); plr->SetDisableGravity(false, true); plr->SetGuidValue(PLAYER_FARSIGHT, ObjectGuid::Empty); + + sScriptMgr->AnticheatSetCanFlybyServer(plr, false); + sScriptMgr->AnticheatSetUnderACKmount(plr); + sScriptMgr->AnticheatSetSkipOnePacketForASH(plr, true); } } @@ -921,6 +934,10 @@ public: { bUpdatedFlying = true; plr->SetDisableGravity(true, true); + + sScriptMgr->AnticheatSetCanFlybyServer(plr, true); + sScriptMgr->AnticheatSetSkipOnePacketForASH(plr, true); + sScriptMgr->AnticheatSetUnderACKmount(plr); } plr->SendMonsterMove(me->GetPositionX() + dist * cos(arcangle), me->GetPositionY() + dist * sin(arcangle), me->GetPositionZ(), VORTEX_DEFAULT_DIFF * 2, SPLINEFLAG_FLYING);