Guest User

Untitled

a guest
Jun 18th, 2015
274
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.55 KB | None | 0 0
  1. From c91a6abf1c774d29102c367355ecc44c7738b781 Mon Sep 17 00:00:00 2001
  2. From: Lord Psyan <[email protected]>
  3. Date: Sun, 7 Dec 2014 00:51:16 -0500
  4. Subject: [PATCH] Passive_Anticheat
  5.  
  6. ---
  7. .../Anticheat/characters.anticheat.sql | 30 ++
  8. src/server/game/Anticheat/AnticheatData.cpp | 118 ++++++
  9. src/server/game/Anticheat/AnticheatData.h | 63 +++
  10. src/server/game/Anticheat/AnticheatMgr.cpp | 434 +++++++++++++++++++++
  11. src/server/game/Anticheat/AnticheatMgr.h | 103 +++++
  12. src/server/game/Anticheat/AnticheatScripts.cpp | 14 +
  13. src/server/game/Anticheat/AnticheatScripts.h | 15 +
  14. src/server/game/CMakeLists.txt | 3 +
  15. src/server/game/Entities/Player/Player.cpp | 7 +
  16. src/server/game/Entities/Unit/Unit.cpp | 4 +
  17. src/server/game/Handlers/MovementHandler.cpp | 4 +
  18. src/server/game/Scripting/ScriptLoader.cpp | 4 +
  19. src/server/game/Spells/SpellEffects.cpp | 1 +
  20. src/server/game/World/World.cpp | 8 +
  21. src/server/game/World/World.h | 4 +
  22. src/server/scripts/CMakeLists.txt | 1 +
  23. src/server/scripts/Commands/cs_anticheat.cpp | 262 +++++++++++++
  24. src/server/worldserver/worldserver.conf.dist | 34 ++
  25. 18 files changed, 1109 insertions(+)
  26. create mode 100644 sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
  27. create mode 100644 src/server/game/Anticheat/AnticheatData.cpp
  28. create mode 100644 src/server/game/Anticheat/AnticheatData.h
  29. create mode 100644 src/server/game/Anticheat/AnticheatMgr.cpp
  30. create mode 100644 src/server/game/Anticheat/AnticheatMgr.h
  31. create mode 100644 src/server/game/Anticheat/AnticheatScripts.cpp
  32. create mode 100644 src/server/game/Anticheat/AnticheatScripts.h
  33. create mode 100644 src/server/scripts/Commands/cs_anticheat.cpp
  34.  
  35. diff --git a/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql b/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
  36. new file mode 100644
  37. index 0000000..3504594
  38. --- /dev/null
  39. +++ b/sql/TrinityCore-Patches/Anticheat/characters.anticheat.sql
  40. @@ -0,0 +1,30 @@
  41. +DROP TABLE IF EXISTS `players_reports_status`;
  42. +
  43. +CREATE TABLE `players_reports_status` (
  44. + `guid` int(10) unsigned NOT NULL DEFAULT '0',
  45. + `creation_time` int(10) unsigned NOT NULL DEFAULT '0',
  46. + `average` float NOT NULL DEFAULT '0',
  47. + `total_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  48. + `speed_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  49. + `fly_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  50. + `jump_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  51. + `waterwalk_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  52. + `teleportplane_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  53. + `climb_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  54. + PRIMARY KEY (`guid`)
  55. +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='';
  56. +
  57. +DROP TABLE IF EXISTS `daily_players_reports`;
  58. +CREATE TABLE `daily_players_reports` (
  59. + `guid` int(10) unsigned NOT NULL DEFAULT '0',
  60. + `creation_time` int(10) unsigned NOT NULL DEFAULT '0',
  61. + `average` float NOT NULL DEFAULT '0',
  62. + `total_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  63. + `speed_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  64. + `fly_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  65. + `jump_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  66. + `waterwalk_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  67. + `teleportplane_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  68. + `climb_reports` bigint(20) unsigned NOT NULL DEFAULT '0',
  69. + PRIMARY KEY (`guid`)
  70. +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='';
  71. \ No newline at end of file
  72. diff --git a/src/server/game/Anticheat/AnticheatData.cpp b/src/server/game/Anticheat/AnticheatData.cpp
  73. new file mode 100644
  74. index 0000000..8c69972
  75. --- /dev/null
  76. +++ b/src/server/game/Anticheat/AnticheatData.cpp
  77. @@ -0,0 +1,118 @@
  78. +#include "AnticheatData.h"
  79. +
  80. +AnticheatData::AnticheatData()
  81. +{
  82. + lastOpcode = 0;
  83. + totalReports = 0;
  84. + for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
  85. + {
  86. + typeReports[i] = 0;
  87. + tempReports[i] = 0;
  88. + tempReportsTimer[i] = 0;
  89. + }
  90. + average = 0;
  91. + creationTime = 0;
  92. + hasDailyReport = false;
  93. +}
  94. +
  95. +AnticheatData::~AnticheatData()
  96. +{
  97. +}
  98. +
  99. +void AnticheatData::SetDailyReportState(bool b)
  100. +{
  101. + hasDailyReport = b;
  102. +}
  103. +
  104. +bool AnticheatData::GetDailyReportState()
  105. +{
  106. + return hasDailyReport;
  107. +}
  108. +
  109. +void AnticheatData::SetLastOpcode(uint32 opcode)
  110. +{
  111. + lastOpcode = opcode;
  112. +}
  113. +
  114. +void AnticheatData::SetPosition(float x, float y, float z, float o)
  115. +{
  116. + lastMovementInfo.pos.m_positionX = x;
  117. + lastMovementInfo.pos.m_positionY = y;
  118. + lastMovementInfo.pos.m_positionZ = z;
  119. + lastMovementInfo.pos.m_orientation = o;
  120. +}
  121. +
  122. +uint32 AnticheatData::GetLastOpcode() const
  123. +{
  124. + return lastOpcode;
  125. +}
  126. +
  127. +const MovementInfo& AnticheatData::GetLastMovementInfo() const
  128. +{
  129. + return lastMovementInfo;
  130. +}
  131. +
  132. +void AnticheatData::SetLastMovementInfo(MovementInfo& moveInfo)
  133. +{
  134. + lastMovementInfo = moveInfo;
  135. +}
  136. +
  137. +uint32 AnticheatData::GetTotalReports() const
  138. +{
  139. + return totalReports;
  140. +}
  141. +
  142. +void AnticheatData::SetTotalReports(uint32 _totalReports)
  143. +{
  144. + totalReports = _totalReports;
  145. +}
  146. +
  147. +void AnticheatData::SetTypeReports(uint32 type, uint32 amount)
  148. +{
  149. + typeReports[type] = amount;
  150. +}
  151. +
  152. +uint32 AnticheatData::GetTypeReports(uint32 type) const
  153. +{
  154. + return typeReports[type];
  155. +}
  156. +
  157. +float AnticheatData::GetAverage() const
  158. +{
  159. + return average;
  160. +}
  161. +
  162. +void AnticheatData::SetAverage(float _average)
  163. +{
  164. + average = _average;
  165. +}
  166. +
  167. +uint32 AnticheatData::GetCreationTime() const
  168. +{
  169. + return creationTime;
  170. +}
  171. +
  172. +void AnticheatData::SetCreationTime(uint32 _creationTime)
  173. +{
  174. + creationTime = _creationTime;
  175. +}
  176. +
  177. +void AnticheatData::SetTempReports(uint32 amount, uint8 type)
  178. +{
  179. + tempReports[type] = amount;
  180. +}
  181. +
  182. +uint32 AnticheatData::GetTempReports(uint8 type)
  183. +{
  184. + return tempReports[type];
  185. +}
  186. +
  187. +void AnticheatData::SetTempReportsTimer(uint32 time, uint8 type)
  188. +{
  189. + tempReportsTimer[type] = time;
  190. +}
  191. +
  192. +uint32 AnticheatData::GetTempReportsTimer(uint8 type)
  193. +{
  194. + return tempReportsTimer[type];
  195. +}
  196. diff --git a/src/server/game/Anticheat/AnticheatData.h b/src/server/game/Anticheat/AnticheatData.h
  197. new file mode 100644
  198. index 0000000..700ad2d
  199. --- /dev/null
  200. +++ b/src/server/game/Anticheat/AnticheatData.h
  201. @@ -0,0 +1,63 @@
  202. +#ifndef SC_ACDATA_H
  203. +#define SC_ACDATA_H
  204. +
  205. +#include "AnticheatMgr.h"
  206. +
  207. +#define MAX_REPORT_TYPES 6
  208. +
  209. +class AnticheatData
  210. +{
  211. +public:
  212. + AnticheatData();
  213. + ~AnticheatData();
  214. +
  215. + void SetLastOpcode(uint32 opcode);
  216. + uint32 GetLastOpcode() const;
  217. +
  218. + const MovementInfo& GetLastMovementInfo() const;
  219. + void SetLastMovementInfo(MovementInfo& moveInfo);
  220. +
  221. + void SetPosition(float x, float y, float z, float o);
  222. +
  223. + /*
  224. + bool GetDisableACCheck() const;
  225. + void SetDisableACCheck(bool check);
  226. +
  227. + uint32 GetDisableACTimer() const;
  228. + void SetDisableACTimer(uint32 timer);*/
  229. +
  230. + uint32 GetTotalReports() const;
  231. + void SetTotalReports(uint32 _totalReports);
  232. +
  233. + uint32 GetTypeReports(uint32 type) const;
  234. + void SetTypeReports(uint32 type, uint32 amount);
  235. +
  236. + float GetAverage() const;
  237. + void SetAverage(float _average);
  238. +
  239. + uint32 GetCreationTime() const;
  240. + void SetCreationTime(uint32 creationTime);
  241. +
  242. + void SetTempReports(uint32 amount, uint8 type);
  243. + uint32 GetTempReports(uint8 type);
  244. +
  245. + void SetTempReportsTimer(uint32 time, uint8 type);
  246. + uint32 GetTempReportsTimer(uint8 type);
  247. +
  248. + void SetDailyReportState(bool b);
  249. + bool GetDailyReportState();
  250. +private:
  251. + uint32 lastOpcode;
  252. + MovementInfo lastMovementInfo;
  253. + //bool disableACCheck;
  254. + //uint32 disableACCheckTimer;
  255. + uint32 totalReports;
  256. + uint32 typeReports[MAX_REPORT_TYPES];
  257. + float average;
  258. + uint32 creationTime;
  259. + uint32 tempReports[MAX_REPORT_TYPES];
  260. + uint32 tempReportsTimer[MAX_REPORT_TYPES];
  261. + bool hasDailyReport;
  262. +};
  263. +
  264. +#endif
  265. \ No newline at end of file
  266. diff --git a/src/server/game/Anticheat/AnticheatMgr.cpp b/src/server/game/Anticheat/AnticheatMgr.cpp
  267. new file mode 100644
  268. index 0000000..f409e93
  269. --- /dev/null
  270. +++ b/src/server/game/Anticheat/AnticheatMgr.cpp
  271. @@ -0,0 +1,434 @@
  272. +/*
  273. + * This program is free software; you can redistribute it and/or modify it
  274. + * under the terms of the GNU General Public License as published by the
  275. + * Free Software Foundation; either version 2 of the License, or (at your
  276. + * option) any later version.
  277. + *
  278. + * This program is distributed in the hope that it will be useful, but WITHOUT
  279. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  280. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  281. + * more details.
  282. + *
  283. + * You should have received a copy of the GNU General Public License along
  284. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  285. + */
  286. +
  287. +#include "AnticheatMgr.h"
  288. +#include "AnticheatScripts.h"
  289. +#include "MapManager.h"
  290. +
  291. +#define CLIMB_ANGLE 1.9f
  292. +
  293. +AnticheatMgr::AnticheatMgr()
  294. +{
  295. +}
  296. +
  297. +AnticheatMgr::~AnticheatMgr()
  298. +{
  299. + m_Players.clear();
  300. +}
  301. +
  302. +void AnticheatMgr::JumpHackDetection(Player* player, MovementInfo /* movementInfo */,uint32 opcode)
  303. +{
  304. + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & JUMP_HACK_DETECTION) == 0)
  305. + return;
  306. +
  307. + uint32 key = player->GetGUIDLow();
  308. +
  309. + if (m_Players[key].GetLastOpcode() == MSG_MOVE_JUMP && opcode == MSG_MOVE_JUMP)
  310. + {
  311. + BuildReport(player,JUMP_HACK_REPORT);
  312. + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Jump-Hack detected player GUID (low) %u",player->GetGUIDLow());
  313. + }
  314. +}
  315. +
  316. +void AnticheatMgr::WalkOnWaterHackDetection(Player* player, MovementInfo /* movementInfo */)
  317. +{
  318. + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & WALK_WATER_HACK_DETECTION) == 0)
  319. + return;
  320. +
  321. + uint32 key = player->GetGUIDLow();
  322. + if (!m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_WATERWALKING))
  323. + return;
  324. +
  325. + // if we are a ghost we can walk on water
  326. + if (!player->IsAlive())
  327. + return;
  328. +
  329. + if (player->HasAuraType(SPELL_AURA_FEATHER_FALL) ||
  330. + player->HasAuraType(SPELL_AURA_SAFE_FALL) ||
  331. + player->HasAuraType(SPELL_AURA_WATER_WALK))
  332. + return;
  333. +
  334. + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Walk on Water - Hack detected player GUID (low) %u",player->GetGUIDLow());
  335. + BuildReport(player,WALK_WATER_HACK_REPORT);
  336. +
  337. +}
  338. +
  339. +void AnticheatMgr::FlyHackDetection(Player* player, MovementInfo /* movementInfo */)
  340. +{
  341. + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & FLY_HACK_DETECTION) == 0)
  342. + return;
  343. +
  344. + uint32 key = player->GetGUIDLow();
  345. + if (!m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_FLYING))
  346. + return;
  347. +
  348. + if (player->HasAuraType(SPELL_AURA_FLY) ||
  349. + player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) ||
  350. + player->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
  351. + return;
  352. +
  353. + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Fly-Hack detected player GUID (low) %u",player->GetGUIDLow());
  354. + BuildReport(player,FLY_HACK_REPORT);
  355. +}
  356. +
  357. +void AnticheatMgr::TeleportPlaneHackDetection(Player* player, MovementInfo movementInfo)
  358. +{
  359. + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & TELEPORT_PLANE_HACK_DETECTION) == 0)
  360. + return;
  361. +
  362. + uint32 key = player->GetGUIDLow();
  363. +
  364. + if (m_Players[key].GetLastMovementInfo().pos.GetPositionZ() != 0 ||
  365. + movementInfo.pos.GetPositionZ() != 0)
  366. + return;
  367. +
  368. + if (movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING))
  369. + return;
  370. +
  371. + //DEAD_FALLING was deprecated
  372. + //if (player->getDeathState() == DEAD_FALLING)
  373. + // return;
  374. + float x, y, z;
  375. + player->GetPosition(x, y, z);
  376. + float ground_Z = player->GetMap()->GetHeight(x, y, z);
  377. + float z_diff = fabs(ground_Z - z);
  378. +
  379. + // we are not really walking there
  380. + if (z_diff > 1.0f)
  381. + {
  382. + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Teleport To Plane - Hack detected player GUID (low) %u",player->GetGUIDLow());
  383. + BuildReport(player,TELEPORT_PLANE_HACK_REPORT);
  384. + }
  385. +}
  386. +
  387. +void AnticheatMgr::StartHackDetection(Player* player, MovementInfo movementInfo, uint32 opcode)
  388. +{
  389. + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
  390. + return;
  391. +
  392. + if (player->IsGameMaster())
  393. + return;
  394. +
  395. + uint32 key = player->GetGUIDLow();
  396. +
  397. + if (player->IsInFlight() || player->GetTransport() || player->GetVehicle())
  398. + {
  399. + m_Players[key].SetLastMovementInfo(movementInfo);
  400. + m_Players[key].SetLastOpcode(opcode);
  401. + return;
  402. + }
  403. +
  404. + SpeedHackDetection(player,movementInfo);
  405. + FlyHackDetection(player,movementInfo);
  406. + WalkOnWaterHackDetection(player,movementInfo);
  407. + JumpHackDetection(player,movementInfo,opcode);
  408. + TeleportPlaneHackDetection(player, movementInfo);
  409. + ClimbHackDetection(player,movementInfo,opcode);
  410. +
  411. + m_Players[key].SetLastMovementInfo(movementInfo);
  412. + m_Players[key].SetLastOpcode(opcode);
  413. +}
  414. +
  415. +// basic detection
  416. +void AnticheatMgr::ClimbHackDetection(Player *player, MovementInfo movementInfo, uint32 opcode)
  417. +{
  418. + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & CLIMB_HACK_DETECTION) == 0)
  419. + return;
  420. +
  421. + uint32 key = player->GetGUIDLow();
  422. +
  423. + if (opcode != MSG_MOVE_HEARTBEAT ||
  424. + m_Players[key].GetLastOpcode() != MSG_MOVE_HEARTBEAT)
  425. + return;
  426. +
  427. + // in this case we don't care if they are "legal" flags, they are handled in another parts of the Anticheat Manager.
  428. + if (player->IsInWater() ||
  429. + player->IsFlying() ||
  430. + player->IsFalling())
  431. + return;
  432. +
  433. + Position playerPos;
  434. + Position pos = player->GetPosition();
  435. +
  436. + float deltaZ = fabs(playerPos.GetPositionZ() - movementInfo.pos.GetPositionZ());
  437. + float deltaXY = movementInfo.pos.GetExactDist2d(&playerPos);
  438. +
  439. + float angle = Position::NormalizeOrientation(tan(deltaZ/deltaXY));
  440. +
  441. + if (angle > CLIMB_ANGLE)
  442. + {
  443. + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Climb-Hack detected player GUID (low) %u", player->GetGUIDLow());
  444. + BuildReport(player,CLIMB_HACK_REPORT);
  445. + }
  446. +}
  447. +
  448. +void AnticheatMgr::SpeedHackDetection(Player* player,MovementInfo movementInfo)
  449. +{
  450. + if ((sWorld->getIntConfig(CONFIG_ANTICHEAT_DETECTIONS_ENABLED) & SPEED_HACK_DETECTION) == 0)
  451. + return;
  452. +
  453. + uint32 key = player->GetGUIDLow();
  454. +
  455. + // We also must check the map because the movementFlag can be modified by the client.
  456. + // If we just check the flag, they could always add that flag and always skip the speed hacking detection.
  457. + // 369 == DEEPRUN TRAM
  458. + if (m_Players[key].GetLastMovementInfo().HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && player->GetMapId() == 369)
  459. + return;
  460. +
  461. + uint32 distance2D = (uint32)movementInfo.pos.GetExactDist2d(&m_Players[key].GetLastMovementInfo().pos);
  462. + uint8 moveType = 0;
  463. +
  464. + // we need to know HOW is the player moving
  465. + // TO-DO: Should we check the incoming movement flags?
  466. + if (player->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
  467. + moveType = MOVE_SWIM;
  468. + else if (player->IsFlying())
  469. + moveType = MOVE_FLIGHT;
  470. + else if (player->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
  471. + moveType = MOVE_WALK;
  472. + else
  473. + moveType = MOVE_RUN;
  474. +
  475. + // how many yards the player can do in one sec.
  476. + uint32 speedRate = (uint32)(player->GetSpeed(UnitMoveType(moveType)) + movementInfo.jump.xyspeed);
  477. +
  478. + // how long the player took to move to here.
  479. + uint32 timeDiff = getMSTimeDiff(m_Players[key].GetLastMovementInfo().time,movementInfo.time);
  480. +
  481. + if (!timeDiff)
  482. + timeDiff = 1;
  483. +
  484. + // this is the distance doable by the player in 1 sec, using the time done to move to this point.
  485. + uint32 clientSpeedRate = distance2D * 1000 / timeDiff;
  486. +
  487. + // we did the (uint32) cast to accept a margin of tolerance
  488. + if (clientSpeedRate > speedRate)
  489. + {
  490. + BuildReport(player,SPEED_HACK_REPORT);
  491. + TC_LOG_DEBUG("entities.player.character", "AnticheatMgr:: Speed-Hack detected player GUID (low) %u",player->GetGUIDLow());
  492. + }
  493. +}
  494. +
  495. +void AnticheatMgr::StartScripts()
  496. +{
  497. + new AnticheatScripts();
  498. +}
  499. +
  500. +void AnticheatMgr::HandlePlayerLogin(Player* player)
  501. +{
  502. + // we must delete this to prevent errors in case of crash
  503. + CharacterDatabase.PExecute("DELETE FROM players_reports_status WHERE guid=%u",player->GetGUIDLow());
  504. + // we initialize the pos of lastMovementPosition var.
  505. + m_Players[player->GetGUIDLow()].SetPosition(player->GetPositionX(),player->GetPositionY(),player->GetPositionZ(),player->GetOrientation());
  506. + QueryResult resultDB = CharacterDatabase.PQuery("SELECT * FROM daily_players_reports WHERE guid=%u;",player->GetGUIDLow());
  507. +
  508. + if (resultDB)
  509. + m_Players[player->GetGUIDLow()].SetDailyReportState(true);
  510. +}
  511. +
  512. +void AnticheatMgr::HandlePlayerLogout(Player* player)
  513. +{
  514. + // TO-DO Make a table that stores the cheaters of the day, with more detailed information.
  515. +
  516. + // 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)
  517. + CharacterDatabase.PExecute("DELETE FROM players_reports_status WHERE guid=%u",player->GetGUIDLow());
  518. + // Delete not needed data from the memory.
  519. + m_Players.erase(player->GetGUIDLow());
  520. +}
  521. +
  522. +void AnticheatMgr::SavePlayerData(Player* player)
  523. +{
  524. + 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());
  525. +}
  526. +
  527. +uint32 AnticheatMgr::GetTotalReports(uint32 lowGUID)
  528. +{
  529. + return m_Players[lowGUID].GetTotalReports();
  530. +}
  531. +
  532. +float AnticheatMgr::GetAverage(uint32 lowGUID)
  533. +{
  534. + return m_Players[lowGUID].GetAverage();
  535. +}
  536. +
  537. +uint32 AnticheatMgr::GetTypeReports(uint32 lowGUID, uint8 type)
  538. +{
  539. + return m_Players[lowGUID].GetTypeReports(type);
  540. +}
  541. +
  542. +bool AnticheatMgr::MustCheckTempReports(uint8 type)
  543. +{
  544. + if (type == JUMP_HACK_REPORT)
  545. + return false;
  546. +
  547. + return true;
  548. +}
  549. +
  550. +void AnticheatMgr::BuildReport(Player* player,uint8 reportType)
  551. +{
  552. + uint32 key = player->GetGUIDLow();
  553. +
  554. + if (MustCheckTempReports(reportType))
  555. + {
  556. + uint32 actualTime = getMSTime();
  557. +
  558. + if (!m_Players[key].GetTempReportsTimer(reportType))
  559. + m_Players[key].SetTempReportsTimer(actualTime,reportType);
  560. +
  561. + if (getMSTimeDiff(m_Players[key].GetTempReportsTimer(reportType),actualTime) < 3000)
  562. + {
  563. + m_Players[key].SetTempReports(m_Players[key].GetTempReports(reportType)+1,reportType);
  564. +
  565. + if (m_Players[key].GetTempReports(reportType) < 3)
  566. + return;
  567. + } else
  568. + {
  569. + m_Players[key].SetTempReportsTimer(actualTime,reportType);
  570. + m_Players[key].SetTempReports(1,reportType);
  571. + return;
  572. + }
  573. + }
  574. +
  575. + // generating creationTime for average calculation
  576. + if (!m_Players[key].GetTotalReports())
  577. + m_Players[key].SetCreationTime(getMSTime());
  578. +
  579. + // increasing total_reports
  580. + m_Players[key].SetTotalReports(m_Players[key].GetTotalReports()+1);
  581. + // increasing specific cheat report
  582. + m_Players[key].SetTypeReports(reportType,m_Players[key].GetTypeReports(reportType)+1);
  583. +
  584. + // diff time for average calculation
  585. + uint32 diffTime = getMSTimeDiff(m_Players[key].GetCreationTime(),getMSTime()) / IN_MILLISECONDS;
  586. +
  587. + if (diffTime > 0)
  588. + {
  589. + // Average == Reports per second
  590. + float average = float(m_Players[key].GetTotalReports()) / float(diffTime);
  591. + m_Players[key].SetAverage(average);
  592. + }
  593. +
  594. + if (sWorld->getIntConfig(CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT) < m_Players[key].GetTotalReports())
  595. + {
  596. + if (!m_Players[key].GetDailyReportState())
  597. + {
  598. + 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());
  599. + m_Players[key].SetDailyReportState(true);
  600. + }
  601. + }
  602. +
  603. + if (m_Players[key].GetTotalReports() > sWorld->getIntConfig(CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION))
  604. + {
  605. + // display warning at the center of the screen, hacky way?
  606. + std::string str = "";
  607. + str = "|cFFFFFC00[AC]|cFF00FFFF[|cFF60FF00" + std::string(player->GetName().c_str()) + "|cFF00FFFF] Possible cheater!";
  608. + WorldPacket data(SMSG_NOTIFICATION, (str.size()+1));
  609. + data << str;
  610. + sWorld->SendGlobalGMMessage(&data);
  611. + }
  612. +}
  613. +
  614. +void AnticheatMgr::AnticheatGlobalCommand(ChatHandler* handler)
  615. +{
  616. + // 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!.
  617. + sObjectAccessor->SaveAllPlayers();
  618. +
  619. + QueryResult resultDB = CharacterDatabase.Query("SELECT guid,average,total_reports FROM players_reports_status WHERE total_reports != 0 ORDER BY average ASC LIMIT 3;");
  620. + if (!resultDB)
  621. + {
  622. + handler->PSendSysMessage("No players found.");
  623. + return;
  624. + } else
  625. + {
  626. + handler->SendSysMessage("=============================");
  627. + handler->PSendSysMessage("Players with the lowest averages:");
  628. + do
  629. + {
  630. + Field *fieldsDB = resultDB->Fetch();
  631. +
  632. + uint32 guid = fieldsDB[0].GetUInt32();
  633. + float average = fieldsDB[1].GetFloat();
  634. + uint32 total_reports = fieldsDB[2].GetUInt32();
  635. +
  636. + if (Player* player = sObjectMgr->GetPlayerByLowGUID(guid))
  637. + handler->PSendSysMessage("Player: %s Average: %f Total Reports: %u",player->GetName().c_str(),average,total_reports);
  638. +
  639. + } while (resultDB->NextRow());
  640. + }
  641. +
  642. + resultDB = CharacterDatabase.Query("SELECT guid,average,total_reports FROM players_reports_status WHERE total_reports != 0 ORDER BY total_reports DESC LIMIT 3;");
  643. +
  644. + // this should never happen
  645. + if (!resultDB)
  646. + {
  647. + handler->PSendSysMessage("No players found.");
  648. + return;
  649. + } else
  650. + {
  651. + handler->SendSysMessage("=============================");
  652. + handler->PSendSysMessage("Players with the more reports:");
  653. + do
  654. + {
  655. + Field *fieldsDB = resultDB->Fetch();
  656. +
  657. + uint32 guid = fieldsDB[0].GetUInt32();
  658. + float average = fieldsDB[1].GetFloat();
  659. + uint32 total_reports = fieldsDB[2].GetUInt32();
  660. +
  661. + if (Player* player = sObjectMgr->GetPlayerByLowGUID(guid))
  662. + handler->PSendSysMessage("Player: %s Total Reports: %u Average: %f",player->GetName().c_str(),total_reports,average);
  663. +
  664. + } while (resultDB->NextRow());
  665. + }
  666. +}
  667. +
  668. +void AnticheatMgr::AnticheatDeleteCommand(uint32 guid)
  669. +{
  670. + if (!guid)
  671. + {
  672. + for (AnticheatPlayersDataMap::iterator it = m_Players.begin(); it != m_Players.end(); ++it)
  673. + {
  674. + (*it).second.SetTotalReports(0);
  675. + (*it).second.SetAverage(0);
  676. + (*it).second.SetCreationTime(0);
  677. + for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
  678. + {
  679. + (*it).second.SetTempReports(0,i);
  680. + (*it).second.SetTempReportsTimer(0,i);
  681. + (*it).second.SetTypeReports(i,0);
  682. + }
  683. + }
  684. + CharacterDatabase.PExecute("DELETE FROM players_reports_status;");
  685. + }
  686. + else
  687. + {
  688. + m_Players[guid].SetTotalReports(0);
  689. + m_Players[guid].SetAverage(0);
  690. + m_Players[guid].SetCreationTime(0);
  691. + for (uint8 i = 0; i < MAX_REPORT_TYPES; i++)
  692. + {
  693. + m_Players[guid].SetTempReports(0,i);
  694. + m_Players[guid].SetTempReportsTimer(0,i);
  695. + m_Players[guid].SetTypeReports(i,0);
  696. + }
  697. + CharacterDatabase.PExecute("DELETE FROM players_reports_status WHERE guid=%u;",guid);
  698. + }
  699. +}
  700. +
  701. +void AnticheatMgr::ResetDailyReportStates()
  702. +{
  703. + for (AnticheatPlayersDataMap::iterator it = m_Players.begin(); it != m_Players.end(); ++it)
  704. + m_Players[(*it).first].SetDailyReportState(false);
  705. +}
  706. diff --git a/src/server/game/Anticheat/AnticheatMgr.h b/src/server/game/Anticheat/AnticheatMgr.h
  707. new file mode 100644
  708. index 0000000..554bdfa
  709. --- /dev/null
  710. +++ b/src/server/game/Anticheat/AnticheatMgr.h
  711. @@ -0,0 +1,103 @@
  712. +/*
  713. + * This program is free software; you can redistribute it and/or modify it
  714. + * under the terms of the GNU General Public License as published by the
  715. + * Free Software Foundation; either version 2 of the License, or (at your
  716. + * option) any later version.
  717. + *
  718. + * This program is distributed in the hope that it will be useful, but WITHOUT
  719. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  720. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  721. + * more details.
  722. + *
  723. + * You should have received a copy of the GNU General Public License along
  724. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  725. + */
  726. +
  727. +#ifndef SC_ACMGR_H
  728. +#define SC_ACMGR_H
  729. +
  730. +//#include <ace/Singleton.h>
  731. +#include "Common.h"
  732. +#include "SharedDefines.h"
  733. +#include "ScriptPCH.h"
  734. +#include "AnticheatData.h"
  735. +#include "Chat.h"
  736. +
  737. +class Player;
  738. +class AnticheatData;
  739. +
  740. +enum ReportTypes
  741. +{
  742. + SPEED_HACK_REPORT = 0,
  743. + FLY_HACK_REPORT,
  744. + WALK_WATER_HACK_REPORT,
  745. + JUMP_HACK_REPORT,
  746. + TELEPORT_PLANE_HACK_REPORT,
  747. + CLIMB_HACK_REPORT,
  748. +
  749. + // MAX_REPORT_TYPES
  750. +};
  751. +
  752. +enum DetectionTypes
  753. +{
  754. + SPEED_HACK_DETECTION = 1,
  755. + FLY_HACK_DETECTION = 2,
  756. + WALK_WATER_HACK_DETECTION = 4,
  757. + JUMP_HACK_DETECTION = 8,
  758. + TELEPORT_PLANE_HACK_DETECTION = 16,
  759. + CLIMB_HACK_DETECTION = 32
  760. +};
  761. +
  762. +// GUIDLow is the key.
  763. +typedef std::map<uint32, AnticheatData> AnticheatPlayersDataMap;
  764. +
  765. +class AnticheatMgr
  766. +{
  767. +// friend class ACE_Singleton<AnticheatMgr, ACE_Null_Mutex>;
  768. + AnticheatMgr();
  769. + ~AnticheatMgr();
  770. +
  771. + public:
  772. + static AnticheatMgr* instance()
  773. + {
  774. + static AnticheatMgr* instance = new AnticheatMgr();
  775. + return instance;
  776. + }
  777. +
  778. + void StartHackDetection(Player* player, MovementInfo movementInfo, uint32 opcode);
  779. + void DeletePlayerReport(Player* player, bool login);
  780. + void DeletePlayerData(Player* player);
  781. + void CreatePlayerData(Player* player);
  782. + void SavePlayerData(Player* player);
  783. +
  784. + void StartScripts();
  785. +
  786. + void HandlePlayerLogin(Player* player);
  787. + void HandlePlayerLogout(Player* player);
  788. +
  789. + uint32 GetTotalReports(uint32 lowGUID);
  790. + float GetAverage(uint32 lowGUID);
  791. + uint32 GetTypeReports(uint32 lowGUID, uint8 type);
  792. +
  793. + void AnticheatGlobalCommand(ChatHandler* handler);
  794. + void AnticheatDeleteCommand(uint32 guid);
  795. +
  796. + void ResetDailyReportStates();
  797. + private:
  798. + void SpeedHackDetection(Player* player, MovementInfo movementInfo);
  799. + void FlyHackDetection(Player* player, MovementInfo movementInfo);
  800. + void WalkOnWaterHackDetection(Player* player, MovementInfo movementInfo);
  801. + void JumpHackDetection(Player* player, MovementInfo movementInfo,uint32 opcode);
  802. + void TeleportPlaneHackDetection(Player* player, MovementInfo);
  803. + void ClimbHackDetection(Player* player,MovementInfo movementInfo,uint32 opcode);
  804. +
  805. + void BuildReport(Player* player,uint8 reportType);
  806. +
  807. + bool MustCheckTempReports(uint8 type);
  808. +
  809. + AnticheatPlayersDataMap m_Players; ///< Player data
  810. +};
  811. +
  812. +#define sAnticheatMgr AnticheatMgr::instance()
  813. +
  814. +#endif
  815. diff --git a/src/server/game/Anticheat/AnticheatScripts.cpp b/src/server/game/Anticheat/AnticheatScripts.cpp
  816. new file mode 100644
  817. index 0000000..340178d
  818. --- /dev/null
  819. +++ b/src/server/game/Anticheat/AnticheatScripts.cpp
  820. @@ -0,0 +1,14 @@
  821. +#include "AnticheatScripts.h"
  822. +#include "AnticheatMgr.h"
  823. +
  824. +AnticheatScripts::AnticheatScripts(): PlayerScript("AnticheatScripts") {}
  825. +
  826. +void AnticheatScripts::OnLogout(Player* player)
  827. +{
  828. + sAnticheatMgr->HandlePlayerLogout(player);
  829. +}
  830. +
  831. +void AnticheatScripts::OnLogin(Player* player,bool)
  832. +{
  833. + sAnticheatMgr->HandlePlayerLogin(player);
  834. +}
  835. diff --git a/src/server/game/Anticheat/AnticheatScripts.h b/src/server/game/Anticheat/AnticheatScripts.h
  836. new file mode 100644
  837. index 0000000..25d34d0
  838. --- /dev/null
  839. +++ b/src/server/game/Anticheat/AnticheatScripts.h
  840. @@ -0,0 +1,15 @@
  841. +#ifndef SC_ACSCRIPTS_H
  842. +#define SC_ACSCRIPTS_H
  843. +
  844. +#include "ScriptPCH.h"
  845. +
  846. +class AnticheatScripts: public PlayerScript
  847. +{
  848. + public:
  849. + AnticheatScripts();
  850. +
  851. + void OnLogout(Player* player);
  852. + void OnLogin(Player* player,bool);
  853. +};
  854. +
  855. +#endif
  856. \ No newline at end of file
  857. diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
  858. index d748be4..259390b 100644
  859. --- a/src/server/game/CMakeLists.txt
  860. +++ b/src/server/game/CMakeLists.txt
  861. @@ -9,6 +9,7 @@
  862. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  863.  
  864. file(GLOB_RECURSE sources_Accounts Accounts/*.cpp Accounts/*.h)
  865. +file(GLOB_RECURSE sources_Anticheat Anticheat/*.cpp Anticheat/*.h)
  866. file(GLOB_RECURSE sources_Achievements Achievements/*.cpp Achievements/*.h)
  867. file(GLOB_RECURSE sources_Addons Addons/*.cpp Addons/*.h)
  868. file(GLOB_RECURSE sources_AI AI/*.cpp AI/*.h)
  869. @@ -60,6 +61,7 @@ endif ()
  870. set(game_STAT_SRCS
  871. ${game_STAT_SRCS}
  872. ${sources_Accounts}
  873. + ${sources_Anticheat}
  874. ${sources_Achievements}
  875. ${sources_Addons}
  876. ${sources_AI}
  877. @@ -131,6 +133,7 @@ include_directories(
  878. ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
  879. ${CMAKE_CURRENT_SOURCE_DIR}
  880. ${CMAKE_CURRENT_SOURCE_DIR}/Accounts
  881. + ${CMAKE_CURRENT_SOURCE_DIR}/Anticheat
  882. ${CMAKE_CURRENT_SOURCE_DIR}/Achievements
  883. ${CMAKE_CURRENT_SOURCE_DIR}/Addons
  884. ${CMAKE_CURRENT_SOURCE_DIR}/AI
  885. diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
  886. index ea85f8b..7842600 100644
  887. --- a/src/server/game/Entities/Player/Player.cpp
  888. +++ b/src/server/game/Entities/Player/Player.cpp
  889. @@ -19,6 +19,7 @@
  890. #include "Player.h"
  891. #include "AccountMgr.h"
  892. #include "AchievementMgr.h"
  893. +#include "AnticheatMgr.h"
  894. #include "ArenaTeam.h"
  895. #include "ArenaTeamMgr.h"
  896. #include "Battlefield.h"
  897. @@ -19589,6 +19590,12 @@ void Player::SaveToDB(bool create /*=false*/)
  898.  
  899. CharacterDatabase.CommitTransaction(trans);
  900.  
  901. + // we save the data here to prevent spamming
  902. + sAnticheatMgr->SavePlayerData(this);
  903. +
  904. + // in this way we prevent to spam the db by each report made!
  905. + // sAnticheatMgr->SavePlayerData(this);
  906. +
  907. // save pet (hunter pet level and experience and all type pets health/mana).
  908. if (Pet* pet = GetPet())
  909. pet->SavePetToDB(PET_SAVE_AS_CURRENT);
  910. diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
  911. index beac32b..3ebf351 100644
  912. --- a/src/server/game/Entities/Unit/Unit.cpp
  913. +++ b/src/server/game/Entities/Unit/Unit.cpp
  914. @@ -16,6 +16,7 @@
  915. * with this program. If not, see <http://www.gnu.org/licenses/>.
  916. */
  917.  
  918. +#include "AnticheatMgr.h"
  919. #include "Unit.h"
  920. #include "Common.h"
  921. #include "Battlefield.h"
  922. @@ -12195,6 +12196,9 @@ void Unit::SetVisible(bool x)
  923.  
  924. void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
  925. {
  926. + //if (this->ToPlayer())
  927. + // sAnticheatMgr->DisableAnticheatDetection(this->ToPlayer());
  928. +
  929. int32 main_speed_mod = 0;
  930. float stack_bonus = 1.0f;
  931. float non_stack_bonus = 1.0f;
  932. diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
  933. index 68d8931..e4d18d5 100644
  934. --- a/src/server/game/Handlers/MovementHandler.cpp
  935. +++ b/src/server/game/Handlers/MovementHandler.cpp
  936. @@ -16,6 +16,7 @@
  937. * with this program. If not, see <http://www.gnu.org/licenses/>.
  938. */
  939.  
  940. +#include "AnticheatMgr.h"
  941. #include "Common.h"
  942. #include "WorldPacket.h"
  943. #include "WorldSession.h"
  944. @@ -341,6 +342,9 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
  945. plrMover->SetInWater(!plrMover->IsInWater() || plrMover->GetBaseMap()->IsUnderWater(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ()));
  946. }
  947.  
  948. + if (plrMover)
  949. + sAnticheatMgr->StartHackDetection(plrMover, movementInfo, opcode);
  950. +
  951. uint32 mstime = getMSTime();
  952. /*----------------------*/
  953. if (m_clientTimeDelay == 0)
  954. diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
  955. index bd43fbe..df86789 100644
  956. --- a/src/server/game/Scripting/ScriptLoader.cpp
  957. +++ b/src/server/game/Scripting/ScriptLoader.cpp
  958. @@ -17,6 +17,7 @@
  959.  
  960. #include "ScriptLoader.h"
  961. #include "World.h"
  962. +#include "AnticheatMgr.h"
  963.  
  964. // spells
  965. void AddSC_deathknight_spell_scripts();
  966. @@ -40,6 +41,7 @@ void AddSC_SmartScripts();
  967. void AddSC_account_commandscript();
  968. void AddSC_achievement_commandscript();
  969. void AddSC_ahbot_commandscript();
  970. +void AddSC_anticheat_commandscript();
  971. void AddSC_arena_commandscript();
  972. void AddSC_ban_commandscript();
  973. void AddSC_bf_commandscript();
  974. @@ -695,6 +697,7 @@ void AddScripts()
  975. AddSpellScripts();
  976. AddSC_SmartScripts();
  977. AddCommandScripts();
  978. + sAnticheatMgr->StartScripts();
  979. #ifdef SCRIPTS
  980. AddWorldScripts();
  981. AddEasternKingdomsScripts();
  982. @@ -729,6 +732,7 @@ void AddSpellScripts()
  983.  
  984. void AddCommandScripts()
  985. {
  986. + AddSC_anticheat_commandscript();
  987. AddSC_account_commandscript();
  988. AddSC_achievement_commandscript();
  989. AddSC_ahbot_commandscript();
  990. diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
  991. index 2b5b65f..ea668e0 100644
  992. --- a/src/server/game/Spells/SpellEffects.cpp
  993. +++ b/src/server/game/Spells/SpellEffects.cpp
  994. @@ -16,6 +16,7 @@
  995. * with this program. If not, see <http://www.gnu.org/licenses/>.
  996. */
  997.  
  998. +#include "AnticheatMgr.h"
  999. #include "Common.h"
  1000. #include "DatabaseEnv.h"
  1001. #include "WorldPacket.h"
  1002. diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
  1003. index afd87b8..97dc07c 100644
  1004. --- a/src/server/game/World/World.cpp
  1005. +++ b/src/server/game/World/World.cpp
  1006. @@ -27,6 +27,7 @@
  1007. #include "AuctionHouseMgr.h"
  1008. #include "BattlefieldMgr.h"
  1009. #include "BattlegroundMgr.h"
  1010. +#include "AnticheatMgr.h"
  1011. #include "CalendarMgr.h"
  1012. #include "Channel.h"
  1013. #include "CharacterDatabaseCleaner.h"
  1014. @@ -1253,6 +1254,11 @@ void World::LoadConfigSettings(bool reload)
  1015. m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = sConfigMgr->GetBoolDefault("PlayerDump.DisallowOverwrite", true);
  1016. m_bool_configs[CONFIG_UI_QUESTLEVELS_IN_DIALOGS] = sConfigMgr->GetBoolDefault("UI.ShowQuestLevelsInDialogs", false);
  1017.  
  1018. + m_bool_configs[CONFIG_ANTICHEAT_ENABLE] = sConfigMgr->GetBoolDefault("Anticheat.Enable", true);
  1019. + m_int_configs[CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION] = sConfigMgr->GetIntDefault("Anticheat.ReportsForIngameWarnings", 70);
  1020. + m_int_configs[CONFIG_ANTICHEAT_DETECTIONS_ENABLED] = sConfigMgr->GetIntDefault("Anticheat.DetectionsEnabled",31);
  1021. + m_int_configs[CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT] = sConfigMgr->GetIntDefault("Anticheat.MaxReportsForDailyReport",70);
  1022. +
  1023. // Wintergrasp battlefield
  1024. m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = sConfigMgr->GetBoolDefault("Wintergrasp.Enable", false);
  1025. m_int_configs[CONFIG_WINTERGRASP_PLR_MAX] = sConfigMgr->GetIntDefault("Wintergrasp.PlayerMax", 100);
  1026. @@ -2940,6 +2946,8 @@ void World::ResetDailyQuests()
  1027.  
  1028. // change available dailies
  1029. sPoolMgr->ChangeDailyQuests();
  1030. +
  1031. + sAnticheatMgr->ResetDailyReportStates();
  1032. }
  1033.  
  1034. void World::LoadDBAllowedSecurityLevel()
  1035. diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
  1036. index 2f13051..0645be5 100644
  1037. --- a/src/server/game/World/World.h
  1038. +++ b/src/server/game/World/World.h
  1039. @@ -145,6 +145,7 @@ enum WorldBoolConfigs
  1040. CONFIG_ALLOW_TICKETS,
  1041. CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES,
  1042. CONFIG_PRESERVE_CUSTOM_CHANNELS,
  1043. + CONFIG_ANTICHEAT_ENABLE,
  1044. CONFIG_PDUMP_NO_PATHS,
  1045. CONFIG_PDUMP_NO_OVERWRITE,
  1046. CONFIG_QUEST_IGNORE_AUTO_ACCEPT,
  1047. @@ -383,7 +384,10 @@ enum WorldIntConfigs
  1048. CONFIG_PRESERVE_CUSTOM_CHANNEL_DURATION,
  1049. CONFIG_PERSISTENT_CHARACTER_CLEAN_FLAGS,
  1050. CONFIG_LFG_OPTIONSMASK,
  1051. + CONFIG_ANTICHEAT_REPORTS_INGAME_NOTIFICATION,
  1052. + CONFIG_ANTICHEAT_MAX_REPORTS_FOR_DAILY_REPORT,
  1053. CONFIG_MAX_INSTANCES_PER_HOUR,
  1054. + CONFIG_ANTICHEAT_DETECTIONS_ENABLED,
  1055. CONFIG_WARDEN_CLIENT_RESPONSE_DELAY,
  1056. CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF,
  1057. CONFIG_WARDEN_CLIENT_FAIL_ACTION,
  1058. diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
  1059. index f11791e..522ece8 100644
  1060. --- a/src/server/scripts/CMakeLists.txt
  1061. +++ b/src/server/scripts/CMakeLists.txt
  1062. @@ -69,6 +69,7 @@ include_directories(
  1063. ${CMAKE_SOURCE_DIR}/src/server/shared
  1064. ${CMAKE_SOURCE_DIR}/src/server/shared/Database
  1065. ${CMAKE_SOURCE_DIR}/src/server/game/Accounts
  1066. + ${CMAKE_SOURCE_DIR}/src/server/game/Anticheat
  1067. ${CMAKE_SOURCE_DIR}/src/server/game/Achievements
  1068. ${CMAKE_SOURCE_DIR}/src/server/game/Addons
  1069. ${CMAKE_SOURCE_DIR}/src/server/game/AI
  1070. diff --git a/src/server/scripts/Commands/cs_anticheat.cpp b/src/server/scripts/Commands/cs_anticheat.cpp
  1071. new file mode 100644
  1072. index 0000000..3cc6784
  1073. --- /dev/null
  1074. +++ b/src/server/scripts/Commands/cs_anticheat.cpp
  1075. @@ -0,0 +1,262 @@
  1076. +/*
  1077. + * This program is free software; you can redistribute it and/or modify it
  1078. + * under the terms of the GNU General Public License as published by the
  1079. + * Free Software Foundation; either version 2 of the License, or (at your
  1080. + * option) any later version.
  1081. + *
  1082. + * This program is distributed in the hope that it will be useful, but WITHOUT
  1083. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  1084. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  1085. + * more details.
  1086. + *
  1087. + * You should have received a copy of the GNU General Public License along
  1088. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  1089. + */
  1090. +#include "Language.h"
  1091. +#include "ScriptMgr.h"
  1092. +#include "ObjectMgr.h"
  1093. +#include "Chat.h"
  1094. +#include "AnticheatMgr.h"
  1095. +
  1096. +class anticheat_commandscript : public CommandScript
  1097. +{
  1098. +public:
  1099. + anticheat_commandscript() : CommandScript("anticheat_commandscript") { }
  1100. +
  1101. + ChatCommand* GetCommands() const
  1102. + {
  1103. + static ChatCommand anticheatCommandTable[] =
  1104. + {
  1105. + { "global", SEC_GAMEMASTER, true, &HandleAntiCheatGlobalCommand, "", NULL },
  1106. + { "player", SEC_GAMEMASTER, true, &HandleAntiCheatPlayerCommand, "", NULL },
  1107. + { "delete", SEC_ADMINISTRATOR, true, &HandleAntiCheatDeleteCommand, "", NULL },
  1108. + { "handle", SEC_ADMINISTRATOR, true, &HandleAntiCheatHandleCommand, "", NULL },
  1109. + { "jail", SEC_GAMEMASTER, true, &HandleAnticheatJailCommand, "", NULL },
  1110. + { "warn", SEC_GAMEMASTER, true, &HandleAnticheatWarnCommand, "", NULL },
  1111. + { NULL, 0, false, NULL, "", NULL }
  1112. + };
  1113. +
  1114. + static ChatCommand commandTable[] =
  1115. + {
  1116. + { "anticheat", SEC_GAMEMASTER, true, NULL, "", anticheatCommandTable},
  1117. + { NULL, 0, false, NULL, "", NULL }
  1118. + };
  1119. +
  1120. + return commandTable;
  1121. + }
  1122. +
  1123. + static bool HandleAnticheatWarnCommand(ChatHandler* handler, const char* args)
  1124. + {
  1125. + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
  1126. + return false;
  1127. +
  1128. + Player* pTarget = NULL;
  1129. +
  1130. + std::string strCommand;
  1131. +
  1132. + char* command = strtok((char*)args, " ");
  1133. +
  1134. + if (command)
  1135. + {
  1136. + strCommand = command;
  1137. + normalizePlayerName(strCommand);
  1138. +
  1139. + pTarget = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
  1140. + }else
  1141. + pTarget = handler->getSelectedPlayer();
  1142. +
  1143. + if (!pTarget)
  1144. + return false;
  1145. +
  1146. + WorldPacket data;
  1147. +
  1148. + // need copy to prevent corruption by strtok call in LineFromMessage original string
  1149. + 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.");
  1150. + char* pos = buf;
  1151. +
  1152. + while (char* line = handler->LineFromMessage(pos))
  1153. + {
  1154. + handler->BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
  1155. + pTarget->GetSession()->SendPacket(&data);
  1156. + }
  1157. +
  1158. + free(buf);
  1159. + return true;
  1160. + }
  1161. +
  1162. + static bool HandleAnticheatJailCommand(ChatHandler* handler, const char* args)
  1163. + {
  1164. + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
  1165. + return false;
  1166. +
  1167. + Player* pTarget = NULL;
  1168. +
  1169. + std::string strCommand;
  1170. +
  1171. + char* command = strtok((char*)args, " ");
  1172. +
  1173. + if (command)
  1174. + {
  1175. + strCommand = command;
  1176. + normalizePlayerName(strCommand);
  1177. +
  1178. + pTarget = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
  1179. + }else
  1180. + pTarget = handler->getSelectedPlayer();
  1181. +
  1182. + if (!pTarget)
  1183. + {
  1184. + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
  1185. + handler->SetSentErrorMessage(true);
  1186. + return false;
  1187. + }
  1188. +
  1189. + if (pTarget == handler->GetSession()->GetPlayer())
  1190. + return false;
  1191. +
  1192. + // teleport both to jail.
  1193. + pTarget->TeleportTo(1,16226.5f,16403.6f,-64.5f,3.2f);
  1194. + handler->GetSession()->GetPlayer()->TeleportTo(1,16226.5f,16403.6f,-64.5f,3.2f);
  1195. +
  1196. + WorldLocation loc;
  1197. +
  1198. + // the player should be already there, but no :(
  1199. + // pTarget->GetPosition(&loc);
  1200. +
  1201. + loc.m_mapId = 1;
  1202. + loc.m_positionX = 16226.5f;
  1203. + loc.m_positionY = 16403.6f;
  1204. + loc.m_positionZ = -64.5f;
  1205. + loc.m_orientation = 3.2f;
  1206. +
  1207. + pTarget->SetHomebind(loc,876);
  1208. + return true;
  1209. + }
  1210. +
  1211. + static bool HandleAntiCheatDeleteCommand(ChatHandler* handler, const char* args)
  1212. + {
  1213. + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
  1214. + return false;
  1215. +
  1216. + std::string strCommand;
  1217. +
  1218. + char* command = strtok((char*)args, " "); //get entered name
  1219. +
  1220. + if (!command)
  1221. + return true;
  1222. +
  1223. + strCommand = command;
  1224. +
  1225. + if (strCommand.compare("deleteall") == 0)
  1226. + sAnticheatMgr->AnticheatDeleteCommand(0);
  1227. + else
  1228. + {
  1229. + normalizePlayerName(strCommand);
  1230. + Player* player = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
  1231. + if (!player)
  1232. + handler->PSendSysMessage("Player doesn't exist");
  1233. + else
  1234. + sAnticheatMgr->AnticheatDeleteCommand(player->GetGUIDLow());
  1235. + }
  1236. +
  1237. + return true;
  1238. + }
  1239. +
  1240. + static bool HandleAntiCheatPlayerCommand(ChatHandler* handler, const char* args)
  1241. + {
  1242. + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
  1243. + return false;
  1244. +
  1245. + std::string strCommand;
  1246. +
  1247. + char* command = strtok((char*)args, " ");
  1248. +
  1249. + uint32 guid = 0;
  1250. + Player* player = NULL;
  1251. +
  1252. + if (command)
  1253. + {
  1254. + strCommand = command;
  1255. +
  1256. + normalizePlayerName(strCommand);
  1257. + player = sObjectAccessor->FindPlayerByName(strCommand.c_str()); //get player by name
  1258. +
  1259. + if (player)
  1260. + guid = player->GetGUIDLow();
  1261. + }else
  1262. + {
  1263. + player = handler->getSelectedPlayer();
  1264. + if (player)
  1265. + guid = player->GetGUIDLow();
  1266. + }
  1267. +
  1268. + if (!guid)
  1269. + {
  1270. + handler->PSendSysMessage("There is no player.");
  1271. + return true;
  1272. + }
  1273. +
  1274. + float average = sAnticheatMgr->GetAverage(guid);
  1275. + uint32 total_reports = sAnticheatMgr->GetTotalReports(guid);
  1276. + uint32 speed_reports = sAnticheatMgr->GetTypeReports(guid,0);
  1277. + uint32 fly_reports = sAnticheatMgr->GetTypeReports(guid,1);
  1278. + uint32 jump_reports = sAnticheatMgr->GetTypeReports(guid,3);
  1279. + uint32 waterwalk_reports = sAnticheatMgr->GetTypeReports(guid,2);
  1280. + uint32 teleportplane_reports = sAnticheatMgr->GetTypeReports(guid,4);
  1281. + uint32 climb_reports = sAnticheatMgr->GetTypeReports(guid,5);
  1282. +
  1283. + handler->PSendSysMessage("Information about player %s",player->GetName().c_str());
  1284. + handler->PSendSysMessage("Average: %f || Total Reports: %u ",average,total_reports);
  1285. + handler->PSendSysMessage("Speed Reports: %u || Fly Reports: %u || Jump Reports: %u ",speed_reports,fly_reports,jump_reports);
  1286. + handler->PSendSysMessage("Walk On Water Reports: %u || Teleport To Plane Reports: %u",waterwalk_reports,teleportplane_reports);
  1287. + handler->PSendSysMessage("Climb Reports: %u", climb_reports);
  1288. +
  1289. + return true;
  1290. + }
  1291. +
  1292. + static bool HandleAntiCheatHandleCommand(ChatHandler* handler, const char* args)
  1293. + {
  1294. + std::string strCommand;
  1295. +
  1296. + char* command = strtok((char*)args, " ");
  1297. +
  1298. + if (!command)
  1299. + return true;
  1300. +
  1301. + if (!handler->GetSession()->GetPlayer())
  1302. + return true;
  1303. +
  1304. + strCommand = command;
  1305. +
  1306. + if (strCommand.compare("on") == 0)
  1307. + {
  1308. + sWorld->setBoolConfig(CONFIG_ANTICHEAT_ENABLE,true);
  1309. + handler->SendSysMessage("The Anticheat System is now: Enabled!");
  1310. + }
  1311. + else if (strCommand.compare("off") == 0)
  1312. + {
  1313. + sWorld->setBoolConfig(CONFIG_ANTICHEAT_ENABLE,false);
  1314. + handler->SendSysMessage("The Anticheat System is now: Disabled!");
  1315. + }
  1316. +
  1317. + return true;
  1318. + }
  1319. +
  1320. + static bool HandleAntiCheatGlobalCommand(ChatHandler* handler, const char* /* args */)
  1321. + {
  1322. + if (!sWorld->getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
  1323. + {
  1324. + handler->PSendSysMessage("The Anticheat System is disabled.");
  1325. + return true;
  1326. + }
  1327. +
  1328. + sAnticheatMgr->AnticheatGlobalCommand(handler);
  1329. +
  1330. + return true;
  1331. + }
  1332. +};
  1333. +
  1334. +void AddSC_anticheat_commandscript()
  1335. +{
  1336. + new anticheat_commandscript();
  1337. +}
  1338. diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
  1339. index c40da51..48ee00b 100644
  1340. --- a/src/server/worldserver/worldserver.conf.dist
  1341. +++ b/src/server/worldserver/worldserver.conf.dist
  1342. @@ -2661,6 +2661,40 @@ LevelReq.Auction = 1
  1343. LevelReq.Mail = 1
  1344.  
  1345. #
  1346. +# Anticheat.Enable
  1347. +# Description: Enables or disables the Anticheat System functionality
  1348. +# Default: 1 - (Enabled)
  1349. +# 0 - (Disabled)
  1350. +
  1351. +Anticheat.Enable = 1
  1352. +
  1353. +# Anticheat.ReportsForIngameWarnings
  1354. +# Description: How many reports the player must have to notify to GameMasters ingame when he generates a new report.
  1355. +# Default: 70
  1356. +
  1357. +Anticheat.ReportsForIngameWarnings = 70
  1358. +
  1359. +# Anticheat.DetectionsEnabled
  1360. +# Description: It represents which detections are enabled.
  1361. +#
  1362. +# SPEED_HACK_DETECTION = 1
  1363. +# FLY_HACK_DETECTION = 2
  1364. +# WALK_WATER_HACK_DETECTION = 4
  1365. +# JUMP_HACK_DETECTION = 8
  1366. +# TELEPORT_PLANE_HACK_DETECTION = 16
  1367. +# CLIMB_HACK_DETECTION = 32
  1368. +#
  1369. +# Default: 31
  1370. +
  1371. +Anticheat.DetectionsEnabled = 31
  1372. +
  1373. +# Anticheat.MaxReportsForDailyReport
  1374. +# 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).
  1375. +# Default: 70
  1376. +
  1377. +Anticheat.MaxReportsForDailyReport = 70
  1378. +
  1379. +#
  1380. # PlayerDump.DisallowPaths
  1381. # Description: Disallow using paths in PlayerDump output files
  1382. # Default: 1
  1383. --
  1384. 2.1.3
Advertisement
Add Comment
Please, Sign In to add comment