Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
- --- a/src/server/game/Chat/Chat.cpp
- +++ b/src/server/game/Chat/Chat.cpp
- @@ -690,6 +690,15 @@
- { NULL, 0, false, NULL, "", NULL }
- };
- + static ChatCommand anticheatCommandTable[] =
- + {
- + { "global", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAntiCheatGlobalCommand, "", NULL },
- + { "player", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAntiCheatPlayerCommand, "", NULL },
- + { "delete", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAntiCheatDeleteCommand, "", NULL },
- + { "handle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleAntiCheatHandleCommand, "", NULL },
- + { NULL, 0, false, NULL, "", NULL }
- + };
- +
- static ChatCommand commandTable[] =
- {
- { "account", SEC_PLAYER, true, NULL, "", accountCommandTable },
- diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
- --- a/src/server/game/Chat/Chat.h
- +++ b/src/server/game/Chat/Chat.h
- @@ -601,6 +601,12 @@
- bool HandleTempGameObjectCommand(const char* args);
- bool HandleTempAddSpwCommand(const char* args);
- + // ANTICHEAT
- + bool HandleAntiCheatGlobalCommand(const char* args); // top3 : Amount || Average || (Amount && Average)
- + bool HandleAntiCheatPlayerCommand(const char* args); // returns especific player's average and amount
- + bool HandleAntiCheatDeleteCommand(const char* args); // if no player name as parameter, deletes all logs else deletes specific player's log
- + bool HandleAntiCheatHandleCommand(const char* args); // turn it on, turn it off
- +
- //! Development Commands
- diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
- --- a/src/server/game/Chat/Commands/Level3.cpp
- +++ b/src/server/game/Chat/Commands/Level3.cpp
- @@ -7195,6 +7195,180 @@
- return true;
- }
- +bool ChatHandler::HandleAntiCheatDeleteCommand(const char *args)
- +{
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " "); //get entered name
- +
- + if (!command)
- + return true;
- +
- + strCommand = command;
- +
- + if (strCommand.compare("deleteall") == 0)
- + {
- + uint8 uiStmt[3] = {"DELETE FROM cheat_first_report","DELETE FROM cheat_temp_reports", "DELETE FROM cheat_reports" };
- + for (uint8 uiI = 0; uiI < 3; uiI++)
- + {
- + stmt = CharacterDatabase.Execute(uiStmt[uiI]);
- + CharacterDatabase.Execute(stmt);
- + }
- +
- + } else
- + {
- + normalizePlayerName(strCommand);
- + Player* pPlayer = sObjectMgr.GetPlayer(strCommand.c_str()); //get player by name
- +
- + if (!pPlayer)
- + PSendSysMessage("Player doesn't exist");
- + else
- + {
- + uint8 uiStmt[3] = {"DELETE FROM cheat_reports WHERE guid=?", "DELETE FROM cheat_temp_reports WHERE guid=?","DELETE FROM cheat_first_report WHERE guid=?"};
- +
- + for (uint8 uiI = 0; uiI < 3; uiI++)
- + {
- + stmt = CharacterDatabase.Execute(uiStmt[uiI]);
- + stmt->setUInt64(0, pPlayer->GetGUIDLow());
- + CharacterDatabase.Execute(stmt);
- + }
- + }
- + }
- +
- + return true;
- +}
- +
- +bool ChatHandler::HandleAntiCheatPlayerCommand(const char *args)
- +{
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " ");
- +
- + uint32 uiGUID = 0;
- + Player* pPlayer = NULL;
- +
- + if (command)
- + {
- + strCommand = command;
- +
- + normalizePlayerName(strCommand);
- +
- + pPlayer = sObjectMgr.GetPlayer(strCommand.c_str()); //get player by name
- +
- + if (pPlayer)
- + uiGUID = pPlayer->GetGUIDLow();
- + }else
- + {
- + pPlayer = getSelectedPlayer();
- + if (pPlayer)
- + uiGUID = pPlayer->GetGUIDLow();
- + }
- +
- + if (uiGUID == 0)
- + {
- + PSendSysMessage("There is no player.");
- + return true;
- + }
- +
- + stmt = CharacterDatabase.Execute("SELECT count( * ) AS 'Repeticiones' FROM `characters` AS A, `cheat_reports` AS B WHERE A.`online` =1 AND A.`guid` = B.`guid` AND A.`guid`=? GROUP BY B.`guid` ORDER BY Repeticiones DESC LIMIT 0 , 1");
- + stmt->setUInt32(0,uiGUID);
- + QueryResult result = CharacterDatabase.Query(stmt);
- +
- + if (result)
- + {
- + do
- + {
- + Field* fields=result->Fetch();
- + uint32 warnings = fields[0].GetUInt32();
- + PSendSysMessage("Amount: %u", warnings);
- + }
- + while (result->NextRow());
- + } else
- + PSendSysMessage("Player's amount log is empty!.");
- +
- + stmt = CharacterDatabase.Execute("SELECT CAST((SUM(B.time ) / count( * ) ) - C.time AS UNSIGNED) AS 'promedio' , CAST(count( * ) AS UNSIGNED) AS 'Repeticiones' FROM `characters` AS A, `cheat_temp_reports` AS B, cheat_first_report AS C WHERE A.`online` =1 AND A.`guid` = B.`guid` AND A.guid = C.guid AND A.`guid`=? GROUP BY B.`guid` ORDER BY Repeticiones DESC LIMIT 0 , 1;");
- + stmt->setUInt32(0,uiGUID);
- + result = CharacterDatabase.Query(stmt);
- +
- + if (result)
- + {
- + do
- + {
- + Field* fields=result->Fetch();
- + uint32 average = fields[0].GetUInt32();
- + uint32 warnings = fields[1].GetUInt32();
- +
- + PSendSysMessage("Average: %u Warnings: %u", average, warnings);
- + }
- + while (result->NextRow());
- + } else
- + PSendSysMessage("Player's average log is empty!.");
- +
- + return true;
- +}
- +
- +bool ChatHandler::HandleAntiCheatHandleCommand(const char *args)
- +{
- + std::string strCommand;
- +
- + char* command = strtok((char*)args, " ");
- +
- + if (!command)
- + return true;
- +
- + strCommand = command;
- +
- + if (strCommand.compare("on") == 0)
- + sWorld.setBoolConfig(CONFIG_ANTICHEAT_ENABLE,true);
- + else if (strCommand.compare("off") == 0)
- + sWorld.setBoolConfig(CONFIG_ANTICHEAT_ENABLE,false);
- +
- + return true;
- +}
- +
- +bool ChatHandler::HandleAntiCheatGlobalCommand(const char *args)
- +{
- + stmt = CharacterDatabase.Execute("SELECT A.`name` , count( * ) AS 'Repeticiones' FROM `characters` AS A, `cheat_reports` AS B WHERE A.`online` =1 AND A.`guid` = B.`guid` GROUP BY B.`guid` ORDER BY Repeticiones DESC LIMIT 0 , 3");
- + QueryResult result = CharacterDatabase.Query(stmt);
- +
- + PSendSysMessage("Cheaters by Amount: -------------");
- + if (result)
- + {
- + do
- + {
- + Field* fields=result->Fetch();
- + std::string name = fields[0].GetCString();
- + uint32 warnings = fields[1].GetUInt32();
- +
- + PSendSysMessage("Name: %s Warnings: %u", name.c_str(), warnings);
- + }
- + while (result->NextRow());
- + } else
- + PSendSysMessage("Cheaters amount log empty!.");
- +
- + PSendSysMessage("Cheaters by Average: -------------");
- +
- + stmt = CharacterDatabase.Execute("SELECT A.`name` , CAST((SUM(B.time ) / count( * ) ) - C.time AS UNSIGNED) AS 'promedio' , CAST(count( * ) AS UNSIGNED) AS 'Repeticiones' FROM `characters` AS A, `cheat_temp_reports` AS B, cheat_first_report AS C WHERE A.`online` =1 AND A.`guid` = B.`guid` AND A.guid = C.guid GROUP BY B.`guid` ORDER BY Repeticiones DESC LIMIT 0 , 3;");
- + result = CharacterDatabase.Query(stmt);
- +
- + if (result)
- + {
- + do
- + {
- + Field* fields=result->Fetch();
- + std::string name = fields[0].GetCString();
- + uint32 average = fields[1].GetUInt32();
- + uint32 warnings = fields[2].GetUInt32();
- +
- + PSendSysMessage("Name: %s Average: %u Warnings: %u", name.c_str(), average, warnings);
- + }
- + while (result->NextRow());
- + } else
- + PSendSysMessage("Cheaters average log empty!.");
- +
- + return true;
- +}
- +
- bool ChatHandler::HandleFreezeCommand(const char *args)
- {
- std::string name;
- diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
- --- a/src/server/game/Entities/Player/Player.cpp
- +++ b/src/server/game/Entities/Player/Player.cpp
- @@ -619,6 +619,10 @@
- Player::~Player ()
- {
- + // anticheat
- + if (sWorld.getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + CleanTempCheatReports();
- +
- // it must be unloaded already in PlayerLogout and accessed only for loggined player
- //m_social = NULL;
- @@ -654,6 +658,89 @@
- sWorld.DecreasePlayerCount();
- }
- +bool Player::HasFirstReport()
- +{
- + stmt = CharacterDatabase.Execute("SELECT * FROM cheat_first_report WHERE guid=?;");
- + stmt->setUInt64(0,GetGUIDLow());
- +
- + QueryResult result = CharacterDatabase.Query(stmt);
- +
- + if (result)
- + return true;
- + else
- + return false;
- +}
- +
- +void Player::CleanTempCheatReports()
- +{
- + for (uint8 uiI = 0; uiI < 2; uiI++)
- + {
- + stmt;
- +
- + if (uiI == 0)
- + stmt = CharacterDatabase.Execute( "DELETE FROM cheat_first_report WHERE guid=?");
- + else
- + stmt = CharacterDatabase.Execute("DELETE FROM cheat_temp_reports WHERE guid=?");
- +
- + stmt->setUInt64(0,GetGUIDLow());
- + CharacterDatabase.Execute(stmt);
- + }
- +}
- +
- +void Player::ElaborateCheatReport(Player* pPlayer, uint8 uiCheatType)
- +{
- + if (!pPlayer)
- + return;
- +
- + // cheatType 1 == SpeedHack
- + // cheatType 2 == FlyHack
- +
- + std::string strReportType;
- +
- + switch(uiCheatType)
- + {
- + case 1:
- + strReportType = "Speed-Hack";
- + break;
- + case 2:
- + strReportType = "Fly-Hack";
- + break;
- + default:
- + strReportType = "";
- + break;
- + }
- +
- + if (!HasFirstReport())
- + {
- + stmt = CharacterDatabase.Execute("INSERT INTO cheat_first_report (`guid`,`name`,`time`) VALUES (?,?,?);");
- + stmt->setUInt64(0,GetGUIDLow());
- + stmt->setString(1,GetName());
- + stmt->setUInt64(2, uint64(time(NULL)));
- + CharacterDatabase.Execute(stmt);
- + }
- +
- + for (uint8 uiI = 0; uiI < 2; uiI++)
- + {
- + stmt;
- +
- + if (uiI == 0)
- + stmt = CharacterDatabase.Execute("INSERT INTO cheat_reports (`guid`,`name`,`mapid`,`position_x`,`position_y`,`position_z`,`report`,`time`) VALUES (?,?,?,?,?,?,?,?);");
- + else
- + stmt = CharacterDatabase.Execute("INSERT INTO cheat_temp_reports (`guid`,`name`,`mapid`,`position_x`,`position_y`,`position_z`,`report`,`time`) VALUES (?,?,?,?,?,?,?,?);");
- +
- + stmt->setUInt64(0,GetGUIDLow());
- + stmt->setString(1,GetName());
- + stmt->setUInt32(2,GetMapId());
- + stmt->setFloat(3,GetPositionX());
- + stmt->setFloat(4,GetPositionY());
- + stmt->setFloat(5,GetPositionZ());
- + stmt->setString(6,strReportType);
- + stmt->setUInt64(7, uint64(time(NULL)));
- + CharacterDatabase.Execute(stmt);
- + }
- +
- +}
- +
- void Player::CleanupsBeforeDelete(bool finalCleanup)
- {
- TradeCancel(false);
- @@ -19862,6 +19949,24 @@
- }
- }
- +bool Player::CanFlyAnticheat(MovementInfo& pMovementInfo)
- +{
- + if (IsUnderWater())
- + return false;
- +
- + if (HasAuraType(SPELL_AURA_FLY) || HasAuraType(SPELL_AURA_WATER_WALK) || HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))
- + return false;
- +
- + if (Creature* pCreature = GetVehicleCreatureBase())
- + if (pCreature->GetCreatureInfo()->InhabitType & INHABIT_AIR)
- + return false;
- +
- + if (HasUnitMovementFlag(MOVEMENTFLAG_JUMPING) || pMovementInfo.HasMovementFlag(MOVEMENTFLAG_JUMPING) || GetMap()->GetGameObject(pMovementInfo.t_guid))
- + return false;
- +
- + return true;
- +}
- +
- void Player::UpdatePvPState(bool onlyFFA)
- {
- // TODO: should we always synchronize UNIT_FIELD_BYTES_2, 1 of controller and controlled?
- diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
- --- a/src/server/game/Entities/Player/Player.h
- +++ b/src/server/game/Entities/Player/Player.h
- @@ -2375,6 +2375,19 @@
- float GetAverageItemLevel();
- + /*********************************************************/
- + /*** ANTICHEAT SYSTEM ***/
- + /*********************************************************/
- + uint32 GetLastPacketTime() { return uiLastPacketTime;}
- + uint32 GetLastOpcode() { return uiLastOpcode; }
- + float GetLastSpeedRate() { return fLastSpeedRate; }
- + void SetLastPacketTime(uint32 uiTime) { uiLastPacketTime = uiTime; }
- + void SetLastSpeedRate(float fSpeedRateRate) { fLastSpeedRate = fSpeedRateRate; }
- + void SetLastOpcode(uint32 uiOpcode) { uiLastOpcode = uiOpcode; }
- + void ElaborateCheatReport(Player* pPlayer, uint8 uiReportType);
- + bool CanFlyAnticheat(MovementInfo& pMovementInfo);
- + bool HasFirstReport();
- + void CleanTempCheatReports();
- protected:
- uint32 m_AreaID;
- uint32 m_regenTimerCount;
- @@ -2615,6 +2628,13 @@
- Runes *m_runes;
- EquipmentSets m_EquipmentSets;
- private:
- + /*********************************************************/
- + /*** ANTICHEAT SYSTEM ***/
- + /*********************************************************/
- + uint32 uiLastPacketTime;
- + float fLastSpeedRate;
- + uint32 uiLastOpcode;
- +
- // internal common parts for CanStore/StoreItem functions
- uint8 _CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem) const;
- uint8 _CanStoreItem_InBag(uint8 bag, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, bool non_specialized, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot) const;
- diff --git a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp
- --- a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp
- +++ b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp
- @@ -348,6 +348,100 @@
- }
- /*----------------------*/
- +
- + // ANTICHEAT CHECKS
- + if (sWorld.getBoolConfig(CONFIG_ANTICHEAT_ENABLE))
- + {
- + if (plMover &&
- + !plMover->isInFlight() &&
- + !plMover->GetTransport() &&
- + !plMover->IsBeingTeleported() &&
- + plMover->CanFreeMove() &&
- + !plMover->isGameMaster())
- + {
- + // fly hack detection
- + // PosZ is checked to see if the player is going up when it should not.
- + if (plMover->CanFlyAnticheat(movementInfo))
- + {
- + if (movementInfo.pos.GetPositionZ() > plMover->GetPositionZ() && fabs(movementInfo.pos.GetPositionZ() - plMover->GetPositionZ()) > 1.5f)
- + {
- + float ground_Z = plMover->GetMap()->GetHeight(movementInfo.pos.GetPositionX(), movementInfo.pos.GetPositionY(), movementInfo.pos.GetPositionZ());
- + if (movementInfo.pos.GetPositionZ() > ground_Z && fabs(movementInfo.pos.GetPositionZ() - ground_Z) >= 5.0f)
- + plMover->ElaborateCheatReport(plMover,2);
- + }
- + }
- +
- + if (plMover->GetLastPacketTime() > 0 &&
- + movementInfo.GetMovementFlags() == plMover->GetUnitMovementFlags() &&
- + opcode == MSG_MOVE_HEARTBEAT &&
- + plMover->GetLastOpcode() == opcode &&
- + !plMover->GetVehicle() &&
- + plMover->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
- + {
- + uint8 uiMoveType = 0;
- +
- + if (plMover->IsFlying())
- + uiMoveType = MOVE_FLIGHT;
- + else if (plMover->IsUnderWater())
- + uiMoveType = MOVE_SWIM;
- + else
- + uiMoveType = MOVE_RUN;
- +
- + // this is the distance doable by a player in 1000 ms.
- + float fSpeedRate = plMover->GetSpeedRate(UnitMoveType(uiMoveType));
- +
- + // in my opinion this var must be constant in each check to avoid false reports
- + if (plMover->GetLastSpeedRate() == fSpeedRate)
- + {
- + // Calculate Distance2D
- + float fDeltaX = pow((movementInfo.pos.GetPositionX() - plMover->GetPositionX()),2);
- + float fDeltaY = pow(movementInfo.pos.GetPositionY() - plMover->GetPositionY(),2);
- + // final distance
- + float fDistance2d = fabs(sqrt(fDeltaX + fDeltaY) - plMover->GetObjectSize() - plMover->GetObjectSize());
- +
- + // time between packets
- + uint32 uiDiffTime = getMSTimeDiff(plMover->GetLastPacketTime(), movementInfo.time);
- +
- + // this is the distance doable by the player in 1 sec using the time between the packets
- + float fCoreDistance = uiDiffTime * 7.0f * fSpeedRate / 1000;
- +
- + /* SPEED HACK DETECTION */
- + if (uiDiffTime < sWorld.getIntConfig(CONFIG_ANTICHEAT_MAX_DIFF_TIME) && uiDiffTime > sWorld.getIntConfig(CONFIG_ANTICHEAT_MIN_DIFF_TIME))
- + {
- + // some times (i dont know why) fCoreDistance is 0
- + if (fCoreDistance > 0.0f && fDistance2d > 0)
- + {
- + if (fDistance2d > fCoreDistance)
- + {
- + if (fabs(fCoreDistance - fDistance2d) > sWorld.getFloatConfig(CONFIG_ANTICHEAT_MAX_DISTANCE_DIFF_ALLOWED))
- + {
- + sLog.outError("Cheater! guid %u name %s fCoreDistance %f fDistance2d %f uiDiffTime %u fSpeedRate %f Latency %u",plMover->GetGUIDLow(),plMover->GetName(),fCoreDistance,fDistance2d,uiDiffTime,fSpeedRate, plMover->GetSession()->GetLatency());
- + plMover->ElaborateCheatReport(plMover,1);
- + }
- + }
- + }
- + }
- + }
- + }
- + }
- +
- + // save packet time for next control.
- + if (plMover)
- + {
- + uint8 uiMoveType = 0;
- +
- + if (plMover->IsFlying())
- + uiMoveType = MOVE_FLIGHT;
- + else if (plMover->IsUnderWater())
- + uiMoveType = MOVE_SWIM;
- + else
- + uiMoveType = MOVE_RUN;
- +
- + plMover->SetLastPacketTime(movementInfo.time);
- + plMover->SetLastSpeedRate(plMover->GetSpeedRate(UnitMoveType(uiMoveType)));
- + plMover->SetLastOpcode(opcode);
- + }
- + }
- /* process position-change */
- WorldPacket data(opcode, recv_data.size());
- diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
- --- a/src/server/game/World/World.cpp
- +++ b/src/server/game/World/World.cpp
- @@ -1222,6 +1222,12 @@
- m_int_configs[CONFIG_AUTOBROADCAST_CENTER] = sConfig.GetIntDefault("AutoBroadcast.Center", 0);
- m_int_configs[CONFIG_AUTOBROADCAST_INTERVAL] = sConfig.GetIntDefault("AutoBroadcast.Timer", 60000);
- + // anticheat configs
- + m_bool_configs[CONFIG_ANTICHEAT_ENABLE] = sConfig.GetBoolDefault("Anticheat.Enable", false);
- + m_int_configs[CONFIG_ANTICHEAT_MAX_DIFF_TIME] = sConfig.GetIntDefault("Anticheat.MaxDiffTime", 1000);
- + m_int_configs[CONFIG_ANTICHEAT_MIN_DIFF_TIME] = sConfig.GetIntDefault("Anticheat.MinDiffTime", 50);
- + m_float_configs[CONFIG_ANTICHEAT_MAX_DISTANCE_DIFF_ALLOWED] = sConfig.GetFloatDefault("Anticheat.MaxMaxAllowedDistance",1.0f);
- +
- sScriptMgr.OnConfigLoad(reload);
- }
- @@ -2597,6 +2603,10 @@
- for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
- if (itr->second->GetPlayer())
- itr->second->GetPlayer()->ResetDailyQuestStatus();
- +
- + //ANTICHEAT
- + CharacterDatabase.Execute("DELETE FROM cheat_reports;");
- + CharacterDatabase.Execute("DELETE FROM cheat_first_report;");
- }
- void World::LoadDBAllowedSecurityLevel()
- diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
- --- a/src/server/game/World/World.h
- +++ b/src/server/game/World/World.h
- @@ -163,6 +163,7 @@
- CONFIG_CHATLOG_BGROUND,
- CONFIG_DUNGEON_FINDER_ENABLE,
- CONFIG_AUTOBROADCAST,
- + CONFIG_ANTICHEAT_ENABLE,
- BOOL_CONFIG_VALUE_COUNT
- };
- @@ -179,6 +180,7 @@
- CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS,
- CONFIG_THREAT_RADIUS,
- CONFIG_CHANCE_OF_GM_SURVEY,
- + CONFIG_ANTICHEAT_MAX_DISTANCE_DIFF_ALLOWED,
- FLOAT_CONFIG_VALUE_COUNT
- };
- @@ -307,6 +309,8 @@
- CONFIG_AUTOBROADCAST_CENTER,
- CONFIG_AUTOBROADCAST_INTERVAL,
- CONFIG_MAX_RESULTS_LOOKUP_COMMANDS,
- + CONFIG_ANTICHEAT_MAX_DIFF_TIME,
- + CONFIG_ANTICHEAT_MIN_DIFF_TIME,
- INT_CONFIG_VALUE_COUNT
- };
- diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
- --- a/src/server/worldserver/worldserver.conf.dist
- +++ b/src/server/worldserver/worldserver.conf.dist
- @@ -2069,6 +2069,16 @@
- # Default: 0 - off
- # 1 - on
- #
- +# Anticheat.Enable
- +# Enable Anticheat System
- +# Default: 0 - off
- +# 1 - on
- +# Anticheat.MaxDiffTime
- +# Default: 1000 ms
- +# Anticheat.MinDiffTime
- +# Default: 350 ms
- +# Anticheat.MaxMaxAllowedDistance
- +# Default: 1.0 f
- ###############################################################################
- PlayerStart.AllReputation = 0
- @@ -2092,3 +2102,7 @@
- LevelReq.Auction = 1
- LevelReq.Mail = 1
- DungeonFinder.Enable = 0
- +Anticheat.Enable = 0
- +Anticheat.MaxDiffTime = 1000
- +Anticheat.MinDiffTime = 50
- +Anticheat.MaxMaxAllowedDistance = 1.0
- \ No newline at end of file
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement