mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 13:16:23 +00:00
feat(Core/Warden): optimization + PQR detection (#3875)
* Update AuctionHouseHandler.cpp * feat(warden): block PQR * wip * Update Warden.cpp * Core/Warden: minor preperation * Core/Misc: implemented some needed container wrapper functions * Core/Warden: more preperations * Core/Warden: more rework * LUA checks now are splitted to seperate config * LUA checks are always in front of queue * Fixed "Other" checks * Fixed PQR detection * Core/Warden: adjusted and optimized * Core/Warden: optimization * Core/Warden: more optimization * Core/Warden: use warden comments in ban reason * Core/Warden: more warden work * Core/Warden: more optimizations * Core/Warden: more refactors * Core/Warden: some more refactors + use default SHA definitions * Core/Warden: more refactoring * Core/Warden: fixed PQR detection again * Core/Warden: improved detection logging * Core/Misc: removed SmartEnums - we do not need it here + maybe should go as seperate commit * Core/Warden: fixed some warnings * Core/Warden: codestyle * Core/Warden: include warden check comment to console logs * Core/Warden: minor adjustment for previous commit * Core/Warden: fixed static analysis warning * Core/Warden: compilers, you're drunk this time... function is not unused... * Core/Warden: minor correction for logs * Core/Warden: one more improvement for logs * Core/Warden: added missing overrides * Core/Warden: some codestyle * Core/Misc: more codestyle * Core/Misc: more codestyle! * Core/Warden: restored default config options... (if you change it, change in core source too) * Core/Warden: addition to previous commit * DB/Warden: added EWT and WOWPlus checks (provided by lineagedr) * DB/Warden: addition to previous commit * fix: codestyle * Core/Warden: fixed build when extra logs are enabled in cmake Co-authored-by: Stefano Borzì <stefanoborzi32@gmail.com> Co-authored-by: Francesco Borzì <borzifrancesco@gmail.com>
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "Util.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "Warden.h"
|
||||
|
||||
#ifdef ELUNA
|
||||
#include "LuaEngine.h"
|
||||
@@ -280,6 +281,12 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
|
||||
if (lang != LANG_ADDON && sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
|
||||
stripLineInvisibleChars(msg);
|
||||
|
||||
// Our Warden module also uses SendAddonMessage as a way to communicate Lua check results to the server, see if this is that
|
||||
if ((type == CHAT_MSG_GUILD) && (lang == LANG_ADDON) && _warden && _warden->ProcessLuaCheckResponse(msg))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// pussywizard:
|
||||
if (msg.length() > 255 || (lang != LANG_ADDON && msg.find("|0") != std::string::npos))
|
||||
return;
|
||||
|
||||
@@ -391,12 +391,16 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
|
||||
if (updater.ProcessLogout())
|
||||
{
|
||||
if (m_Socket && !m_Socket->IsClosed() && _warden)
|
||||
{
|
||||
_warden->Update(diff);
|
||||
}
|
||||
|
||||
time_t currTime = time(nullptr);
|
||||
if (ShouldLogOut(currTime) && !m_playerLoading)
|
||||
{
|
||||
LogoutPlayer(true);
|
||||
|
||||
if (m_Socket && !m_Socket->IsClosed() && _warden)
|
||||
_warden->Update();
|
||||
}
|
||||
|
||||
if (m_Socket && m_Socket->IsClosed())
|
||||
{
|
||||
@@ -405,7 +409,9 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
||||
}
|
||||
|
||||
if (!m_Socket)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
#include "Warden.h"
|
||||
#include "AccountMgr.h"
|
||||
#include "BanManager.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
Warden::Warden() : _session(nullptr), _inputCrypto(16), _outputCrypto(16), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0),
|
||||
_dataSent(false), _previousTimestamp(0), _module(nullptr), _initialized(false)
|
||||
_dataSent(false), _module(nullptr), _initialized(false)
|
||||
{
|
||||
memset(_inputKey, 0, sizeof(_inputKey));
|
||||
memset(_outputKey, 0, sizeof(_outputKey));
|
||||
@@ -77,6 +78,8 @@ void Warden::RequestModule()
|
||||
memcpy(request.ModuleKey, _module->Key, 16);
|
||||
request.Size = _module->CompressedSize;
|
||||
|
||||
EndianConvert(request.Size);
|
||||
|
||||
// Encrypt with warden RC4 key.
|
||||
EncryptData((uint8*)&request, sizeof(WardenModuleUse));
|
||||
|
||||
@@ -85,31 +88,37 @@ void Warden::RequestModule()
|
||||
_session->SendPacket(&pkt);
|
||||
}
|
||||
|
||||
void Warden::Update()
|
||||
void Warden::Update(uint32 const diff)
|
||||
{
|
||||
if (_initialized)
|
||||
if (!_initialized)
|
||||
{
|
||||
uint32 currentTimestamp = World::GetGameTimeMS();
|
||||
uint32 diff = getMSTimeDiff(_previousTimestamp, currentTimestamp);
|
||||
_previousTimestamp = currentTimestamp;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_dataSent)
|
||||
if (_dataSent)
|
||||
{
|
||||
uint32 maxClientResponseDelay = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
|
||||
if (maxClientResponseDelay > 0)
|
||||
{
|
||||
uint32 maxClientResponseDelay = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY);
|
||||
if (maxClientResponseDelay > 0)
|
||||
if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS)
|
||||
{
|
||||
if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS)
|
||||
_session->KickPlayer("clientResponseTimer > maxClientResponseDelay");
|
||||
else
|
||||
_clientResponseTimer += diff;
|
||||
_session->KickPlayer("Warden: clientResponseTimer > maxClientResponseDelay (Warden::Update)");
|
||||
}
|
||||
else
|
||||
{
|
||||
_clientResponseTimer += diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (diff >= _checkTimer)
|
||||
{
|
||||
RequestChecks();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (diff >= _checkTimer)
|
||||
RequestData();
|
||||
else
|
||||
_checkTimer -= diff;
|
||||
_checkTimer -= diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,136 +175,142 @@ uint32 Warden::BuildChecksum(const uint8* data, uint32 length)
|
||||
SHA1(data, length, hash.bytes.bytes);
|
||||
uint32 checkSum = 0;
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
{
|
||||
checkSum = checkSum ^ hash.ints.ints[i];
|
||||
}
|
||||
|
||||
return checkSum;
|
||||
}
|
||||
|
||||
std::string Warden::Penalty(WardenCheck* check /*= NULL*/, uint16 checkFailed /*= 0*/)
|
||||
static std::string GetWardenActionStr(uint32 action)
|
||||
{
|
||||
WardenActions action;
|
||||
switch (action)
|
||||
{
|
||||
case WARDEN_ACTION_LOG:
|
||||
return "WARDEN_ACTION_LOG";
|
||||
case WARDEN_ACTION_KICK:
|
||||
return "WARDEN_ACTION_KICK";
|
||||
case WARDEN_ACTION_BAN:
|
||||
return "WARDEN_ACTION_BAN";
|
||||
}
|
||||
|
||||
if (check)
|
||||
action = check->Action;
|
||||
else
|
||||
action = WardenActions(sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION));
|
||||
return "UNHANDLED ACTION";
|
||||
}
|
||||
|
||||
std::string banReason = "Anticheat violation";
|
||||
bool longBan = false; // 14d = 1209600s
|
||||
if (checkFailed)
|
||||
switch (checkFailed)
|
||||
void Warden::ApplyPenalty(uint16 checkId, std::string const& reason)
|
||||
{
|
||||
WardenCheck const* checkData = sWardenCheckMgr->GetWardenDataById(checkId);
|
||||
|
||||
uint32 action = WardenActions(sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION));
|
||||
std::string causeMsg;
|
||||
if (checkId && checkData)
|
||||
{
|
||||
action = checkData->Action;
|
||||
|
||||
if (checkData->Comment.empty())
|
||||
{
|
||||
case 47:
|
||||
banReason += " (FrameXML Signature Check)";
|
||||
break;
|
||||
case 51:
|
||||
banReason += " (Lua DoString)";
|
||||
break;
|
||||
case 59:
|
||||
banReason += " (Lua Protection Patch)";
|
||||
break;
|
||||
case 72:
|
||||
banReason += " (Movement State related)";
|
||||
break;
|
||||
case 118:
|
||||
banReason += " (Wall Climb)";
|
||||
break;
|
||||
case 121:
|
||||
banReason += " (No Fall Damage Patch)";
|
||||
break;
|
||||
case 193:
|
||||
banReason += " (Follow Unit Check)";
|
||||
break;
|
||||
case 209:
|
||||
banReason += " (WoWEmuHacker Injection)";
|
||||
longBan = true;
|
||||
break;
|
||||
case 237:
|
||||
banReason += " (AddChatMessage)";
|
||||
break;
|
||||
case 246:
|
||||
banReason += " (Language Patch)";
|
||||
break;
|
||||
case 260:
|
||||
banReason += " (Jump Momentum)";
|
||||
break;
|
||||
case 288:
|
||||
banReason += " (Language Patch)";
|
||||
break;
|
||||
case 308:
|
||||
banReason += " (SendChatMessage)";
|
||||
break;
|
||||
case 312:
|
||||
banReason += " (Jump Physics)";
|
||||
break;
|
||||
case 314:
|
||||
banReason += " (GetCharacterInfo)";
|
||||
break;
|
||||
case 329:
|
||||
banReason += " (Wall Climb)";
|
||||
break;
|
||||
case 343:
|
||||
banReason += " (Login Password Pointer)";
|
||||
break;
|
||||
case 349:
|
||||
banReason += " (Language Patch)";
|
||||
break;
|
||||
case 712:
|
||||
banReason += " (WS2_32.Send)";
|
||||
break;
|
||||
case 780:
|
||||
banReason += " (Lua Protection Remover)";
|
||||
break;
|
||||
case 781:
|
||||
banReason += " (Walk on Water Patch)";
|
||||
break;
|
||||
case 782:
|
||||
banReason += " (Collision M2 Special)";
|
||||
longBan = true;
|
||||
break;
|
||||
case 783:
|
||||
banReason += " (Collision M2 Regular)";
|
||||
longBan = true;
|
||||
break;
|
||||
case 784:
|
||||
banReason += " (Collision WMD)";
|
||||
longBan = true;
|
||||
break;
|
||||
case 785:
|
||||
banReason += " (Multi-Jump Patch)";
|
||||
break;
|
||||
case 786:
|
||||
banReason += " (WPE PRO)";
|
||||
longBan = true;
|
||||
break;
|
||||
case 787:
|
||||
banReason += " (rEdoX Packet Editor)";
|
||||
break;
|
||||
causeMsg = "Warden id " + std::to_string(checkId) + " violation";
|
||||
}
|
||||
else
|
||||
{
|
||||
causeMsg = "Warden: " + checkData->Comment;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if its not warden check id based, reason must be always provided
|
||||
ASSERT(!reason.empty());
|
||||
causeMsg = reason;
|
||||
}
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case WARDEN_ACTION_LOG:
|
||||
return "None";
|
||||
break;
|
||||
case WARDEN_ACTION_KICK:
|
||||
_session->KickPlayer("WARDEN_ACTION_KICK");
|
||||
return "Kick";
|
||||
{
|
||||
_session->KickPlayer(causeMsg.find("Warden") != std::string::npos ? causeMsg : "Warden: " + causeMsg);
|
||||
break;
|
||||
}
|
||||
case WARDEN_ACTION_BAN:
|
||||
{
|
||||
std::stringstream duration;
|
||||
duration << sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_BAN_DURATION) << "s";
|
||||
std::string accountName;
|
||||
AccountMgr::GetName(_session->GetAccountId(), accountName);
|
||||
sBan->BanAccount(accountName, ((longBan && false /*ZOMG!*/) ? "1209600s" : duration.str()), banReason, "Server");
|
||||
|
||||
return "Ban";
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::stringstream duration;
|
||||
duration << sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_BAN_DURATION) << "s";
|
||||
std::string accountName;
|
||||
AccountMgr::GetName(_session->GetAccountId(), accountName);
|
||||
sBan->BanAccount(accountName, duration.str(), causeMsg, "Server");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return "Undefined";
|
||||
|
||||
std::string reportMsg;
|
||||
if (checkId)
|
||||
{
|
||||
if (Player const* plr = _session->GetPlayer())
|
||||
{
|
||||
std::string const reportFormat = "Player %s (guid %u, account id: %u) failed warden %u check (%s). Action: %s";
|
||||
reportMsg = acore::StringFormat(reportFormat, plr->GetName().c_str(), plr->GetGUIDLow(), _session->GetAccountId(),
|
||||
checkId, ((checkData && !checkData->Comment.empty()) ? checkData->Comment.c_str() : "<warden comment is not set>"),
|
||||
GetWardenActionStr(action).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string const reportFormat = "Account id: %u failed warden %u check. Action: %s";
|
||||
reportMsg = acore::StringFormat(reportFormat, _session->GetAccountId(), checkId, GetWardenActionStr(action).c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Player const* plr = _session->GetPlayer())
|
||||
{
|
||||
std::string const reportFormat = "Player %s (guid %u, account id: %u) triggered warden penalty by reason: %s. Action: %s";
|
||||
reportMsg = acore::StringFormat(reportFormat, plr->GetName().c_str(), plr->GetGUIDLow(), _session->GetAccountId(), causeMsg.c_str(), GetWardenActionStr(action).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string const reportFormat = "Account id: %u failed warden %u check. Action: %s";
|
||||
reportMsg = acore::StringFormat(reportFormat, _session->GetAccountId(), causeMsg.c_str(), GetWardenActionStr(action).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
reportMsg = "Warden: " + reportMsg;
|
||||
sLog->outString(reportMsg.c_str());
|
||||
}
|
||||
|
||||
bool Warden::ProcessLuaCheckResponse(std::string const& msg)
|
||||
{
|
||||
static constexpr char WARDEN_TOKEN[] = "_TW\t";
|
||||
// if msg starts with WARDEN_TOKEN
|
||||
if (!(msg.rfind(WARDEN_TOKEN, 0) == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 id = 0;
|
||||
|
||||
{
|
||||
std::stringstream msg2(msg);
|
||||
std::string temp;
|
||||
while (msg2 >> temp)
|
||||
{
|
||||
// Found check id - stop loop
|
||||
if (std::stringstream(temp) >> id)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id < sWardenCheckMgr->GetMaxValidCheckId())
|
||||
{
|
||||
WardenCheck const* check = sWardenCheckMgr->GetWardenDataById(id);
|
||||
if (check && check->Type == LUA_EVAL_CHECK)
|
||||
{
|
||||
ApplyPenalty(id, "");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ApplyPenalty(0, "Sent bogus Lua check response for Warden");
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData)
|
||||
|
||||
@@ -38,7 +38,7 @@ enum WardenCheckType
|
||||
PAGE_CHECK_A = 0xB2, // 178: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans all pages for specified hash)
|
||||
PAGE_CHECK_B = 0xBF, // 191: uint Seed + byte[20] SHA1 + uint Addr + byte Len (scans only pages starts with MZ+PE headers for specified hash)
|
||||
MPQ_CHECK = 0x98, // 152: byte fileNameIndex (check to ensure MPQ file isn't modified)
|
||||
LUA_STR_CHECK = 0x8B, // 139: byte luaNameIndex (check to ensure LUA string isn't used)
|
||||
LUA_EVAL_CHECK = 139, // evaluate arbitrary Lua check
|
||||
DRIVER_CHECK = 0x71, // 113: uint Seed + byte[20] SHA1 + byte driverNameIndex (check to ensure driver isn't loaded)
|
||||
TIMING_CHECK = 0x57, // 87: empty (check to ensure GetTickCount() isn't detoured)
|
||||
PROC_CHECK = 0x7E, // 126: uint Seed + byte[20] SHA1 + byte moluleNameIndex + byte procNameIndex + uint Offset + byte Len (check to ensure proc isn't detoured)
|
||||
@@ -101,21 +101,22 @@ public:
|
||||
virtual ClientWardenModule* GetModuleForClient() = 0;
|
||||
virtual void InitializeModule() = 0;
|
||||
virtual void RequestHash() = 0;
|
||||
virtual void HandleHashResult(ByteBuffer& buff) = 0;
|
||||
virtual void RequestData() = 0;
|
||||
virtual void HandleData(ByteBuffer& buff) = 0;
|
||||
virtual void HandleHashResult(ByteBuffer &buff) = 0;
|
||||
virtual void RequestChecks() = 0;
|
||||
virtual void HandleData(ByteBuffer &buff) = 0;
|
||||
bool ProcessLuaCheckResponse(std::string const& msg);
|
||||
|
||||
void SendModuleToClient();
|
||||
void RequestModule();
|
||||
void Update();
|
||||
void Update(uint32 const diff);
|
||||
void DecryptData(uint8* buffer, uint32 length);
|
||||
void EncryptData(uint8* buffer, uint32 length);
|
||||
|
||||
static bool IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 length);
|
||||
static uint32 BuildChecksum(const uint8* data, uint32 length);
|
||||
static bool IsValidCheckSum(uint32 checksum, const uint8 *data, const uint16 length);
|
||||
static uint32 BuildChecksum(const uint8 *data, uint32 length);
|
||||
|
||||
// If no check is passed, the default action from config is executed
|
||||
std::string Penalty(WardenCheck* check = NULL, uint16 checkFailed = 0);
|
||||
void ApplyPenalty(uint16 checkId, std::string const& reason);
|
||||
|
||||
private:
|
||||
WorldSession* _session;
|
||||
@@ -127,7 +128,6 @@ private:
|
||||
uint32 _checkTimer; // Timer for sending check requests
|
||||
uint32 _clientResponseTimer; // Timer for client response delay
|
||||
bool _dataSent;
|
||||
uint32 _previousTimestamp;
|
||||
ClientWardenModule* _module;
|
||||
bool _initialized;
|
||||
};
|
||||
|
||||
@@ -19,11 +19,6 @@ WardenCheckMgr::WardenCheckMgr()
|
||||
|
||||
WardenCheckMgr::~WardenCheckMgr()
|
||||
{
|
||||
for (uint16 i = 0; i < CheckStore.size(); ++i)
|
||||
delete CheckStore[i];
|
||||
|
||||
for (CheckResultContainer::iterator itr = CheckResultStore.begin(); itr != CheckResultStore.end(); ++itr)
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
WardenCheckMgr* WardenCheckMgr::instance()
|
||||
@@ -67,6 +62,13 @@ void WardenCheckMgr::LoadWardenChecks()
|
||||
|
||||
uint16 id = fields[0].GetUInt16();
|
||||
uint8 checkType = fields[1].GetUInt8();
|
||||
|
||||
if (checkType == LUA_EVAL_CHECK && id > 9999)
|
||||
{
|
||||
sLog->outError("sql.sql: Warden Lua check with id %u found in `warden_checks`. Lua checks may have four-digit IDs at most. Skipped.", id);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string data = fields[2].GetString();
|
||||
std::string checkResult = fields[3].GetString();
|
||||
uint32 address = fields[4].GetUInt32();
|
||||
@@ -74,66 +76,96 @@ void WardenCheckMgr::LoadWardenChecks()
|
||||
std::string str = fields[6].GetString();
|
||||
std::string comment = fields[7].GetString();
|
||||
|
||||
WardenCheck* wardenCheck = new WardenCheck();
|
||||
wardenCheck->Type = checkType;
|
||||
wardenCheck->CheckId = id;
|
||||
WardenCheck &wardenCheck = CheckStore.at(id);
|
||||
wardenCheck.Type = checkType;
|
||||
wardenCheck.CheckId = id;
|
||||
|
||||
// Initialize action with default action from config
|
||||
wardenCheck->Action = WardenActions(sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION));
|
||||
|
||||
if (checkType == PAGE_CHECK_A || checkType == PAGE_CHECK_B || checkType == DRIVER_CHECK)
|
||||
wardenCheck.Action = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION);
|
||||
if (wardenCheck.Action > MAX_WARDEN_ACTION)
|
||||
{
|
||||
wardenCheck->Data.SetHexStr(data.c_str());
|
||||
int len = data.size() / 2;
|
||||
|
||||
if (wardenCheck->Data.GetNumBytes() < len)
|
||||
{
|
||||
uint8 temp[24];
|
||||
memset(temp, 0, len);
|
||||
memcpy(temp, wardenCheck->Data.AsByteArray().get(), wardenCheck->Data.GetNumBytes());
|
||||
std::reverse(temp, temp + len);
|
||||
wardenCheck->Data.SetBinary((uint8*)temp, len);
|
||||
}
|
||||
wardenCheck.Action = WARDEN_ACTION_BAN;
|
||||
}
|
||||
|
||||
if (checkType == MEM_CHECK || checkType == MODULE_CHECK)
|
||||
MemChecksIdPool.push_back(id);
|
||||
else
|
||||
OtherChecksIdPool.push_back(id);
|
||||
|
||||
if (checkType == MEM_CHECK || checkType == PAGE_CHECK_A || checkType == PAGE_CHECK_B || checkType == PROC_CHECK)
|
||||
{
|
||||
wardenCheck->Address = address;
|
||||
wardenCheck->Length = length;
|
||||
wardenCheck.Address = address;
|
||||
wardenCheck.Length = length;
|
||||
}
|
||||
|
||||
// PROC_CHECK support missing
|
||||
if (checkType == MEM_CHECK || checkType == MPQ_CHECK || checkType == LUA_STR_CHECK || checkType == DRIVER_CHECK || checkType == MODULE_CHECK)
|
||||
wardenCheck->Str = str;
|
||||
|
||||
CheckStore[id] = wardenCheck;
|
||||
if (checkType == MEM_CHECK || checkType == MPQ_CHECK || checkType == LUA_EVAL_CHECK || checkType == DRIVER_CHECK || checkType == MODULE_CHECK)
|
||||
{
|
||||
wardenCheck.Str = str;
|
||||
}
|
||||
|
||||
if (checkType == MPQ_CHECK || checkType == MEM_CHECK)
|
||||
{
|
||||
WardenCheckResult* wr = new WardenCheckResult();
|
||||
wr->Result.SetHexStr(checkResult.c_str());
|
||||
int len = checkResult.size() / 2;
|
||||
if (wr->Result.GetNumBytes() < len)
|
||||
WardenCheckResult wr;
|
||||
wr.Result.SetHexStr(checkResult.c_str());
|
||||
int len = static_cast<int>(checkResult.size()) / 2;
|
||||
if (wr.Result.GetNumBytes() < len)
|
||||
{
|
||||
uint8* temp = new uint8[len];
|
||||
memset(temp, 0, len);
|
||||
memcpy(temp, wr->Result.AsByteArray().get(), wr->Result.GetNumBytes());
|
||||
memcpy(temp, wr.Result.AsByteArray().get(), wr.Result.GetNumBytes());
|
||||
std::reverse(temp, temp + len);
|
||||
wr->Result.SetBinary((uint8*)temp, len);
|
||||
wr.Result.SetBinary((uint8*)temp, len);
|
||||
delete [] temp;
|
||||
}
|
||||
CheckResultStore[id] = wr;
|
||||
}
|
||||
|
||||
if (comment.empty())
|
||||
wardenCheck->Comment = "Undocumented Check";
|
||||
wardenCheck.Comment = "Undocumented Check";
|
||||
else
|
||||
wardenCheck->Comment = comment;
|
||||
wardenCheck.Comment = comment;
|
||||
|
||||
// Prepare check pools
|
||||
switch (checkType)
|
||||
{
|
||||
case MEM_CHECK:
|
||||
case MODULE_CHECK:
|
||||
{
|
||||
CheckIdPool[WARDEN_CHECK_MEM_TYPE].push_back(id);
|
||||
break;
|
||||
}
|
||||
case LUA_EVAL_CHECK:
|
||||
{
|
||||
if (wardenCheck.Length > WARDEN_MAX_LUA_CHECK_LENGTH)
|
||||
{
|
||||
sLog->outError("sql.sql: Found over-long Lua check for Warden check with id %u in `warden_checks`. Max length is %u. Skipped.", id, WARDEN_MAX_LUA_CHECK_LENGTH);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string str = fmt::sprintf("%04u", id);
|
||||
ASSERT(str.size() == 4);
|
||||
std::copy(str.begin(), str.end(), wardenCheck.IdStr.begin());
|
||||
|
||||
CheckIdPool[WARDEN_CHECK_LUA_TYPE].push_back(id);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (checkType == PAGE_CHECK_A || checkType == PAGE_CHECK_B || checkType == DRIVER_CHECK)
|
||||
{
|
||||
wardenCheck.Data.SetHexStr(data.c_str());
|
||||
int len = static_cast<int>(data.size()) / 2;
|
||||
|
||||
if (wardenCheck.Data.GetNumBytes() < len)
|
||||
{
|
||||
uint8 temp[24];
|
||||
memset(temp, 0, len);
|
||||
memcpy(temp, wardenCheck.Data.AsByteArray().get(), wardenCheck.Data.GetNumBytes());
|
||||
std::reverse(temp, temp + len);
|
||||
wardenCheck.Data.SetBinary((uint8*)temp, len);
|
||||
}
|
||||
}
|
||||
|
||||
CheckIdPool[WARDEN_CHECK_OTHER_TYPE].push_back(id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
@@ -164,8 +196,6 @@ void WardenCheckMgr::LoadWardenOverrides()
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
ACE_WRITE_GUARD(ACE_RW_Mutex, g, _checkStoreLock);
|
||||
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
@@ -181,7 +211,7 @@ void WardenCheckMgr::LoadWardenOverrides()
|
||||
sLog->outError("Warden check action override for non-existing check (ID: %u, action: %u), skipped", checkId, action);
|
||||
else
|
||||
{
|
||||
CheckStore[checkId]->Action = WardenActions(action);
|
||||
CheckStore.at(checkId).Action = WardenActions(action);
|
||||
++count;
|
||||
}
|
||||
} while (result->NextRow());
|
||||
@@ -190,18 +220,22 @@ void WardenCheckMgr::LoadWardenOverrides()
|
||||
sLog->outString();
|
||||
}
|
||||
|
||||
WardenCheck* WardenCheckMgr::GetWardenDataById(uint16 Id)
|
||||
WardenCheck const* WardenCheckMgr::GetWardenDataById(uint16 Id)
|
||||
{
|
||||
if (Id < CheckStore.size())
|
||||
return CheckStore[Id];
|
||||
return &CheckStore.at(Id);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WardenCheckResult* WardenCheckMgr::GetWardenResultById(uint16 Id)
|
||||
WardenCheckResult const* WardenCheckMgr::GetWardenResultById(uint16 Id)
|
||||
{
|
||||
CheckResultContainer::const_iterator itr = CheckResultStore.find(Id);
|
||||
if (itr != CheckResultStore.end())
|
||||
return itr->second;
|
||||
{
|
||||
return &itr->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,11 +12,22 @@
|
||||
|
||||
enum WardenActions
|
||||
{
|
||||
WARDEN_ACTION_LOG,
|
||||
WARDEN_ACTION_KICK,
|
||||
WARDEN_ACTION_BAN
|
||||
WARDEN_ACTION_LOG = 0,
|
||||
WARDEN_ACTION_KICK = 1,
|
||||
WARDEN_ACTION_BAN = 2,
|
||||
};
|
||||
|
||||
constexpr uint8 MAX_WARDEN_ACTION = 3;
|
||||
|
||||
enum WardenCheckTypes
|
||||
{
|
||||
WARDEN_CHECK_MEM_TYPE = 0,
|
||||
WARDEN_CHECK_LUA_TYPE = 1,
|
||||
WARDEN_CHECK_OTHER_TYPE = 2,
|
||||
};
|
||||
|
||||
constexpr uint8 MAX_WARDEN_CHECK_TYPES = 3;
|
||||
|
||||
struct WardenCheck
|
||||
{
|
||||
uint8 Type;
|
||||
@@ -26,9 +37,12 @@ struct WardenCheck
|
||||
std::string Str; // LUA, MPQ, DRIVER
|
||||
std::string Comment;
|
||||
uint16 CheckId;
|
||||
enum WardenActions Action;
|
||||
std::array<char, 4> IdStr = {}; // LUA
|
||||
uint32 Action;
|
||||
};
|
||||
|
||||
constexpr uint8 WARDEN_MAX_LUA_CHECK_LENGTH = 170;
|
||||
|
||||
struct WardenCheckResult
|
||||
{
|
||||
BigNumber Result; // MEM_CHECK
|
||||
@@ -43,23 +57,21 @@ public:
|
||||
static WardenCheckMgr* instance();
|
||||
|
||||
// We have a linear key without any gaps, so we use vector for fast access
|
||||
typedef std::vector<WardenCheck*> CheckContainer;
|
||||
typedef std::map<uint32, WardenCheckResult*> CheckResultContainer;
|
||||
typedef std::vector<WardenCheck> CheckContainer;
|
||||
typedef std::map<uint32, WardenCheckResult> CheckResultContainer;
|
||||
|
||||
WardenCheck* GetWardenDataById(uint16 Id);
|
||||
WardenCheckResult* GetWardenResultById(uint16 Id);
|
||||
uint16 GetMaxValidCheckId() const { return static_cast<uint16>(CheckStore.size()); }
|
||||
WardenCheck const* GetWardenDataById(uint16 Id);
|
||||
WardenCheckResult const* GetWardenResultById(uint16 Id);
|
||||
|
||||
std::vector<uint16> MemChecksIdPool;
|
||||
std::vector<uint16> OtherChecksIdPool;
|
||||
std::vector<uint16> CheckIdPool[MAX_WARDEN_CHECK_TYPES];
|
||||
|
||||
void LoadWardenChecks();
|
||||
void LoadWardenOverrides();
|
||||
|
||||
ACE_RW_Mutex _checkStoreLock;
|
||||
|
||||
private:
|
||||
CheckContainer CheckStore;
|
||||
CheckResultContainer CheckResultStore;
|
||||
std::vector<WardenCheck> CheckStore;
|
||||
std::map<uint32, WardenCheckResult> CheckResultStore;
|
||||
};
|
||||
|
||||
#define sWardenCheckMgr WardenCheckMgr::instance()
|
||||
|
||||
@@ -166,7 +166,7 @@ void WardenMac::HandleHashResult(ByteBuffer& buff)
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "Request hash reply: failed");
|
||||
#endif
|
||||
Penalty();
|
||||
ApplyPenalty(0, "Request hash reply: failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -188,11 +188,9 @@ void WardenMac::HandleHashResult(ByteBuffer& buff)
|
||||
_outputCrypto.Init(_outputKey);
|
||||
|
||||
_initialized = true;
|
||||
|
||||
_previousTimestamp = World::GetGameTimeMS();
|
||||
}
|
||||
|
||||
void WardenMac::RequestData()
|
||||
void WardenMac::RequestChecks()
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "Request data");
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
void InitializeModule() override;
|
||||
void RequestHash() override;
|
||||
void HandleHashResult(ByteBuffer& buff) override;
|
||||
void RequestData() override;
|
||||
void RequestChecks() override;
|
||||
void HandleData(ByteBuffer& buff) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -22,23 +22,72 @@
|
||||
#include "WardenCheckMgr.h"
|
||||
#include "AccountMgr.h"
|
||||
|
||||
// GUILD is the shortest string that has no client validation (RAID only sends if in a raid group)
|
||||
static constexpr char _luaEvalPrefix[] = "local S,T,R=SendAddonMessage,function()";
|
||||
static constexpr char _luaEvalMidfix[] = " end R=S and T()if R then S('_TW',";
|
||||
static constexpr char _luaEvalPostfix[] = ",'GUILD')end";
|
||||
|
||||
static_assert((sizeof(_luaEvalPrefix)-1 + sizeof(_luaEvalMidfix)-1 + sizeof(_luaEvalPostfix)-1 + WARDEN_MAX_LUA_CHECK_LENGTH) == 255);
|
||||
|
||||
static constexpr uint8 GetCheckPacketBaseSize(uint8 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DRIVER_CHECK:
|
||||
case MPQ_CHECK: return 1;
|
||||
case LUA_EVAL_CHECK: return 1 + sizeof(_luaEvalPrefix) - 1 + sizeof(_luaEvalMidfix) - 1 + 4 + sizeof(_luaEvalPostfix) - 1;
|
||||
case PAGE_CHECK_A: return (4 + 1);
|
||||
case PAGE_CHECK_B: return (4 + 1);
|
||||
case MODULE_CHECK: return (4 + SHA_DIGEST_LENGTH);
|
||||
case MEM_CHECK: return (1 + 4 + 1);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16 GetCheckPacketSize(WardenCheck const* check)
|
||||
{
|
||||
if (!check)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 size = 1 + GetCheckPacketBaseSize(check->Type); // 1 byte check type
|
||||
if (!check->Str.empty())
|
||||
{
|
||||
size += (static_cast<uint16>(check->Str.length()) + 1); // 1 byte string length
|
||||
}
|
||||
|
||||
BigNumber tempNumber = check->Data;
|
||||
if (!tempNumber.GetNumBytes())
|
||||
{
|
||||
size += tempNumber.GetNumBytes();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
// Returns config id for specific type id
|
||||
static WorldIntConfigs GetMaxWardenChecksForType(uint8 type)
|
||||
{
|
||||
// Should never be higher type than defined
|
||||
ASSERT(type < MAX_WARDEN_CHECK_TYPES);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case WARDEN_CHECK_MEM_TYPE:
|
||||
return CONFIG_WARDEN_NUM_MEM_CHECKS;
|
||||
case WARDEN_CHECK_LUA_TYPE:
|
||||
return CONFIG_WARDEN_NUM_LUA_CHECKS;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return CONFIG_WARDEN_NUM_OTHER_CHECKS;
|
||||
}
|
||||
|
||||
WardenWin::WardenWin() : Warden(), _serverTicks(0) { }
|
||||
|
||||
WardenWin::~WardenWin()
|
||||
{
|
||||
// Xinef: ZOMG! CRASH DEBUG INFO
|
||||
uint32 otherSize = _otherChecksTodo.size();
|
||||
uint32 memSize = _memChecksTodo.size();
|
||||
uint32 curSize = _currentChecks.size();
|
||||
bool otherClear = _otherChecksTodo.empty();
|
||||
bool memClear = _memChecksTodo.empty();
|
||||
bool curClear = _currentChecks.empty();
|
||||
|
||||
sLog->outDebug(LOG_FILTER_POOLSYS, "IM DESTRUCTING MYSELF QQ, OTHERSIZE: %u, OTHEREM: %u, MEMSIZE: %u, MEMEM: %u, CURSIZE: %u, CUREM: %u!\n", otherSize, otherClear, memSize, memClear, curSize, curClear);
|
||||
_otherChecksTodo.clear();
|
||||
_memChecksTodo.clear();
|
||||
_currentChecks.clear();
|
||||
sLog->outDebug(LOG_FILTER_POOLSYS, "IM DESTRUCTING MYSELF QQ, OTHERSIZE: %u, OTHEREM: %u, MEMSIZE: %u, MEMEM: %u, CURSIZE: %u, CUREM: %u!\n", otherSize, otherClear, memSize, memClear, curSize, curClear);
|
||||
}
|
||||
|
||||
void WardenWin::Init(WorldSession* session, BigNumber* k)
|
||||
@@ -109,16 +158,16 @@ void WardenWin::InitializeModule()
|
||||
Request.Function1[1] = 0x000218C0; // 0x00400000 + 0x000218C0 SFileGetFileSize
|
||||
Request.Function1[2] = 0x00022530; // 0x00400000 + 0x00022530 SFileReadFile
|
||||
Request.Function1[3] = 0x00022910; // 0x00400000 + 0x00022910 SFileCloseFile
|
||||
Request.CheckSumm1 = BuildChecksum(&Request.Unk1, 20);
|
||||
Request.CheckSumm1 = BuildChecksum(&Request.Unk1, SHA_DIGEST_LENGTH);
|
||||
|
||||
Request.Command2 = WARDEN_SMSG_MODULE_INITIALIZE;
|
||||
Request.Size2 = 8;
|
||||
Request.Unk3 = 4;
|
||||
Request.Unk4 = 0;
|
||||
Request.String_library2 = 0;
|
||||
Request.Function2 = 0x00419D40; // 0x00400000 + 0x00419D40 FrameScript::GetText
|
||||
Request.Function2 = 0x00419210; // 0x00400000 + 0x00419210 FrameScript::Execute
|
||||
Request.Function2_set = 1;
|
||||
Request.CheckSumm2 = BuildChecksum(&Request.Unk2, 8);
|
||||
Request.CheckSumm2 = BuildChecksum(&Request.Unk3, 8);
|
||||
|
||||
Request.Command3 = WARDEN_SMSG_MODULE_INITIALIZE;
|
||||
Request.Size3 = 8;
|
||||
@@ -129,11 +178,24 @@ void WardenWin::InitializeModule()
|
||||
Request.Function3_set = 1;
|
||||
Request.CheckSumm3 = BuildChecksum(&Request.Unk5, 8);
|
||||
|
||||
EndianConvert(Request.Size1);
|
||||
EndianConvert(Request.CheckSumm1);
|
||||
EndianConvert(Request.Function1[0]);
|
||||
EndianConvert(Request.Function1[1]);
|
||||
EndianConvert(Request.Function1[2]);
|
||||
EndianConvert(Request.Function1[3]);
|
||||
EndianConvert(Request.Size2);
|
||||
EndianConvert(Request.CheckSumm2);
|
||||
EndianConvert(Request.Function2);
|
||||
EndianConvert(Request.Size3);
|
||||
EndianConvert(Request.CheckSumm3);
|
||||
EndianConvert(Request.Function3);
|
||||
|
||||
// Encrypt with warden RC4 key.
|
||||
EncryptData((uint8*)&Request, sizeof(WardenInitModuleRequest));
|
||||
EncryptData(reinterpret_cast<uint8*>(&Request), sizeof(WardenInitModuleRequest));
|
||||
|
||||
WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenInitModuleRequest));
|
||||
pkt.append((uint8*)&Request, sizeof(WardenInitModuleRequest));
|
||||
pkt.append(reinterpret_cast<uint8*>(&Request), sizeof(WardenInitModuleRequest));
|
||||
_session->SendPacket(&pkt);
|
||||
}
|
||||
|
||||
@@ -149,10 +211,10 @@ void WardenWin::RequestHash()
|
||||
memcpy(Request.Seed, _seed, 16);
|
||||
|
||||
// Encrypt with warden RC4 key.
|
||||
EncryptData((uint8*)&Request, sizeof(WardenHashRequest));
|
||||
EncryptData(reinterpret_cast<uint8*>(&Request), sizeof(WardenHashRequest));
|
||||
|
||||
WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenHashRequest));
|
||||
pkt.append((uint8*)&Request, sizeof(WardenHashRequest));
|
||||
pkt.append(reinterpret_cast<uint8*>(&Request), sizeof(WardenHashRequest));
|
||||
_session->SendPacket(&pkt);
|
||||
}
|
||||
|
||||
@@ -161,12 +223,12 @@ void WardenWin::HandleHashResult(ByteBuffer& buff)
|
||||
buff.rpos(buff.wpos());
|
||||
|
||||
// Verify key
|
||||
if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash, 20) != 0)
|
||||
if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash, SHA_DIGEST_LENGTH) != 0)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "Request hash reply: failed");
|
||||
#endif
|
||||
Penalty();
|
||||
ApplyPenalty(0, "Request hash reply: failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -182,83 +244,135 @@ void WardenWin::HandleHashResult(ByteBuffer& buff)
|
||||
_outputCrypto.Init(_outputKey);
|
||||
|
||||
_initialized = true;
|
||||
|
||||
_previousTimestamp = World::GetGameTimeMS();
|
||||
}
|
||||
|
||||
void WardenWin::RequestData()
|
||||
void WardenWin::RequestChecks()
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "Request data");
|
||||
#endif
|
||||
|
||||
// If all checks were done, fill the todo list again
|
||||
if (_memChecksTodo.empty())
|
||||
_memChecksTodo.assign(sWardenCheckMgr->MemChecksIdPool.begin(), sWardenCheckMgr->MemChecksIdPool.end());
|
||||
|
||||
if (_otherChecksTodo.empty())
|
||||
_otherChecksTodo.assign(sWardenCheckMgr->OtherChecksIdPool.begin(), sWardenCheckMgr->OtherChecksIdPool.end());
|
||||
for (uint8 i = 0; i < MAX_WARDEN_CHECK_TYPES; ++i)
|
||||
{
|
||||
if (_ChecksTodo[i].empty())
|
||||
_ChecksTodo[i].assign(sWardenCheckMgr->CheckIdPool[i].begin(), sWardenCheckMgr->CheckIdPool[i].end());
|
||||
}
|
||||
|
||||
_serverTicks = World::GetGameTimeMS();
|
||||
_CurrentChecks.clear();
|
||||
|
||||
uint16 id;
|
||||
uint8 type;
|
||||
WardenCheck* wd;
|
||||
_currentChecks.clear();
|
||||
|
||||
// Build check request
|
||||
for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_MEM_CHECKS); ++i)
|
||||
// No pending checks
|
||||
if (_PendingChecks.empty())
|
||||
{
|
||||
// If todo list is done break loop (will be filled on next Update() run)
|
||||
if (_memChecksTodo.empty())
|
||||
break;
|
||||
for (uint8 checkType = 0; checkType < MAX_WARDEN_CHECK_TYPES; ++checkType)
|
||||
{
|
||||
for (uint32 y = 0; y < sWorld->getIntConfig(GetMaxWardenChecksForType(checkType)); ++y)
|
||||
{
|
||||
// If todo list is done break loop (will be filled on next Update() run)
|
||||
if (_ChecksTodo[checkType].empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Get check id from the end and remove it from todo
|
||||
id = _memChecksTodo.back();
|
||||
_memChecksTodo.pop_back();
|
||||
// Get check id from the end and remove it from todo
|
||||
uint16 const id = _ChecksTodo[checkType].back();
|
||||
_ChecksTodo[checkType].pop_back();
|
||||
|
||||
// Add the id to the list sent in this cycle
|
||||
if (id != 786 /*WPE PRO*/ && id != 209 /*WoWEmuHacker*/)
|
||||
_currentChecks.push_back(id);
|
||||
// Insert check to queue
|
||||
if (checkType == WARDEN_CHECK_LUA_TYPE)
|
||||
{
|
||||
_CurrentChecks.push_front(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
_CurrentChecks.push_back(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_currentChecks.push_back(786);
|
||||
_currentChecks.push_back(209);
|
||||
else
|
||||
{
|
||||
bool hasLuaChecks = false;
|
||||
for (uint16 const checkId : _PendingChecks)
|
||||
{
|
||||
WardenCheck const* check = sWardenCheckMgr->GetWardenDataById(checkId);
|
||||
if (!hasLuaChecks && check->Type == LUA_EVAL_CHECK)
|
||||
{
|
||||
hasLuaChecks = true;
|
||||
}
|
||||
|
||||
_CurrentChecks.push_back(checkId);
|
||||
}
|
||||
|
||||
// Always include lua checks
|
||||
if (!hasLuaChecks)
|
||||
{
|
||||
for (uint32 i = 0; i < sWorld->getIntConfig(GetMaxWardenChecksForType(WARDEN_CHECK_LUA_TYPE)); ++i)
|
||||
{
|
||||
// If todo list is done break loop (will be filled on next Update() run)
|
||||
if (_ChecksTodo[WARDEN_CHECK_LUA_TYPE].empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Get check id from the end and remove it from todo
|
||||
uint16 const id = _ChecksTodo[WARDEN_CHECK_LUA_TYPE].back();
|
||||
_ChecksTodo[WARDEN_CHECK_LUA_TYPE].pop_back();
|
||||
|
||||
// Lua checks must be always in front
|
||||
_CurrentChecks.push_front(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter too high checks queue
|
||||
// Filtered checks will get passed in next checks
|
||||
uint16 expectedSize = 4;
|
||||
_PendingChecks.clear();
|
||||
acore::Containers::EraseIf(_CurrentChecks,
|
||||
[this, &expectedSize](uint16 id)
|
||||
{
|
||||
uint16 const thisSize = GetCheckPacketSize(sWardenCheckMgr->GetWardenDataById(id));
|
||||
if ((expectedSize + thisSize) > 500) // warden packets are truncated to 512 bytes clientside
|
||||
{
|
||||
_PendingChecks.push_back(id);
|
||||
return true;
|
||||
}
|
||||
expectedSize += thisSize;
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
ByteBuffer buff;
|
||||
buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST);
|
||||
|
||||
ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock);
|
||||
|
||||
for (uint32 i = 0; i < sWorld->getIntConfig(CONFIG_WARDEN_NUM_OTHER_CHECKS); ++i)
|
||||
for (uint16 const checkId : _CurrentChecks)
|
||||
{
|
||||
// If todo list is done break loop (will be filled on next Update() run)
|
||||
if (_otherChecksTodo.empty())
|
||||
break;
|
||||
|
||||
// Get check id from the end and remove it from todo
|
||||
id = _otherChecksTodo.back();
|
||||
_otherChecksTodo.pop_back();
|
||||
|
||||
// Add the id to the list sent in this cycle
|
||||
_currentChecks.push_back(id);
|
||||
|
||||
wd = sWardenCheckMgr->GetWardenDataById(id);
|
||||
|
||||
if (wd)
|
||||
switch (wd->Type)
|
||||
WardenCheck const* check = sWardenCheckMgr->GetWardenDataById(checkId);
|
||||
switch (check->Type)
|
||||
{
|
||||
case LUA_EVAL_CHECK:
|
||||
{
|
||||
case MPQ_CHECK:
|
||||
case LUA_STR_CHECK:
|
||||
case DRIVER_CHECK:
|
||||
buff << uint8(wd->Str.size());
|
||||
buff.append(wd->Str.c_str(), wd->Str.size());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
buff << uint8(sizeof(_luaEvalPrefix) - 1 + check->Str.size() + sizeof(_luaEvalMidfix) - 1 + check->IdStr.size() + sizeof(_luaEvalPostfix) - 1);
|
||||
buff.append(_luaEvalPrefix, sizeof(_luaEvalPrefix) - 1);
|
||||
buff.append(check->Str.data(), check->Str.size());
|
||||
buff.append(_luaEvalMidfix, sizeof(_luaEvalMidfix) - 1);
|
||||
buff.append(check->IdStr.data(), check->IdStr.size());
|
||||
buff.append(_luaEvalPostfix, sizeof(_luaEvalPostfix) - 1);
|
||||
break;
|
||||
}
|
||||
case MPQ_CHECK:
|
||||
case DRIVER_CHECK:
|
||||
{
|
||||
buff << uint8(check->Str.size());
|
||||
buff.append(check->Str.c_str(), check->Str.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 xorByte = _inputKey[0];
|
||||
uint8 const xorByte = _inputKey[0];
|
||||
|
||||
// Add TIMING_CHECK
|
||||
buff << uint8(0x00);
|
||||
@@ -266,51 +380,51 @@ void WardenWin::RequestData()
|
||||
|
||||
uint8 index = 1;
|
||||
|
||||
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
|
||||
for (uint16 const checkId : _CurrentChecks)
|
||||
{
|
||||
wd = sWardenCheckMgr->GetWardenDataById(*itr);
|
||||
|
||||
type = wd->Type;
|
||||
buff << uint8(type ^ xorByte);
|
||||
switch (type)
|
||||
WardenCheck const* check = sWardenCheckMgr->GetWardenDataById(checkId);
|
||||
buff << uint8(check->Type ^ xorByte);
|
||||
switch (check->Type)
|
||||
{
|
||||
case MEM_CHECK:
|
||||
{
|
||||
buff << uint8(0x00);
|
||||
buff << uint32(wd->Address);
|
||||
buff << uint8(wd->Length);
|
||||
break;
|
||||
}
|
||||
{
|
||||
buff << uint8(0x00);
|
||||
buff << uint32(check->Address);
|
||||
buff << uint8(check->Length);
|
||||
break;
|
||||
}
|
||||
case PAGE_CHECK_A:
|
||||
case PAGE_CHECK_B:
|
||||
{
|
||||
buff.append(wd->Data.AsByteArray(0, false).get(), wd->Data.GetNumBytes());
|
||||
buff << uint32(wd->Address);
|
||||
buff << uint8(wd->Length);
|
||||
break;
|
||||
}
|
||||
{
|
||||
BigNumber tempNumber = check->Data;
|
||||
buff.append(tempNumber.AsByteArray(0, false).get(), tempNumber.GetNumBytes());
|
||||
buff << uint32(check->Address);
|
||||
buff << uint8(check->Length);
|
||||
break;
|
||||
}
|
||||
case MPQ_CHECK:
|
||||
case LUA_STR_CHECK:
|
||||
{
|
||||
buff << uint8(index++);
|
||||
break;
|
||||
}
|
||||
case LUA_EVAL_CHECK:
|
||||
{
|
||||
buff << uint8(index++);
|
||||
break;
|
||||
}
|
||||
case DRIVER_CHECK:
|
||||
{
|
||||
buff.append(wd->Data.AsByteArray(0, false).get(), wd->Data.GetNumBytes());
|
||||
buff << uint8(index++);
|
||||
break;
|
||||
}
|
||||
{
|
||||
BigNumber tempNumber = check->Data;
|
||||
buff.append(tempNumber.AsByteArray(0, false).get(), tempNumber.GetNumBytes());
|
||||
buff << uint8(index++);
|
||||
break;
|
||||
}
|
||||
case MODULE_CHECK:
|
||||
{
|
||||
uint32 seed = rand32();
|
||||
buff << uint32(seed);
|
||||
HmacHash hmac(4, (uint8*)&seed);
|
||||
hmac.UpdateData(wd->Str);
|
||||
hmac.Finalize();
|
||||
buff.append(hmac.GetDigest(), hmac.GetLength());
|
||||
break;
|
||||
}
|
||||
{
|
||||
uint32 seed = rand32();
|
||||
buff << uint32(seed);
|
||||
HmacHash hmac(4, (uint8*)&seed);
|
||||
hmac.UpdateData(check->Str);
|
||||
hmac.Finalize();
|
||||
buff.append(hmac.GetDigest(), hmac.GetLength());
|
||||
break;
|
||||
}
|
||||
/*case PROC_CHECK:
|
||||
{
|
||||
buff.append(wd->i.AsByteArray(0, false).get(), wd->i.GetNumBytes());
|
||||
@@ -320,8 +434,6 @@ void WardenWin::RequestData()
|
||||
buff << uint8(wd->Length);
|
||||
break;
|
||||
}*/
|
||||
default:
|
||||
break; // Should never happen
|
||||
}
|
||||
}
|
||||
buff << uint8(xorByte);
|
||||
@@ -336,12 +448,14 @@ void WardenWin::RequestData()
|
||||
|
||||
_dataSent = true;
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
std::stringstream stream;
|
||||
stream << "Sent check id's: ";
|
||||
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
|
||||
stream << *itr << " ";
|
||||
for (uint16 checkId : _currentChecks)
|
||||
{
|
||||
stream << checkId << " ";
|
||||
}
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "%s", stream.str().c_str());
|
||||
#endif
|
||||
}
|
||||
@@ -360,13 +474,20 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
uint32 Checksum;
|
||||
buff >> Checksum;
|
||||
|
||||
if (Length != (buff.size() - buff.rpos()))
|
||||
{
|
||||
buff.rfinish();
|
||||
ApplyPenalty(0, "Failed size checks in HandleData");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length))
|
||||
{
|
||||
buff.rpos(buff.wpos());
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "CHECKSUM FAIL");
|
||||
#endif
|
||||
Penalty();
|
||||
ApplyPenalty(0, "Failed checksum in HandleData");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -380,7 +501,7 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "TIMING CHECK FAIL result 0x00");
|
||||
#endif
|
||||
Penalty();
|
||||
ApplyPenalty(0, "TIMING CHECK FAIL result");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,51 +519,46 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
#endif
|
||||
}
|
||||
|
||||
WardenCheckResult* rs;
|
||||
WardenCheck* rd;
|
||||
uint8 type;
|
||||
uint16 checkFailed = 0;
|
||||
|
||||
ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock);
|
||||
|
||||
for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr)
|
||||
for (uint16 const checkId : _CurrentChecks)
|
||||
{
|
||||
rd = sWardenCheckMgr->GetWardenDataById(*itr);
|
||||
rs = sWardenCheckMgr->GetWardenResultById(*itr);
|
||||
|
||||
type = rd->Type;
|
||||
WardenCheck const* rd = sWardenCheckMgr->GetWardenDataById(checkId);
|
||||
uint8 const type = rd->Type;
|
||||
switch (type)
|
||||
{
|
||||
case MEM_CHECK:
|
||||
{
|
||||
uint8 Mem_Result;
|
||||
buff >> Mem_Result;
|
||||
|
||||
if (Mem_Result != 0)
|
||||
{
|
||||
uint8 Mem_Result;
|
||||
buff >> Mem_Result;
|
||||
|
||||
if (Mem_Result != 0)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
#endif
|
||||
checkFailed = *itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false).get(), rd->Length) != 0)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
#endif
|
||||
checkFailed = *itr;
|
||||
buff.rpos(buff.rpos() + rd->Length);
|
||||
continue;
|
||||
}
|
||||
|
||||
buff.rpos(buff.rpos() + rd->Length);
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
#endif
|
||||
break;
|
||||
checkFailed = checkId;
|
||||
continue;
|
||||
}
|
||||
|
||||
WardenCheckResult const* rs = sWardenCheckMgr->GetWardenResultById(checkId);
|
||||
BigNumber tempNumber = rs->Result;
|
||||
if (memcmp(buff.contents() + buff.rpos(), tempNumber.AsByteArray(0, false).get(), rd->Length) != 0)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK fail CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
#endif
|
||||
checkFailed = checkId;
|
||||
buff.rpos(buff.rpos() + rd->Length);
|
||||
continue;
|
||||
}
|
||||
|
||||
buff.rpos(buff.rpos() + rd->Length);
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK passed CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case PAGE_CHECK_A:
|
||||
case PAGE_CHECK_B:
|
||||
case DRIVER_CHECK:
|
||||
@@ -453,15 +569,15 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
if (type == PAGE_CHECK_A || type == PAGE_CHECK_B)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT PAGE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT PAGE_CHECK fail, CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
|
||||
if (type == MODULE_CHECK)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK fail, CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
|
||||
if (type == DRIVER_CHECK)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK fail, CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
#endif
|
||||
checkFailed = *itr;
|
||||
checkFailed = checkId;
|
||||
buff.rpos(buff.rpos() + 1);
|
||||
continue;
|
||||
}
|
||||
@@ -470,44 +586,24 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
if (type == PAGE_CHECK_A || type == PAGE_CHECK_B)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT PAGE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT PAGE_CHECK passed CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
else if (type == MODULE_CHECK)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK passed CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
else if (type == DRIVER_CHECK)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK passed CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case LUA_STR_CHECK:
|
||||
break;
|
||||
}
|
||||
case LUA_EVAL_CHECK:
|
||||
{
|
||||
uint8 const result = buff.read<uint8>();
|
||||
if (result == 0)
|
||||
{
|
||||
uint8 Lua_Result;
|
||||
buff >> Lua_Result;
|
||||
buff.read_skip(buff.read<uint8>()); // discard attached string
|
||||
}
|
||||
|
||||
if (Lua_Result != 0)
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
#endif
|
||||
checkFailed = *itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8 luaStrLen;
|
||||
buff >> luaStrLen;
|
||||
|
||||
if (luaStrLen != 0)
|
||||
{
|
||||
char* str = new char[luaStrLen + 1];
|
||||
memcpy(str, buff.contents() + buff.rpos(), luaStrLen);
|
||||
str[luaStrLen] = '\0'; // null terminator
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "Lua string: %s", str);
|
||||
#endif
|
||||
delete[] str;
|
||||
}
|
||||
buff.rpos(buff.rpos() + luaStrLen); // Skip string
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "LUA_EVAL_CHECK CheckId %u account Id %u got in-warden dummy response", checkId, _session->GetAccountId()/* , result */);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@@ -521,38 +617,37 @@ void WardenWin::HandleData(ByteBuffer& buff)
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId());
|
||||
#endif
|
||||
checkFailed = *itr;
|
||||
checkFailed = checkId;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false).get(), 20) != 0) // SHA1
|
||||
WardenCheckResult const* rs = sWardenCheckMgr->GetWardenResultById(checkId);
|
||||
BigNumber tempNumber = rs->Result;
|
||||
if (memcmp(buff.contents() + buff.rpos(), tempNumber.AsByteArray(0, false).get(), SHA_DIGEST_LENGTH) != 0) // SHA1
|
||||
{
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK fail, CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
#endif
|
||||
checkFailed = *itr;
|
||||
buff.rpos(buff.rpos() + 20); // 20 bytes SHA1
|
||||
checkFailed = checkId;
|
||||
buff.rpos(buff.rpos() + SHA_DIGEST_LENGTH); // 20 bytes SHA1
|
||||
continue;
|
||||
}
|
||||
|
||||
buff.rpos(buff.rpos() + 20); // 20 bytes SHA1
|
||||
buff.rpos(buff.rpos() + SHA_DIGEST_LENGTH); // 20 bytes SHA1
|
||||
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId());
|
||||
sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK passed, CheckId %u account Id %u", checkId, _session->GetAccountId());
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default: // Should never happen
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkFailed > 0)
|
||||
{
|
||||
WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed);
|
||||
Penalty(check, checkFailed);
|
||||
ApplyPenalty(checkFailed, "");
|
||||
}
|
||||
|
||||
// Set hold off timer, minimum timer should at least be 1 second
|
||||
uint32 holdOff = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF);
|
||||
uint32 const holdOff = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF);
|
||||
_checkTimer = (holdOff < 1 ? 1 : holdOff) * IN_MILLISECONDS;
|
||||
}
|
||||
|
||||
@@ -69,14 +69,15 @@ public:
|
||||
void InitializeModule() override;
|
||||
void RequestHash() override;
|
||||
void HandleHashResult(ByteBuffer& buff) override;
|
||||
void RequestData() override;
|
||||
void RequestChecks() override;
|
||||
void HandleData(ByteBuffer& buff) override;
|
||||
|
||||
private:
|
||||
uint32 _serverTicks;
|
||||
std::list<uint16> _otherChecksTodo;
|
||||
std::list<uint16> _memChecksTodo;
|
||||
std::list<uint16> _currentChecks;
|
||||
std::list<uint16> _ChecksTodo[MAX_WARDEN_CHECK_TYPES];
|
||||
|
||||
std::list<uint16> _CurrentChecks;
|
||||
std::list<uint16> _PendingChecks;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // _WARDEN_WIN_H
|
||||
|
||||
@@ -340,6 +340,7 @@ enum WorldIntConfigs
|
||||
CONFIG_WARDEN_CLIENT_FAIL_ACTION,
|
||||
CONFIG_WARDEN_CLIENT_BAN_DURATION,
|
||||
CONFIG_WARDEN_NUM_MEM_CHECKS,
|
||||
CONFIG_WARDEN_NUM_LUA_CHECKS,
|
||||
CONFIG_WARDEN_NUM_OTHER_CHECKS,
|
||||
CONFIG_BIRTHDAY_TIME,
|
||||
CONFIG_SOCKET_TIMEOUTTIME_ACTIVE,
|
||||
|
||||
@@ -1315,6 +1315,7 @@ void World::LoadConfigSettings(bool reload)
|
||||
// Warden
|
||||
m_bool_configs[CONFIG_WARDEN_ENABLED] = sConfigMgr->GetBoolDefault("Warden.Enabled", false);
|
||||
m_int_configs[CONFIG_WARDEN_NUM_MEM_CHECKS] = sConfigMgr->GetIntDefault("Warden.NumMemChecks", 3);
|
||||
m_int_configs[CONFIG_WARDEN_NUM_LUA_CHECKS] = sConfigMgr->GetIntDefault("Warden.NumLuaChecks", 1);
|
||||
m_int_configs[CONFIG_WARDEN_NUM_OTHER_CHECKS] = sConfigMgr->GetIntDefault("Warden.NumOtherChecks", 7);
|
||||
m_int_configs[CONFIG_WARDEN_CLIENT_BAN_DURATION] = sConfigMgr->GetIntDefault("Warden.BanDuration", 86400);
|
||||
m_int_configs[CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF] = sConfigMgr->GetIntDefault("Warden.ClientCheckHoldOff", 30);
|
||||
|
||||
@@ -1590,7 +1590,7 @@ IsPreloadedContinentTransport.Enabled = 0
|
||||
# Default: 0 - (Disabled)
|
||||
# 1 - (Enabled)
|
||||
|
||||
Warden.Enabled = 1
|
||||
Warden.Enabled = 0
|
||||
|
||||
#
|
||||
# Warden.NumMemChecks
|
||||
@@ -1598,7 +1598,15 @@ Warden.Enabled = 1
|
||||
# Default: 3 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
Warden.NumMemChecks = 2
|
||||
Warden.NumMemChecks = 3
|
||||
|
||||
#
|
||||
# Warden.NumLuaChecks
|
||||
# Description: Number of Warden LUA checks that are sent to the client each cycle.
|
||||
# Default: 1 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
Warden.NumLuaChecks = 1
|
||||
|
||||
#
|
||||
# Warden.NumOtherChecks
|
||||
@@ -1607,7 +1615,7 @@ Warden.NumMemChecks = 2
|
||||
# Default: 7 - (Enabled)
|
||||
# 0 - (Disabled)
|
||||
|
||||
Warden.NumOtherChecks = 5
|
||||
Warden.NumOtherChecks = 7
|
||||
|
||||
#
|
||||
# Warden.LogFile
|
||||
@@ -1644,7 +1652,7 @@ Warden.ClientCheckHoldOff = 30
|
||||
# 1 - (Kick)
|
||||
# 2 - (Ban)
|
||||
|
||||
Warden.ClientCheckFailAction = 2
|
||||
Warden.ClientCheckFailAction = 0
|
||||
|
||||
#
|
||||
# Warden.BanDuration
|
||||
|
||||
Reference in New Issue
Block a user