Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From c91a6abf1c774d29102c367355ecc44c7738b781 Mon Sep 17 00:00:00 2001
- From: Lord Psyan <[email protected]>
- Date: Sun, 7 Dec 2014 00:51:16 -0500
- Subject: [PATCH] Passive_Anticheat
- ---
- .../Anticheat/characters.anticheat.sql | 30 ++
- src/server/game/Anticheat/AnticheatData.cpp | 118 ++++++
- src/server/game/Anticheat/AnticheatData.h | 63 +++
- src/server/game/Anticheat/AnticheatMgr.cpp | 434 +++++++++++++++++++++
- src/server/game/Anticheat/AnticheatMgr.h | 103 +++++
- src/server/game/Anticheat/AnticheatScripts.cpp | 14 +
- src/server/game/Anticheat/AnticheatScripts.h | 15 +
- src/server/game/CMakeLists.txt | 3 +
- src/server/game/Entities/Player/Player.cpp | 7 +
- src/server/game/Entities/Unit/Unit.cpp | 4 +
- src/server/game/Handlers/MovementHandler.cpp | 4 +
- src/server/game/Scripting/ScriptLoader.cpp | 4 +
- src/server/game/Spells/SpellEffects.cpp | 1 +
- src/server/game/World/World.cpp | 8 +
- src/server/game/World/World.h | 4 +
- src/server/scripts/CMakeLists.txt | 1 +
- src/server/scripts/Commands/cs_anticheat.cpp | 262 +++++++++++++
- src/server/worldserver/worldserver.conf.dist | 34 ++
- 18 files changed, 1109 insertions(+)
- create mode 100644 sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
- create mode 100644 src/server/game/Anticheat/AnticheatData.cpp
- create mode 100644 src/server/game/Anticheat/AnticheatData.h
- create mode 100644 src/server/game/Anticheat/AnticheatMgr.cpp
- create mode 100644 src/server/game/Anticheat/AnticheatMgr.h
- create mode 100644 src/server/game/Anticheat/AnticheatScripts.cpp
- create mode 100644 src/server/game/Anticheat/AnticheatScripts.h
- create mode 100644 src/server/scripts/Commands/cs_anticheat.cpp
- diff --git a/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql b/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
- new file mode 100644
- index 0000000..3504594
- --- /dev/null
- +++ b/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
- @@ -0,0 +1,30 @@
- +DROP TABLE IF EXISTS `players_reports_status`;
- +
- +CREATE TABLE `players_reports_status` (
- + `guid` int(10) unsigned NOT NULL DEFAULT '0',
- + `creation_time` int(10) unsigned NOT NULL DEFAULT '0',
- + `average` float NOT NULL DEFAULT '0',
- + `total_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `speed_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `fly_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `jump_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `waterwalk_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `teleportplane_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `climb_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + PRIMARY KEY (`guid`)
- +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='';
- +
- +DROP TABLE IF EXISTS `daily_players_reports`;
- +CREATE TABLE `daily_players_reports` (
- + `guid` int(10) unsigned NOT NULL DEFAULT '0',
- + `creation_time` int(10) unsigned NOT NULL DEFAULT '0',
- + `average` float NOT NULL DEFAULT '0',
- + `total_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `speed_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `fly_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `jump_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `waterwalk_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `teleportplane_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + `climb_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
- + PRIMARY KEY (`guid`)
- +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='';
- \ No newline at end of file
- diff --git a/src/server/game/Anticheat/AnticheatData.cpp b/src/server/game/Anticheat/AnticheatData.cpp
- new file mode 100644
- index 0000000..8c69972
- --- /dev/null
- +++ b/src/server/game/Anticheat/AnticheatData.cpp
- @@ -0,0 +1,118 @@
- +#include "AnticheatData.h"
- +
- +AnticheatData::AnticheatData()
- +{
- + lastOpcode = 0;
- + totalReports = 0;
- + for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
- + {
- + typeReports[i] = 0;
- + tempReports[i] = 0;
- + tempReportsTimer[i] = 0;
- + }
- + average = 0;
- + creationTime = 0;
- + hasDailyReport = false;
- +}
- +
- +AnticheatData::~AnticheatData()
- +{
- +}
- +
- +void AnticheatData::SetDailyReportState(bool b)
- +{
- + hasDailyReport = b;
- +}
- +
- +bool AnticheatData::GetDailyReportState()
- +{
- + return hasDailyReport;
- +}
- +
- +void AnticheatData::SetLastOpcode(uint32 opcode)
- +{
- + lastOpcode = opcode;
- +}
- +
- +void AnticheatData::SetPosition(float x, float y, float z, float o)
- +{
- + lastMovementInfo.pos.m_positionX = x;
- + lastMovementInfo.pos.m_positionY = y;
- + lastMovementInfo.pos.m_positionZ = z;
- + lastMovementInfo.pos.m_orientation = o;
- +}
- +
- +uint32 AnticheatData::GetLastOpcode() const
- +{
- + return lastOpcode;
- +}
- +
- +const MovementInfo& AnticheatData::GetLastMovementInfo() const
- +{
- + return lastMovementInfo;
- +}
- +
- +void AnticheatData::SetLastMovementInfo(MovementInfo& moveInfo)
- +{
- + lastMovementInfo = moveInfo;
- +}
- +
- +uint32 AnticheatData::GetTotalReports() const
- +{
- + return totalReports;
- +}
- +
- +void AnticheatData::SetTotalReports(uint32 _totalReports)
- +{
- + totalReports = _totalReports;
- +}
- +
- +void AnticheatData::SetTypeReports(uint32 type, uint32 amount)
- +{
- + typeReports[type] = amount;
- +}
- +
- +uint32 AnticheatData::GetTypeReports(uint32 type) const
- +{
- + return typeReports[type];
- +}
- +
- +float AnticheatData::GetAverage() const
- +{
- + return average;
- +}
- +
- +void AnticheatData::SetAverage(float _average)
- +{
- + average = _average;
- +}
- +
- +uint32 AnticheatData::GetCreationTime() const
- +{
- + return creationTime;
- +}
- +
- +void AnticheatData::SetCreationTime(uint32 _creationTime)
- +{
- + creationTime = _creationTime;
- +}
- +
- +void AnticheatData::SetTempReports(uint32 amount, uint8 type)
- +{
- + tempReports[type] = amount;
- +}
- +
- +uint32 AnticheatData::GetTempReports(uint8 type)
- +{
- + return tempReports[type];
- +}
- +
- +void AnticheatData::SetTempReportsTimer(uint32 time, uint8 type)
- +{
- + tempReportsTimer[type] = time;
- +}
- +
- +uint32 AnticheatData::GetTempReportsTimer(uint8 type)
- +{
- + return tempReportsTimer[type];
- +}
- diff --git a/src/server/game/Anticheat/AnticheatData.h b/src/server/game/Anticheat/AnticheatData.h
- new file mode 100644
- index 0000000..700ad2d
- --- /dev/null
- +++ b/src/server/game/Anticheat/AnticheatData.h
- @@ -0,0 +1,63 @@
- +#ifndef SC_ACDATA_H
- +#define SC_ACDATA_H
- +
- +#include "AnticheatMgr.h"
- +
- +#define MAX_REPORT_TYPES 6
- +
- +class AnticheatData
- +{
- +public:
- + AnticheatData();
- + ~AnticheatData();
- +
- + void SetLastOpcode(uint32 opcode);
- + uint32 GetLastOpcode() const;
- +
- + const MovementInfo& GetLastMovementInfo() const;
- + void SetLastMovementInfo(MovementInfo& moveInfo);
- +
- + void SetPosition(float x, float y, float z, float o);
- +
- + /*
- + bool GetDisableACCheck() const;
- + void SetDisableACCheck(bool check);
- +
- + uint32 GetDisableACTimer() const;
- + void SetDisableACTimer(uint32 timer);*/
- +
- + uint32 GetTotalReports() const;
- + void SetTotalReports(uint32 _totalReports);
- +
- + uint32 GetTypeReports(uint32 type) const;
- + void SetTypeReports(uint32 type, uint32 amount);
- +
- + float GetAverage() const;
- + void SetAverage(float _average);
- +
- + uint32 GetCreationTime() const;
- + void SetCreationTime(uint32 creationTime);
- +
- + void SetTempReports(uint32 amount, uint8 type);
- + uint32 GetTempReports(uint8 type);
- +
- + void SetTempReportsTimer(uint32 time, uint8 type);
- + uint32 GetTempReportsTimer(uint8 type);
- +
- + void SetDailyReportState(bool b);
- + bool GetDailyReportState();
- +private:
- + uint32 lastOpcode;
- + MovementInfo lastMovementInfo;
- + //bool disableACCheck;
- + //uint32 disableACCheckTimer;
- + uint32 totalReports;
- + uint32 typeReports[MAX_REPORT_TYPES];
- + float average;
- + uint32 creationTime;
- + uint32 tempReports[MAX_REPORT_TYPES];
- + uint32 tempReportsTimer[MAX_REPORT_TYPES];
- + bool hasDailyReport;
- +};
- +
- +#endif
- \ No newline at end of file
- diff --git a/src/server/game/Anticheat/AnticheatMgr.cpp b/src/server/game/Anticheat/AnticheatMgr.cpp
- new file mode 100644
- index 0000000..f409e93
- --- /dev/null
- +++ b/src/server/game/Anticheat/AnticheatMgr.cpp
- @@ -0,0 +1,434 @@
- +/*
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful, but WITHOUT
- + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + * more details.
- + *
- + * You should have received a copy of the GNU General Public License along
- + * with this program. If not, see <http://www.gnu.org/licenses/>.
- + */
- +
- +#include "AnticheatMgr.h"
- +#include "AnticheatScripts.h"
- +#include "MapManager.h"
- +
- +#define CLIMB_ANGLE 1.9f
- +
- +AnticheatMgr::AnticheatMgr()
- +{
- +}
- +
- +AnticheatMgr::~AnticheatMgr()
- +{
- + m_Players.clear();
- +}
- +
- +void AnticheatMgr::JumpHackDetection(Player* player, MovementInfo /* movementInfo */,uint32 opcode)
- +{
- + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & JUMP_HACK_DETECTION) == 0)
- + return;
- +
- + uint32 key = player->GetGUIDLow();
- +
- + if (m_Players[key].GetLastOpcode() == MSG_MOVE_JUMP && opcode == MSG_MOVE_JUMP)
- + {
- + BuildReport(player,JUMP_HACK_REPORT);
- + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Jump-Hack detected player GUID (low) %u",player->GetGUIDLow());
- + }
- +}
- +
- +void AnticheatMgr::WalkOnWaterHackDetection(Player* player, MovementInfo /* movementInfo */)
- +{
- + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & WALK_WATER_HACK_DETECTION) == 0)
- + return;
- +
- + uint32 key = player->GetGUIDLow();
- + if (!m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_WATERWALKING))
- + return;
- +
- + // if we are a ghost we can walk on water
- + if (!player->IsAlive())
- + return;
- +
- + if (player->HasAuraType(SPELL_AURA_FEATHER_FALL) ||
- + player->HasAuraType(SPELL_AURA_SAFE_FALL) ||
- + player->HasAuraType(SPELL_AURA_WATER_WALK))
- + return;
- +
- + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Walk on Water - Hack detected player GUID (low) %u",player->GetGUIDLow());
- + BuildReport(player,WALK_WATER_HACK_REPORT);
- +
- +}
- +
- +void AnticheatMgr::FlyHackDetection(Player* player, MovementInfo /* movementInfo */)
- +{
- + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & FLY_HACK_DETECTION) == 0)
- + return;
- +
- + uint32 key = player->GetGUIDLow();
- + if (!m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_FLYING))
- + return;
- +
- + if (player->HasAuraType(SPELL_AURA_FLY) ||
- + player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) ||
- + player->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
- + return;
- +
- + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Fly-Hack detected player GUID (low) %u",player->GetGUIDLow());
- + BuildReport(player,FLY_HACK_REPORT);
- +}
- +
- +void AnticheatMgr::TeleportPlaneHackDetection(Player* player, MovementInfo movementInfo)
- +{
- + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & TELEPORT_PLANE_HACK_DETECTION) == 0)
- + return;
- +
- + uint32 key = player->GetGUIDLow();
- +
- + if (m_Players[key].GetLastMovementInfo().pos.GetPositionZ() != 0 ||
- + movementInfo.pos.GetPositionZ() != 0)
- + return;
- +
- + if (movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING))
- + return;
- +
- + //DEAD_FALLING was deprecated
- + //if (player->getDeathState() == DEAD_FALLING)
- + // return;
- + float x, y, z;
- + player->GetPosition(x, y, z);
- + float ground_Z = player->GetMap()->GetHeight(x, y, z);
- + float z_diff = fabs(ground_Z - z);
- +
- + // we are not really walking there
- + if (z_diff > 1.0f)
- + {
- + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Teleport To Plane - Hack detected player GUID (low) %u",player->GetGUIDLow());
- + BuildReport(player,TELEPORT_PLANE_HACK_REPORT);
- + }
- +}
- +
- +void AnticheatMgr::StartHackDetection(Player* player, MovementInfo movementInfo, uint32 opcode)
- +{
- + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + return;
- +
- + if (player->IsGameMaster())
- + return;
- +
- + uint32 key = player->GetGUIDLow();
- +
- + if (player->IsInFlight() || player->GetTransport() || player->GetVehicle())
- + {
- + m_Players[key].SetLastMovementInfo(movementInfo);
- + m_Players[key].SetLastOpcode(opcode);
- + return;
- + }
- +
- + SpeedHackDetection(player,movementInfo);
- + FlyHackDetection(player,movementInfo);
- + WalkOnWaterHackDetection(player,movementInfo);
- + JumpHackDetection(player,movementInfo,opcode);
- + TeleportPlaneHackDetection(player, movementInfo);
- + ClimbHackDetection(player,movementInfo,opcode);
- +
- + m_Players[key].SetLastMovementInfo(movementInfo);
- + m_Players[key].SetLastOpcode(opcode);
- +}
- +
- +// basic detection
- +void AnticheatMgr::ClimbHackDetection(Player *player, MovementInfo movementInfo, uint32 opcode)
- +{
- + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & CLIMB_HACK_DETECTION) == 0)
- + return;
- +
- + uint32 key = player->GetGUIDLow();
- +
- + if (opcode != MSG_MOVE_HEARTBEAT ||
- + m_Players[key].GetLastOpcode() != MSG_MOVE_HEARTBEAT)
- + return;
- +
- + // in this case we don't care if they are "legal" flags, they are handled in another parts of the Anticheat Manager.
- + if (player->IsInWater() ||
- + player->IsFlying() ||
- + player->IsFalling())
- + return;
- +
- + Position playerPos;
- + Position pos = player->GetPosition();
- +
- + float deltaZ = fabs(playerPos.GetPositionZ() - movementInfo.pos.GetPositionZ());
- + float deltaXY = movementInfo.pos.GetExactDist2d(&playerPos);
- +
- + float angle = Position::NormalizeOrientation(tan(deltaZ/deltaXY));
- +
- + if (angle > CLIMB_ANGLE)
- + {
- + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Climb-Hack detected player GUID (low) %u", player->GetGUIDLow());
- + BuildReport(player,CLIMB_HACK_REPORT);
- + }
- +}
- +
- +void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo)
- +{
- + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & SPEED_HACK_DETECTION) == 0)
- + return;
- +
- + uint32 key = player->GetGUIDLow();
- +
- + // We also must check the map because the movementFlag can be modified by the client.
- + // If we just check the flag, they could always add that flag and always skip the speed hacking detection.
- + // 369 == DEEPRUN TRAM
- + if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && player->GetMapId() == 369)
- + return;
- +
- + uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&m_Players[key].GetLastMovementInfo().pos);
- + uint8 moveType = 0;
- +
- + // we need to know HOW is the player moving
- + // TO-DO: Should we check the incoming movement flags?
- + if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
- + moveType = MOVE_SWIM;
- + else if (player->IsFlying())
- + moveType = MOVE_FLIGHT;
- + else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- + moveType = MOVE_WALK;
- + else
- + moveType = MOVE_RUN;
- +
- + // how many yards the player can do in one sec.
- + uint32 speedRate = (uint32)(player->GetSpeed(UnitMoveType(moveType)) + movementInfo.jump.xyspeed);
- +
- + // how long the player took to move to here.
- + uint32 timeDiff = getMSTimeDiff(m_Players[key].GetLastMovementInfo().time,movementInfo.time);
- +
- + if (!timeDiff)
- + timeDiff = 1;
- +
- + // this is the distance doable by the player in 1 sec, using the time done to move to this point.
- + uint32 clientSpeedRate = distance2D * 1000 / timeDiff;
- +
- + // we did the (uint32) cast to accept a margin of tolerance
- + if (clientSpeedRate > speedRate)
- + {
- + BuildReport(player,SPEED_HACK_REPORT);
- + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Speed-Hack detected player GUID (low) %u",player->GetGUIDLow());
- + }
- +}
- +
- +void AnticheatMgr::StartScripts()
- +{
- + new AnticheatScripts();
- +}
- +
- +void AnticheatMgr::HandlePlayerLogin(Player* player)
- +{
- + // we must delete this to prevent errors in case of crash
- + CharacterDatabase.PExecute("DELETE FROM players_reports_status WHERE guid=%u",player->GetGUIDLow());
- + // we initialize the pos of lastMovementPosition var.
- + m_Players[player->GetGUIDLow()].SetPosition(player->GetPositionX(),player->GetPositionY(),player->GetPositionZ(),player->GetOrientation());
- + QueryResult resultDB = CharacterDatabase.PQuery("SELECT * FROM daily_players_reports WHERE guid=%u;",player->GetGUIDLow());
- +
- + if (resultDB)
- + m_Players[player->GetGUIDLow()].SetDailyReportState(true);
- +}
- +
- +void AnticheatMgr::HandlePlayerLogout(Player* player)
- +{
- + // TO-DO Make a table that stores the cheaters of the day, with more detailed information.
- +
- + // We must also delete it at logout to prevent have data of offline players in the db when we query the database (IE: The GM Command)
- + CharacterDatabase.PExecute("DELETE FROM players_reports_status WHERE guid=%u",player->GetGUIDLow());
- + // Delete not needed data from the memory.
- + m_Players.erase(player->GetGUIDLow());
- +}
- +
- +void AnticheatMgr::SavePlayerData(Player* player)
- +{
- + CharacterDatabase.PExecute("REPLACE INTO players_reports_status (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,creation_time) VALUES (%u,%f,%u,%u,%u,%u,%u,%u,%u,%u);",player->GetGUIDLow(),m_Players[player->GetGUIDLow()].GetAverage(),m_Players[player->GetGUIDLow()].GetTotalReports(), m_Players[player->GetGUIDLow()].GetTypeReports(SPEED_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(FLY_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(JUMP_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(WALK_WATER_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(CLIMB_HACK_REPORT),m_Players[player->GetGUIDLow()].GetCreationTime());
- +}
- +
- +uint32 AnticheatMgr::GetTotalReports(uint32 lowGUID)
- +{
- + return m_Players[lowGUID].GetTotalReports();
- +}
- +
- +float AnticheatMgr::GetAverage(uint32 lowGUID)
- +{
- + return m_Players[lowGUID].GetAverage();
- +}
- +
- +uint32 AnticheatMgr::GetTypeReports(uint32 lowGUID, uint8 type)
- +{
- + return m_Players[lowGUID].GetTypeReports(type);
- +}
- +
- +bool AnticheatMgr::MustCheckTempReports(uint8 type)
- +{
- + if (type == JUMP_HACK_REPORT)
- + return false;
- +
- + return true;
- +}
- +
- +void AnticheatMgr::BuildReport(Player* player,uint8 reportType)
- +{
- + uint32 key = player->GetGUIDLow();
- +
- + if (MustCheckTempReports(reportType))
- + {
- + uint32 actualTime = getMSTime();
- +
- + if (!m_Players[key].GetTempReportsTimer(reportType))
- + m_Players[key].SetTempReportsTimer(actualTime,reportType);
- +
- + if (getMSTimeDiff(m_Players[key].GetTempReportsTimer(reportType),actualTime) < 3000)
- + {
- + m_Players[key].SetTempReports(m_Players[key].GetTempReports(reportType)+1,reportType);
- +
- + if (m_Players[key].GetTempReports(reportType) < 3)
- + return;
- + } else
- + {
- + m_Players[key].SetTempReportsTimer(actualTime,reportType);
- + m_Players[key].SetTempReports(1,reportType);
- + return;
- + }
- + }
- +
- + // generating creationTime for average calculation
- + if (!m_Players[key].GetTotalReports())
- + m_Players[key].SetCreationTime(getMSTime());
- +
- + // increasing total_reports
- + m_Players[key].SetTotalReports(m_Players[key].GetTotalReports()+1);
- + // increasing specific cheat report
- + m_Players[key].SetTypeReports(reportType,m_Players[key].GetTypeReports(reportType)+1);
- +
- + // diff time for average calculation
- + uint32 diffTime = getMSTimeDiff(m_Players[key].GetCreationTime(),getMSTime()) / IN_MILLISECONDS;
- +
- + if (diffTime > 0)
- + {
- + // Average == Reports per second
- + float average = float(m_Players[key].GetTotalReports()) / float(diffTime);
- + m_Players[key].SetAverage(average);
- + }
- +
- + if (sWorld->getIntConfig(CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT) < m_Players[key].GetTotalReports())
- + {
- + if (!m_Players[key].GetDailyReportState())
- + {
- + CharacterDatabase.PExecute("REPLACE INTO daily_players_reports (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,creation_time) VALUES (%u,%f,%u,%u,%u,%u,%u,%u,%u,%u);",player->GetGUIDLow(),m_Players[player->GetGUIDLow()].GetAverage(),m_Players[player->GetGUIDLow()].GetTotalReports(), m_Players[player->GetGUIDLow()].GetTypeReports(SPEED_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(FLY_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(JUMP_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(WALK_WATER_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT),m_Players[player->GetGUIDLow()].GetTypeReports(CLIMB_HACK_REPORT),m_Players[player->GetGUIDLow()].GetCreationTime());
- + m_Players[key].SetDailyReportState(true);
- + }
- + }
- +
- + if (m_Players[key].GetTotalReports() > sWorld->getIntConfig(CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION))
- + {
- + // display warning at the center of the screen, hacky way?
- + std::string str = "";
- + str = "|cFFFFFC00[AC]|cFF00FFFF[|cFF60FF00" + std::string(player->GetName().c_str()) + "|cFF00FFFF] Possible cheater!";
- + WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
- + data << str;
- + sWorld->SendGlobalGMMessage(&data);
- + }
- +}
- +
- +void AnticheatMgr::AnticheatGlobalCommand(ChatHandler* handler)
- +{
- + // MySQL will sort all for us, anyway this is not the best way we must only save the anticheat data not whole player's data!.
- + sObjectAccessor->SaveAllPlayers();
- +
- + QueryResult resultDB = CharacterDatabase.Query("SELECT guid,average,total_reports FROM players_reports_status WHERE total_reports != 0 ORDER BY average ASC LIMIT 3;");
- + if (!resultDB)
- + {
- + handler->PSendSysMessage("No players found.");
- + return;
- + } else
- + {
- + handler->SendSysMessage("=============================");
- + handler->PSendSysMessage("Players with the lowest averages:");
- + do
- + {
- + Field *fieldsDB = resultDB->Fetch();
- +
- + uint32 guid = fieldsDB[0].GetUInt32();
- + float average = fieldsDB[1].GetFloat();
- + uint32 total_reports = fieldsDB[2].GetUInt32();
- +
- + if (Player* player = sObjectMgr->GetPlayerByLowGUID(guid))
- + handler->PSendSysMessage("Player: %s Average: %f Total Reports: %u",player->GetName().c_str(),average,total_reports);
- +
- + } while (resultDB->NextRow());
- + }
- +
- + resultDB = CharacterDatabase.Query("SELECT guid,average,total_reports FROM players_reports_status WHERE total_reports != 0 ORDER BY total_reports DESC LIMIT 3;");
- +
- + // this should never happen
- + if (!resultDB)
- + {
- + handler->PSendSysMessage("No players found.");
- + return;
- + } else
- + {
- + handler->SendSysMessage("=============================");
- + handler->PSendSysMessage("Players with the more reports:");
- + do
- + {
- + Field *fieldsDB = resultDB->Fetch();
- +
- + uint32 guid = fieldsDB[0].GetUInt32();
- + float average = fieldsDB[1].GetFloat();
- + uint32 total_reports = fieldsDB[2].GetUInt32();
- +
- + if (Player* player = sObjectMgr->GetPlayerByLowGUID(guid))
- + handler->PSendSysMessage("Player: %s Total Reports: %u Average: %f",player->GetName().c_str(),total_reports,average);
- +
- + } while (resultDB->NextRow());
- + }
- +}
- +
- +void AnticheatMgr::AnticheatDeleteCommand(uint32 guid)
- +{
- + if (!guid)
- + {
- + for (AnticheatPlayersDataMap::iterator it = m_Players.begin(); it != m_Players.end(); ++it)
- + {
- + (*it).second.SetTotalReports(0);
- + (*it).second.SetAverage(0);
- + (*it).second.SetCreationTime(0);
- + for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
- + {
- + (*it).second.SetTempReports(0,i);
- + (*it).second.SetTempReportsTimer(0,i);
- + (*it).second.SetTypeReports(i,0);
- + }
- + }
- + CharacterDatabase.PExecute("DELETE FROM players_reports_status;");
- + }
- + else
- + {
- + m_Players[guid].SetTotalReports(0);
- + m_Players[guid].SetAverage(0);
- + m_Players[guid].SetCreationTime(0);
- + for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
- + {
- + m_Players[guid].SetTempReports(0,i);
- + m_Players[guid].SetTempReportsTimer(0,i);
- + m_Players[guid].SetTypeReports(i,0);
- + }
- + CharacterDatabase.PExecute("DELETE FROM players_reports_status WHERE guid=%u;",guid);
- + }
- +}
- +
- +void AnticheatMgr::ResetDailyReportStates()
- +{
- + for (AnticheatPlayersDataMap::iterator it = m_Players.begin(); it != m_Players.end(); ++it)
- + m_Players[(*it).first].SetDailyReportState(false);
- +}
- diff --git a/src/server/game/Anticheat/AnticheatMgr.h b/src/server/game/Anticheat/AnticheatMgr.h
- new file mode 100644
- index 0000000..554bdfa
- --- /dev/null
- +++ b/src/server/game/Anticheat/AnticheatMgr.h
- @@ -0,0 +1,103 @@
- +/*
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful, but WITHOUT
- + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + * more details.
- + *
- + * You should have received a copy of the GNU General Public License along
- + * with this program. If not, see <http://www.gnu.org/licenses/>.
- + */
- +
- +#ifndef SC_ACMGR_H
- +#define SC_ACMGR_H
- +
- +//#include <ace/Singleton.h>
- +#include "Common.h"
- +#include "SharedDefines.h"
- +#include "ScriptPCH.h"
- +#include "AnticheatData.h"
- +#include "Chat.h"
- +
- +class Player;
- +class AnticheatData;
- +
- +enum ReportTypes
- +{
- + SPEED_HACK_REPORT = 0,
- + FLY_HACK_REPORT,
- + WALK_WATER_HACK_REPORT,
- + JUMP_HACK_REPORT,
- + TELEPORT_PLANE_HACK_REPORT,
- + CLIMB_HACK_REPORT,
- +
- + // MAX_REPORT_TYPES
- +};
- +
- +enum DetectionTypes
- +{
- + SPEED_HACK_DETECTION = 1,
- + FLY_HACK_DETECTION = 2,
- + WALK_WATER_HACK_DETECTION = 4,
- + JUMP_HACK_DETECTION = 8,
- + TELEPORT_PLANE_HACK_DETECTION = 16,
- + CLIMB_HACK_DETECTION = 32
- +};
- +
- +// GUIDLow is the key.
- +typedef std::map<uint32, AnticheatData> AnticheatPlayersDataMap;
- +
- +class AnticheatMgr
- +{
- +// friend class ACE_Singleton<AnticheatMgr, ACE_Null_Mutex>;
- + AnticheatMgr();
- + ~AnticheatMgr();
- +
- + public:
- + static AnticheatMgr* instance()
- + {
- + static AnticheatMgr* instance = new AnticheatMgr();
- + return instance;
- + }
- +
- + void StartHackDetection(Player* player, MovementInfo movementInfo, uint32 opcode);
- + void DeletePlayerReport(Player* player, bool login);
- + void DeletePlayerData(Player* player);
- + void CreatePlayerData(Player* player);
- + void SavePlayerData(Player* player);
- +
- + void StartScripts();
- +
- + void HandlePlayerLogin(Player* player);
- + void HandlePlayerLogout(Player* player);
- +
- + uint32 GetTotalReports(uint32 lowGUID);
- + float GetAverage(uint32 lowGUID);
- + uint32 GetTypeReports(uint32 lowGUID, uint8 type);
- +
- + void AnticheatGlobalCommand(ChatHandler* handler);
- + void AnticheatDeleteCommand(uint32 guid);
- +
- + void ResetDailyReportStates();
- + private:
- + void SpeedHackDetection(Player* player, MovementInfo movementInfo);
- + void FlyHackDetection(Player* player, MovementInfo movementInfo);
- + void WalkOnWaterHackDetection(Player* player, MovementInfo movementInfo);
- + void JumpHackDetection(Player* player, MovementInfo movementInfo,uint32 opcode);
- + void TeleportPlaneHackDetection(Player* player, MovementInfo);
- + void ClimbHackDetection(Player* player,MovementInfo movementInfo,uint32 opcode);
- +
- + void BuildReport(Player* player,uint8 reportType);
- +
- + bool MustCheckTempReports(uint8 type);
- +
- + AnticheatPlayersDataMap m_Players; ///< Player data
- +};
- +
- +#define sAnticheatMgr AnticheatMgr::instance()
- +
- +#endif
- diff --git a/src/server/game/Anticheat/AnticheatScripts.cpp b/src/server/game/Anticheat/AnticheatScripts.cpp
- new file mode 100644
- index 0000000..340178d
- --- /dev/null
- +++ b/src/server/game/Anticheat/AnticheatScripts.cpp
- @@ -0,0 +1,14 @@
- +#include "AnticheatScripts.h"
- +#include "AnticheatMgr.h"
- +
- +AnticheatScripts::AnticheatScripts(): PlayerScript("AnticheatScripts") {}
- +
- +void AnticheatScripts::OnLogout(Player* player)
- +{
- + sAnticheatMgr->HandlePlayerLogout(player);
- +}
- +
- +void AnticheatScripts::OnLogin(Player* player,bool)
- +{
- + sAnticheatMgr->HandlePlayerLogin(player);
- +}
- diff --git a/src/server/game/Anticheat/AnticheatScripts.h b/src/server/game/Anticheat/AnticheatScripts.h
- new file mode 100644
- index 0000000..25d34d0
- --- /dev/null
- +++ b/src/server/game/Anticheat/AnticheatScripts.h
- @@ -0,0 +1,15 @@
- +#ifndef SC_ACSCRIPTS_H
- +#define SC_ACSCRIPTS_H
- +
- +#include "ScriptPCH.h"
- +
- +class AnticheatScripts: public PlayerScript
- +{
- + public:
- + AnticheatScripts();
- +
- + void OnLogout(Player* player);
- + void OnLogin(Player* player,bool);
- +};
- +
- +#endif
- \ No newline at end of file
- diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
- index d748be4..259390b 100644
- --- a/src/server/game/CMakeLists.txt
- +++ b/src/server/game/CMakeLists.txt
- @@ -9,6 +9,7 @@
- # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- file(GLOB_RECURSE sources_Accounts Accounts/*.cpp Accounts/*.h)
- +file(GLOB_RECURSE sources_Anticheat Anticheat/*.cpp Anticheat/*.h)
- file(GLOB_RECURSE sources_Achievements Achievements/*.cpp Achievements/*.h)
- file(GLOB_RECURSE sources_Addons Addons/*.cpp Addons/*.h)
- file(GLOB_RECURSE sources_AI AI/*.cpp AI/*.h)
- @@ -60,6 +61,7 @@ endif ()
- set(game_STAT_SRCS
- ${game_STAT_SRCS}
- ${sources_Accounts}
- + ${sources_Anticheat}
- ${sources_Achievements}
- ${sources_Addons}
- ${sources_AI}
- @@ -131,6 +133,7 @@ include_directories(
- ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/Accounts
- + ${CMAKE_CURRENT_SOURCE_DIR}/Anticheat
- ${CMAKE_CURRENT_SOURCE_DIR}/Achievements
- ${CMAKE_CURRENT_SOURCE_DIR}/Addons
- ${CMAKE_CURRENT_SOURCE_DIR}/AI
- diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
- index ea85f8b..7842600 100644
- --- a/src/server/game/Entities/Player/Player.cpp
- +++ b/src/server/game/Entities/Player/Player.cpp
- @@ -19,6 +19,7 @@
- #include "Player.h"
- #include "AccountMgr.h"
- #include "AchievementMgr.h"
- +#include "AnticheatMgr.h"
- #include "ArenaTeam.h"
- #include "ArenaTeamMgr.h"
- #include "Battlefield.h"
- @@ -19589,6 +19590,12 @@ void Player::SaveToDB(bool create /*=false*/)
- CharacterDatabase.CommitTransaction(trans);
- + // we save the data here to prevent spamming
- + sAnticheatMgr->SavePlayerData(this);
- +
- + // in this way we prevent to spam the db by each report made!
- + // sAnticheatMgr->SavePlayerData(this);
- +
- // save pet (hunter pet level and experience and all type pets health/mana).
- if (Pet* pet = GetPet())
- pet->SavePetToDB(PET_SAVE_AS_CURRENT);
- diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
- index beac32b..3ebf351 100644
- --- a/src/server/game/Entities/Unit/Unit.cpp
- +++ b/src/server/game/Entities/Unit/Unit.cpp
- @@ -16,6 +16,7 @@
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- +#include "AnticheatMgr.h"
- #include "Unit.h"
- #include "Common.h"
- #include "Battlefield.h"
- @@ -12195,6 +12196,9 @@ void Unit::SetVisible(bool x)
- void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
- {
- + //if (this->ToPlayer())
- + // sAnticheatMgr->DisableAnticheatDetection(this->ToPlayer());
- +
- int32 main_speed_mod = 0;
- float stack_bonus = 1.0f;
- float non_stack_bonus = 1.0f;
- diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
- index 68d8931..e4d18d5 100644
- --- a/src/server/game/Handlers/MovementHandler.cpp
- +++ b/src/server/game/Handlers/MovementHandler.cpp
- @@ -16,6 +16,7 @@
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- +#include "AnticheatMgr.h"
- #include "Common.h"
- #include "WorldPacket.h"
- #include "WorldSession.h"
- @@ -341,6 +342,9 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
- plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
- }
- + if (plrMover)
- + sAnticheatMgr->StartHackDetection(plrMover, movementInfo, opcode);
- +
- uint32 mstime = getMSTime();
- /*----------------------*/
- if (m_clientTimeDelay == 0)
- diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
- index bd43fbe..df86789 100644
- --- a/src/server/game/Scripting/ScriptLoader.cpp
- +++ b/src/server/game/Scripting/ScriptLoader.cpp
- @@ -17,6 +17,7 @@
- #include "ScriptLoader.h"
- #include "World.h"
- +#include "AnticheatMgr.h"
- // spells
- void AddSC_deathknight_spell_scripts();
- @@ -40,6 +41,7 @@ void AddSC_SmartScripts();
- void AddSC_account_commandscript();
- void AddSC_achievement_commandscript();
- void AddSC_ahbot_commandscript();
- +void AddSC_anticheat_commandscript();
- void AddSC_arena_commandscript();
- void AddSC_ban_commandscript();
- void AddSC_bf_commandscript();
- @@ -695,6 +697,7 @@ void AddScripts()
- AddSpellScripts();
- AddSC_SmartScripts();
- AddCommandScripts();
- + sAnticheatMgr->StartScripts();
- #ifdef SCRIPTS
- AddWorldScripts();
- AddEasternKingdomsScripts();
- @@ -729,6 +732,7 @@ void AddSpellScripts()
- void AddCommandScripts()
- {
- + AddSC_anticheat_commandscript();
- AddSC_account_commandscript();
- AddSC_achievement_commandscript();
- AddSC_ahbot_commandscript();
- diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
- index 2b5b65f..ea668e0 100644
- --- a/src/server/game/Spells/SpellEffects.cpp
- +++ b/src/server/game/Spells/SpellEffects.cpp
- @@ -16,6 +16,7 @@
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- +#include "AnticheatMgr.h"
- #include "Common.h"
- #include "DatabaseEnv.h"
- #include "WorldPacket.h"
- diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
- index afd87b8..97dc07c 100644
- --- a/src/server/game/World/World.cpp
- +++ b/src/server/game/World/World.cpp
- @@ -27,6 +27,7 @@
- #include "AuctionHouseMgr.h"
- #include "BattlefieldMgr.h"
- #include "BattlegroundMgr.h"
- +#include "AnticheatMgr.h"
- #include "CalendarMgr.h"
- #include "Channel.h"
- #include "CharacterDatabaseCleaner.h"
- @@ -1253,6 +1254,11 @@ void World::LoadConfigSettings(bool reload)
- m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = sConfigMgr->GetBoolDefault("PlayerDump.DisallowOverwrite", true);
- m_bool_configs[CONFIG_UI_QUESTLEVELS_IN_DIALOGS] = sConfigMgr->GetBoolDefault("UI.ShowQuestLevelsInDialogs", false);
- + m_bool_configs[CONFIG_ANTICHEAT_ENABLE] = sConfigMgr->GetBoolDefault("Anticheat.Enable", true);
- + m_int_configs[CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION] = sConfigMgr->GetIntDefault("Anticheat.ReportsForIngameWarnings", 70);
- + m_int_configs[CONFIG_ANTICHEAT_DETECTIONS_ENABLED] = sConfigMgr->GetIntDefault("Anticheat.DetectionsEnabled",31);
- + m_int_configs[CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT] = sConfigMgr->GetIntDefault("Anticheat.MaxReportsForDailyReport",70);
- +
- // Wintergrasp battlefield
- m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = sConfigMgr->GetBoolDefault("Wintergrasp.Enable", false);
- m_int_configs[CONFIG_WINTERGRASP_PLR_MAX] = sConfigMgr->GetIntDefault("Wintergrasp.PlayerMax", 100);
- @@ -2940,6 +2946,8 @@ void World::ResetDailyQuests()
- // change available dailies
- sPoolMgr->ChangeDailyQuests();
- +
- + sAnticheatMgr->ResetDailyReportStates();
- }
- void World::LoadDBAllowedSecurityLevel()
- diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
- index 2f13051..0645be5 100644
- --- a/src/server/game/World/World.h
- +++ b/src/server/game/World/World.h
- @@ -145,6 +145,7 @@ enum WorldBoolConfigs
- CONFIG_ALLOW_TICKETS,
- CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES,
- CONFIG_PRESERVE_CUSTOM_CHANNELS,
- + CONFIG_ANTICHEAT_ENABLE,
- CONFIG_PDUMP_NO_PATHS,
- CONFIG_PDUMP_NO_OVERWRITE,
- CONFIG_QUEST_IGNORE_AUTO_ACCEPT,
- @@ -383,7 +384,10 @@ enum WorldIntConfigs
- CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION,
- CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS,
- CONFIG_LFG_OPTIONSMASK,
- + CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION,
- + CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT,
- CONFIG_MAX_INSTANCES_PER_HOUR,
- + CONFIG_ANTICHEAT_DETECTIONS_ENABLED,
- CONFIG_WARDEN_CLIENT_RESPONSE_DELAY,
- CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF,
- CONFIG_WARDEN_CLIENT_FAIL_ACTION,
- diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
- index f11791e..522ece8 100644
- --- a/src/server/scripts/CMakeLists.txt
- +++ b/src/server/scripts/CMakeLists.txt
- @@ -69,6 +69,7 @@ include_directories(
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/src/server/shared/Database
- ${CMAKE_SOURCE_DIR}/src/server/game/Accounts
- + ${CMAKE_SOURCE_DIR}/src/server/game/Anticheat
- ${CMAKE_SOURCE_DIR}/src/server/game/Achievements
- ${CMAKE_SOURCE_DIR}/src/server/game/Addons
- ${CMAKE_SOURCE_DIR}/src/server/game/AI
- diff --git a/src/server/scripts/Commands/cs_anticheat.cpp b/src/server/scripts/Commands/cs_anticheat.cpp
- new file mode 100644
- index 0000000..3cc6784
- --- /dev/null
- +++ b/src/server/scripts/Commands/cs_anticheat.cpp
- @@ -0,0 +1,262 @@
- +/*
- + * This program is free software; you can redistribute it and/or modify it
- + * under the terms of the GNU General Public License as published by the
- + * Free Software Foundation; either version 2 of the License, or (at your
- + * option) any later version.
- + *
- + * This program is distributed in the hope that it will be useful, but WITHOUT
- + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- + * more details.
- + *
- + * You should have received a copy of the GNU General Public License along
- + * with this program. If not, see <http://www.gnu.org/licenses/>.
- + */
- +#include "Language.h"
- +#include "ScriptMgr.h"
- +#include "ObjectMgr.h"
- +#include "Chat.h"
- +#include "AnticheatMgr.h"
- +
- +class anticheat_commandscript : public CommandScript
- +{
- +public:
- + anticheat_commandscript() : CommandScript("anticheat_commandscript") { }
- +
- + ChatCommand* GetCommands() const
- + {
- + static ChatCommand anticheatCommandTable[] =
- + {
- + { "global", SEC_GAMEMASTER, true, &HandleAntiCheatGlobalCommand, "", NULL },
- + { "player", SEC_GAMEMASTER, true, &HandleAntiCheatPlayerCommand, "", NULL },
- + { "delete", SEC_ADMINISTRATOR, true, &HandleAntiCheatDeleteCommand, "", NULL },
- + { "handle", SEC_ADMINISTRATOR, true, &HandleAntiCheatHandleCommand, "", NULL },
- + { "jail", SEC_GAMEMASTER, true, &HandleAnticheatJailCommand, "", NULL },
- + { "warn", SEC_GAMEMASTER, true, &HandleAnticheatWarnCommand, "", NULL },
- + { NULL, 0, false, NULL, "", NULL }
- + };
- +
- + static ChatCommand commandTable[] =
- + {
- + { "anticheat", SEC_GAMEMASTER, true, NULL, "", anticheatCommandTable},
- + { NULL, 0, false, NULL, "", NULL }
- + };
- +
- + return commandTable;
- + }
- +
- + static bool HandleAnticheatWarnCommand(ChatHandler* handler, const char* args)
- + {
- + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + return false;
- +
- + Player* pTarget = NULL;
- +
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " ");
- +
- + if (command)
- + {
- + strCommand = command;
- + normalizePlayerName(strCommand);
- +
- + pTarget = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
- + }else
- + pTarget = handler->getSelectedPlayer();
- +
- + if (!pTarget)
- + return false;
- +
- + WorldPacket data;
- +
- + // need copy to prevent corruption by strtok call in LineFromMessage original string
- + char* buf = strdup("The anticheat system has reported several times that you may be cheating. You will be monitored to confirm if this is accurate.");
- + char* pos = buf;
- +
- + while (char* line = handler->LineFromMessage(pos))
- + {
- + handler->BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
- + pTarget->GetSession()->SendPacket(&data);
- + }
- +
- + free(buf);
- + return true;
- + }
- +
- + static bool HandleAnticheatJailCommand(ChatHandler* handler, const char* args)
- + {
- + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + return false;
- +
- + Player* pTarget = NULL;
- +
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " ");
- +
- + if (command)
- + {
- + strCommand = command;
- + normalizePlayerName(strCommand);
- +
- + pTarget = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
- + }else
- + pTarget = handler->getSelectedPlayer();
- +
- + if (!pTarget)
- + {
- + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
- + handler->SetSentErrorMessage(true);
- + return false;
- + }
- +
- + if (pTarget == handler->GetSession()->GetPlayer())
- + return false;
- +
- + // teleport both to jail.
- + pTarget->TeleportTo(1,16226.5f,16403.6f,-64.5f,3.2f);
- + handler->GetSession()->GetPlayer()->TeleportTo(1,16226.5f,16403.6f,-64.5f,3.2f);
- +
- + WorldLocation loc;
- +
- + // the player should be already there, but no :(
- + // pTarget->GetPosition(&loc);
- +
- + loc.m_mapId = 1;
- + loc.m_positionX = 16226.5f;
- + loc.m_positionY = 16403.6f;
- + loc.m_positionZ = -64.5f;
- + loc.m_orientation = 3.2f;
- +
- + pTarget->SetHomebind(loc,876);
- + return true;
- + }
- +
- + static bool HandleAntiCheatDeleteCommand(ChatHandler* handler, const char* args)
- + {
- + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + return false;
- +
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " "); //get entered name
- +
- + if (!command)
- + return true;
- +
- + strCommand = command;
- +
- + if (strCommand.compare("deleteall") == 0)
- + sAnticheatMgr->AnticheatDeleteCommand(0);
- + else
- + {
- + normalizePlayerName(strCommand);
- + Player* player = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
- + if (!player)
- + handler->PSendSysMessage("Player doesn't exist");
- + else
- + sAnticheatMgr->AnticheatDeleteCommand(player->GetGUIDLow());
- + }
- +
- + return true;
- + }
- +
- + static bool HandleAntiCheatPlayerCommand(ChatHandler* handler, const char* args)
- + {
- + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + return false;
- +
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " ");
- +
- + uint32 guid = 0;
- + Player* player = NULL;
- +
- + if (command)
- + {
- + strCommand = command;
- +
- + normalizePlayerName(strCommand);
- + player = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
- +
- + if (player)
- + guid = player->GetGUIDLow();
- + }else
- + {
- + player = handler->getSelectedPlayer();
- + if (player)
- + guid = player->GetGUIDLow();
- + }
- +
- + if (!guid)
- + {
- + handler->PSendSysMessage("There is no player.");
- + return true;
- + }
- +
- + float average = sAnticheatMgr->GetAverage(guid);
- + uint32 total_reports = sAnticheatMgr->GetTotalReports(guid);
- + uint32 speed_reports = sAnticheatMgr->GetTypeReports(guid,0);
- + uint32 fly_reports = sAnticheatMgr->GetTypeReports(guid,1);
- + uint32 jump_reports = sAnticheatMgr->GetTypeReports(guid,3);
- + uint32 waterwalk_reports = sAnticheatMgr->GetTypeReports(guid,2);
- + uint32 teleportplane_reports = sAnticheatMgr->GetTypeReports(guid,4);
- + uint32 climb_reports = sAnticheatMgr->GetTypeReports(guid,5);
- +
- + handler->PSendSysMessage("Information about player %s",player->GetName().c_str());
- + handler->PSendSysMessage("Average: %f || Total Reports: %u ",average,total_reports);
- + handler->PSendSysMessage("Speed Reports: %u || Fly Reports: %u || Jump Reports: %u ",speed_reports,fly_reports,jump_reports);
- + handler->PSendSysMessage("Walk On Water Reports: %u || Teleport To Plane Reports: %u",waterwalk_reports,teleportplane_reports);
- + handler->PSendSysMessage("Climb Reports: %u", climb_reports);
- +
- + return true;
- + }
- +
- + static bool HandleAntiCheatHandleCommand(ChatHandler* handler, const char* args)
- + {
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " ");
- +
- + if (!command)
- + return true;
- +
- + if (!handler->GetSession()->GetPlayer())
- + return true;
- +
- + strCommand = command;
- +
- + if (strCommand.compare("on") == 0)
- + {
- + sWorld->setBoolConfig(CONFIG_ANTICHEAT_ENABLE,true);
- + handler->SendSysMessage("The Anticheat System is now: Enabled!");
- + }
- + else if (strCommand.compare("off") == 0)
- + {
- + sWorld->setBoolConfig(CONFIG_ANTICHEAT_ENABLE,false);
- + handler->SendSysMessage("The Anticheat System is now: Disabled!");
- + }
- +
- + return true;
- + }
- +
- + static bool HandleAntiCheatGlobalCommand(ChatHandler* handler, const char* /* args */)
- + {
- + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + {
- + handler->PSendSysMessage("The Anticheat System is disabled.");
- + return true;
- + }
- +
- + sAnticheatMgr->AnticheatGlobalCommand(handler);
- +
- + return true;
- + }
- +};
- +
- +void AddSC_anticheat_commandscript()
- +{
- + new anticheat_commandscript();
- +}
- diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
- index c40da51..48ee00b 100644
- --- a/src/server/worldserver/worldserver.conf.dist
- +++ b/src/server/worldserver/worldserver.conf.dist
- @@ -2661,6 +2661,40 @@ LevelReq.Auction = 1
- LevelReq.Mail = 1
- #
- +# Anticheat.Enable
- +# Description: Enables or disables the Anticheat System functionality
- +# Default: 1 - (Enabled)
- +# 0 - (Disabled)
- +
- +Anticheat.Enable = 1
- +
- +# Anticheat.ReportsForIngameWarnings
- +# Description: How many reports the player must have to notify to GameMasters ingame when he generates a new report.
- +# Default: 70
- +
- +Anticheat.ReportsForIngameWarnings = 70
- +
- +# Anticheat.DetectionsEnabled
- +# Description: It represents which detections are enabled.
- +#
- +# SPEED_HACK_DETECTION = 1
- +# FLY_HACK_DETECTION = 2
- +# WALK_WATER_HACK_DETECTION = 4
- +# JUMP_HACK_DETECTION = 8
- +# TELEPORT_PLANE_HACK_DETECTION = 16
- +# CLIMB_HACK_DETECTION = 32
- +#
- +# Default: 31
- +
- +Anticheat.DetectionsEnabled = 31
- +
- +# Anticheat.MaxReportsForDailyReport
- +# Description: How many reports must the player have to make a report that it is in DB for a day (not only during the player's session).
- +# Default: 70
- +
- +Anticheat.MaxReportsForDailyReport = 70
- +
- +#
- # PlayerDump.DisallowPaths
- # Description: Disallow using paths in PlayerDump output files
- # Default: 1
- --
- 2.1.3
Advertisement
Add Comment
Please, Sign In to add comment