From a354922e07020f5ba5c7c6aa43d95eaae10aa1b3 Mon Sep 17 00:00:00 2001 From: MDIC Date: Sun, 20 Feb 2022 20:55:26 -0500 Subject: [PATCH] Update: Readjusted SQL, New Dectection , new Conf Readjusted the Sql again, Removes the teleporthack_report collumns. It is pretty much worthless with its insane high count that would cause drag on the db and well not needed, it seems like a good idea at the time but it isnt, instead it will add a +1 to the total_reports collumn and the teleport and ignore control hacks will spam their own message once the reports hit default 70 or whatever the user has set. New detection type Ignore Control Hack, This is if a player is rooted or stunned, they are able to still move when effected. --- conf/Anticheat.conf.dist | 1 + .../base/charactersdb_anticheat.sql | 2 - src/AnticheatMgr.cpp | 63 ++++++++++++++----- src/AnticheatMgr.h | 19 +++--- src/cs_anticheat.cpp | 4 +- 5 files changed, 63 insertions(+), 26 deletions(-) diff --git a/conf/Anticheat.conf.dist b/conf/Anticheat.conf.dist index 89b2647..70ec1d1 100644 --- a/conf/Anticheat.conf.dist +++ b/conf/Anticheat.conf.dist @@ -62,6 +62,7 @@ Anticheat.DetectTelePlaneHack = 1 Anticheat.DetectSpeedHack = 1 Anticheat.DetectClimbHack = 0 Anticheat.DetectTelePortHack =1 +Anticheat.IgnoreControlHack = 1 # Anticheat.StricterFlyHackCheck # Description: Checks moveflag ascending (may give false positives) diff --git a/sql/characters/base/charactersdb_anticheat.sql b/sql/characters/base/charactersdb_anticheat.sql index 61cfb79..507fd00 100644 --- a/sql/characters/base/charactersdb_anticheat.sql +++ b/sql/characters/base/charactersdb_anticheat.sql @@ -10,7 +10,6 @@ CREATE TABLE IF NOT EXISTS `daily_players_reports` ( `waterwalk_reports` bigint unsigned NOT NULL DEFAULT 0, `teleportplane_reports` bigint unsigned NOT NULL DEFAULT 0, `climb_reports` bigint unsigned NOT NULL DEFAULT 0, - `teleporthack_reports` bigint unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; @@ -26,6 +25,5 @@ CREATE TABLE IF NOT EXISTS `players_reports_status` ( `waterwalk_reports` bigint unsigned NOT NULL DEFAULT 0, `teleportplane_reports` bigint unsigned NOT NULL DEFAULT 0, `climb_reports` bigint unsigned NOT NULL DEFAULT 0, - `teleporthack_reports` bigint unsigned NOT NULL DEFAULT 0, PRIMARY KEY (`guid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; diff --git a/src/AnticheatMgr.cpp b/src/AnticheatMgr.cpp index a0b5b66..5e59137 100644 --- a/src/AnticheatMgr.cpp +++ b/src/AnticheatMgr.cpp @@ -79,14 +79,14 @@ void AnticheatMgr::WalkOnWaterHackDetection(Player* player, MovementInfo moveme LOG_INFO("module", "AnticheatMgr:: Walk on Water - Hack detected and counteracted by kicking player {} ({})", player->GetName(), player->GetGUID().ToString()); player->GetSession()->KickPlayer(true); - if(sConfigMgr->GetOption("Anticheat.AnnounceKick", true)) + if (sConfigMgr->GetOption("Anticheat.AnnounceKick", true)) { std::string plr = player->GetName(); std::string tag_colour = "7bbef7"; std::string plr_colour = "ff0000"; std::ostringstream stream; stream << "|CFF" << plr_colour << "[AntiCheat]|r|CFF" << tag_colour << - " Player |r|cff" << plr_colour << plr << "|r|cff" << tag_colour << + " Player |r|cff" << plr_colour << plr << "|r|cff" << tag_colour << " has been kicked.|r"; sWorld->SendServerMessage(SERVER_MSG_STRING, stream.str().c_str()); } @@ -130,24 +130,24 @@ void AnticheatMgr::FlyHackDetection(Player* player, MovementInfo movementInfo) } player->GetSession()->KickPlayer(true); - if(sConfigMgr->GetOption("Anticheat.AnnounceKick", true)) + if (sConfigMgr->GetOption("Anticheat.AnnounceKick", true)) { std::string plr = player->GetName(); std::string tag_colour = "7bbef7"; std::string plr_colour = "ff0000"; std::ostringstream stream; stream << "|CFF" << plr_colour << "[AntiCheat]|r|CFF" << tag_colour << - " Player |r|cff" << plr_colour << plr << "|r|cff" << tag_colour << + " Player |r|cff" << plr_colour << plr << "|r|cff" << tag_colour << " has been kicked.|r"; sWorld->SendServerMessage(SERVER_MSG_STRING, stream.str().c_str()); } } - else if (sConfigMgr->GetOption("Anticheat.WriteLog", false)) + else if (sConfigMgr->GetOption("Anticheat.WriteLog", false)) { LOG_INFO("module", "AnticheatMgr:: Fly-Hack detected player {} ({})", player->GetName(), player->GetGUID().ToString()); } - BuildReport(player,FLY_HACK_REPORT); + BuildReport(player, FLY_HACK_REPORT); } void AnticheatMgr::TeleportPlaneHackDetection(Player* player, MovementInfo movementInfo) @@ -182,6 +182,37 @@ void AnticheatMgr::TeleportPlaneHackDetection(Player* player, MovementInfo movem } } +void AnticheatMgr::IgnoreControlHackDetection(Player* player, MovementInfo movementInfo) +{ + float x, y; + player->GetPosition(x, y); + ObjectGuid key = player->GetGUID(); + + if (sConfigMgr->GetOption("Anticheat.IgnoreControlHack", true)) + { + if (player->HasUnitState(UNIT_STATE_ROOT) && !player->GetVehicle()) + { + bool unrestricted = movementInfo.pos.GetPositionX() != x || movementInfo.pos.GetPositionY() != y; + if (unrestricted) + { + if (m_Players[key].GetTotalReports() > sConfigMgr->GetOption("Anticheat.ReportsForIngameWarnings", 70)) + { + // display warning at the center of the screen, hacky way? + std::string str = ""; + str = "|cFFFFFC00[Playername:|cFF00FFFF[|cFF60FF00" + std::string(player->GetName().c_str()) + "|cFF00FFFF] Possible Ignore Control Hack Detected!"; + WorldPacket data(SMSG_NOTIFICATION, (str.size() + 1)); + data << str; + sWorld->SendGlobalGMMessage(&data); + } + if (sConfigMgr->GetOption("Anticheat.WriteLog", false)) + LOG_INFO("module", "AnticheatMgr:: Ignore Control - Hack detected player {} ({})", player->GetName(), player->GetGUID().ToString()); + + BuildReport(player, IGNORE_CONTROL_REPORT); + } + } + } +} + void AnticheatMgr::TeleportHackDetection(Player* player, MovementInfo movementInfo) { if (!sConfigMgr->GetOption("Anticheat.DetectTelePortHack", true)) @@ -245,12 +276,13 @@ void AnticheatMgr::StartHackDetection(Player* player, MovementInfo movementInfo, TeleportPlaneHackDetection(player, movementInfo); ClimbHackDetection(player, movementInfo, opcode); TeleportHackDetection(player, movementInfo); + IgnoreControlHackDetection(player, movementInfo); m_Players[key].SetLastMovementInfo(movementInfo); m_Players[key].SetLastOpcode(opcode); } // basic detection -void AnticheatMgr::ClimbHackDetection(Player *player, MovementInfo movementInfo, uint32 opcode) +void AnticheatMgr::ClimbHackDetection(Player* player, MovementInfo movementInfo, uint32 opcode) { if (!sConfigMgr->GetOption("Anticheat.DetectClimbHack", false)) return; @@ -355,8 +387,8 @@ void AnticheatMgr::HandlePlayerLogout(Player* player) } void AnticheatMgr::SavePlayerData(Player* player) -{ - CharacterDatabase.Execute("REPLACE INTO players_reports_status (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,teleporthack_reports,creation_time) VALUES ({},{},{},{},{},{},{},{},{},{},{});",player->GetGUID().GetCounter(), m_Players[player->GetGUID()].GetAverage(), m_Players[player->GetGUID()].GetTotalReports(), m_Players[player->GetGUID()].GetTypeReports(SPEED_HACK_REPORT),m_Players[player->GetGUID()].GetTypeReports(FLY_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(JUMP_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(WALK_WATER_HACK_REPORT),m_Players[player->GetGUID()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(CLIMB_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(TELEPORT_HACK_REPORT), m_Players[player->GetGUID()].GetCreationTime()); +{// 1 2 3 4 5 6 7 8 9 10 + CharacterDatabase.Execute("REPLACE INTO players_reports_status (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,creation_time) VALUES ({},{},{},{},{},{},{},{},{},{});", player->GetGUID().GetCounter(), m_Players[player->GetGUID()].GetAverage(), m_Players[player->GetGUID()].GetTotalReports(), m_Players[player->GetGUID()].GetTypeReports(SPEED_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(FLY_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(JUMP_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(WALK_WATER_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(CLIMB_HACK_REPORT), m_Players[player->GetGUID()].GetCreationTime()); } uint32 AnticheatMgr::GetTotalReports(ObjectGuid guid) @@ -382,10 +414,13 @@ bool AnticheatMgr::MustCheckTempReports(uint8 type) if (type == TELEPORT_HACK_REPORT) return false; + if (type == IGNORE_CONTROL_REPORT) + return false; + return true; } -void AnticheatMgr::BuildReport(Player* player, uint8 reportType) +void AnticheatMgr::BuildReport(Player* player, uint16 reportType) { ObjectGuid key = player->GetGUID(); @@ -433,8 +468,8 @@ void AnticheatMgr::BuildReport(Player* player, uint8 reportType) if (sConfigMgr->GetOption("Anticheat.MaxReportsForDailyReport", 70) < m_Players[key].GetTotalReports()) { if (!m_Players[key].GetDailyReportState()) - { - CharacterDatabase.Execute("REPLACE INTO daily_players_reports (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,teleporthack_reports,creation_time) VALUES ({},{},{},{},{},{},{},{},{},{},{});", player->GetGUID().GetCounter(), m_Players[player->GetGUID()].GetAverage(), m_Players[player->GetGUID()].GetTotalReports(), m_Players[player->GetGUID()].GetTypeReports(SPEED_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(FLY_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(JUMP_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(WALK_WATER_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(CLIMB_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(TELEPORT_HACK_REPORT), m_Players[player->GetGUID()].GetCreationTime()); + {// 1 2 3 4 5 6 7 8 9 10 + CharacterDatabase.Execute("REPLACE INTO daily_players_reports (guid,average,total_reports,speed_reports,fly_reports,jump_reports,waterwalk_reports,teleportplane_reports,climb_reports,creation_time) VALUES ({},{},{},{},{},{},{},{},{},{});", player->GetGUID().GetCounter(), m_Players[player->GetGUID()].GetAverage(), m_Players[player->GetGUID()].GetTotalReports(), m_Players[player->GetGUID()].GetTypeReports(SPEED_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(FLY_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(JUMP_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(WALK_WATER_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(TELEPORT_PLANE_HACK_REPORT), m_Players[player->GetGUID()].GetTypeReports(CLIMB_HACK_REPORT), m_Players[player->GetGUID()].GetCreationTime()); m_Players[key].SetDailyReportState(true); } } @@ -467,7 +502,7 @@ void AnticheatMgr::AnticheatGlobalCommand(ChatHandler* handler) handler->PSendSysMessage("Players with the lowest averages:"); do { - Field *fieldsDB = resultDB->Fetch(); + Field* fieldsDB = resultDB->Fetch(); ObjectGuid guid = ObjectGuid::Create(fieldsDB[0].Get()); float average = fieldsDB[1].Get(); @@ -493,7 +528,7 @@ void AnticheatMgr::AnticheatGlobalCommand(ChatHandler* handler) handler->PSendSysMessage("Players with the more reports:"); do { - Field *fieldsDB = resultDB->Fetch(); + Field* fieldsDB = resultDB->Fetch(); ObjectGuid guid = ObjectGuid::Create(fieldsDB[0].Get()); float average = fieldsDB[1].Get(); diff --git a/src/AnticheatMgr.h b/src/AnticheatMgr.h index 2f06905..03fbfaa 100644 --- a/src/AnticheatMgr.h +++ b/src/AnticheatMgr.h @@ -30,12 +30,13 @@ 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, - TELEPORT_HACK_REPORT, + FLY_HACK_REPORT = 1, + WALK_WATER_HACK_REPORT = 2, + JUMP_HACK_REPORT = 3, + TELEPORT_PLANE_HACK_REPORT = 4, + CLIMB_HACK_REPORT = 5, + TELEPORT_HACK_REPORT = 6, + IGNORE_CONTROL_REPORT = 7 // MAX_REPORT_TYPES }; @@ -48,7 +49,8 @@ enum DetectionTypes JUMP_HACK_DETECTION = 8, TELEPORT_PLANE_HACK_DETECTION = 16, CLIMB_HACK_DETECTION = 32, - TELEPORT_HACK_DETECTION = 64 + TELEPORT_HACK_DETECTION = 64, + IGNORE_CONTROL_DETECTION = 128 }; // GUID is the key. @@ -89,7 +91,8 @@ class AnticheatMgr void TeleportPlaneHackDetection(Player* player, MovementInfo); void ClimbHackDetection(Player* player,MovementInfo movementInfo,uint32 opcode); void TeleportHackDetection(Player* player, MovementInfo movementInfo); - void BuildReport(Player* player,uint8 reportType); + void IgnoreControlHackDetection(Player* player, MovementInfo movementInfo); + void BuildReport(Player* player,uint16 reportType); bool MustCheckTempReports(uint8 type); diff --git a/src/cs_anticheat.cpp b/src/cs_anticheat.cpp index 95b1612..f87f3d7 100644 --- a/src/cs_anticheat.cpp +++ b/src/cs_anticheat.cpp @@ -210,13 +210,13 @@ public: uint32 teleportplane_reports = sAnticheatMgr->GetTypeReports(guid, 4); uint32 climb_reports = sAnticheatMgr->GetTypeReports(guid, 5); uint32 teleporthack_reports = sAnticheatMgr->GetTypeReports(guid, 6); + uint32 ignorecontrol_reports = sAnticheatMgr->GetTypeReports(guid, 7); 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 || Teleport Hack Reports: %u", climb_reports, teleporthack_reports); - + handler->PSendSysMessage("Climb Reports: %u", climb_reports); return true; }