GiSTpenalty * MTentry::Penalty (const GiSTentry &newEntry, MTpenalty *minPenalty) const // in this case we can avoid to compute some distances by using some stored information: // minPenalty (the minimum penalty achieved so far), // newEntry.key->distance (the distance of the entry from the parent of this entry, stored in the SearchMinPenalty method) and maxradius. { assert (newEntry.IsA() == MTENTRY_CLASS); if (((MTkey *) newEntry.Key())->distance > 0 && minPenalty) { // in this case is possible to prune some entries using triangular inequality double distPen = fabs(((MTkey *) newEntry.Key())->distance - Key()->distance) - MaxRadius(); MTpenalty *tmpPen = NULL; if (distPen >= 0) { tmpPen = new MTpenalty (distPen, 0); } else { tmpPen = new MTpenalty (distPen + MaxRadius() - MaxDist(), 0); } if (!((*tmpPen)<(*minPenalty))) { // larger than or equal to minPenalty delete tmpPen; return new MTpenalty (MAXDOUBLE, 0); // avoid to compute this distance } delete tmpPen; } return Penalty (newEntry); }
void WardenWin::HandleHashResult(ByteBuffer &buff) { buff.rpos(buff.wpos()); // Verify key if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash, 20) != 0) { #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_WARDEN, "Request hash reply: failed"); #endif Penalty(); return; } #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_WARDEN, "Request hash reply: succeed"); #endif // Change keys here memcpy(_inputKey, Module.ClientKeySeed, 16); memcpy(_outputKey, Module.ServerKeySeed, 16); _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); _initialized = true; _previousTimestamp = World::GetGameTimeMS(); }
TOD_Turn_Data::TOD_Turn_Data (void) { Start (0); End (0); Use (0); Penalty (0); TOD_List (0); }
// Sometimes deleting a cluster will improve the score, when you take into accout // the BIC. This function sees if this is the case. It will not delete more than // one cluster at a time. void KK::ConsiderDeletion() { int c, p, CandidateClass; float Loss, DeltaPen; Array<float> DeletionLoss(MaxPossibleClusters); // the increase in log P by deleting the cluster for(c=1; c<MaxPossibleClusters; c++) { if (ClassAlive[c]) DeletionLoss[c] = 0; else DeletionLoss[c] = HugeScore; // don't delete classes that are already there } // compute losses by deleting clusters for(p=0; p<nPoints; p++) { DeletionLoss[Class[p]] += LogP[p*MaxPossibleClusters + Class2[p]] - LogP[p*MaxPossibleClusters + Class[p]]; } // find class with least to lose Loss = HugeScore; for(c=1; c<MaxPossibleClusters; c++) { if (DeletionLoss[c]<Loss) { Loss = DeletionLoss[c]; CandidateClass = c; } } // what is the change in penalty? DeltaPen = Penalty(nClustersAlive) - Penalty(nClustersAlive-1); //Output("cand Class %d would lose %f gain is %f\n", CandidateClass, Loss, DeltaPen); // is it worth it? if (Loss<DeltaPen) { Output("Deleting Class %d. Lose %f but Gain %f\n", CandidateClass, Loss, DeltaPen); // set it to dead ClassAlive[CandidateClass] = 0; // re-allocate all of its points for(p=0;p<nPoints; p++) if(Class[p]==CandidateClass) Class[p] = Class2[p]; } Reindex(); }
// ComputeScore() - computes total score. Requires M, E, and C steps to have been run float KK::ComputeScore() { int p; float Score = Penalty(nClustersAlive); for(p=0; p<nPoints; p++) { Score += LogP[p*MaxPossibleClusters + Class[p]]; // Output("point %d: cumulative score %f\n", p, Score); } if (Debug) { int c, cc; float tScore; for(cc=0; cc<nClustersAlive; cc++) { c = AliveIndex[cc]; tScore = 0; for(p=0; p<nPoints; p++) if(Class[p]==c) tScore += LogP[p*MaxPossibleClusters + Class[p]]; Output("class %d has subscore %f\n", c, tScore); } } return Score; }
void WardenWin::HandleData(ByteBuffer &buff) { sLog->outDebug(LOG_FILTER_WARDEN, "Handle data"); _dataSent = false; _clientResponseTimer = 0; uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); sLog->outWarn(LOG_FILTER_WARDEN, "%s failed checksum. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; } // TIMING_CHECK { uint8 result; buff >> result; // TODO: test it. if (result == 0x00) { sLog->outWarn(LOG_FILTER_WARDEN, "%s failed timing check. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks); sLog->outDebug(LOG_FILTER_WARDEN, "ServerTicks %u", ticksNow); // Now sLog->outDebug(LOG_FILTER_WARDEN, "RequestTicks %u", _serverTicks); // At request sLog->outDebug(LOG_FILTER_WARDEN, "Ticks %u", newClientTicks); // At response sLog->outDebug(LOG_FILTER_WARDEN, "Ticks diff %u", ourTicks - newClientTicks); } 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) { rd = sWardenCheckMgr->GetWardenDataById(*itr); rs = sWardenCheckMgr->GetWardenResultById(*itr); type = rd->Type; switch (type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if (Mem_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), rd->Length) != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { 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()); if (type == MODULE_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == DRIVER_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 1); continue; } buff.rpos(buff.rpos() + 1); 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()); else if (type == MODULE_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == DRIVER_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if (Lua_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); 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 sLog->outDebug(LOG_FILTER_WARDEN, "Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // Skip string sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if (Mpq_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), 20) != 0) // SHA1 { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } default: // Should never happen break; } } if (checkFailed > 0) { WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed); sLog->outWarn(LOG_FILTER_WARDEN, "%s failed Warden check %u. Action: %s", _session->GetPlayerInfo().c_str(), checkFailed, Penalty(check).c_str()); } // Set hold off timer, minimum timer should at least be 1 second uint32 holdOff = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF); _checkTimer = (holdOff < 1 ? 1 : holdOff) * IN_MILLISECONDS; }
void WardenWin::HandleHashResult(ByteBuffer &buff) { buff.rpos(buff.wpos()); // Verify key if (memcmp(buff.contents() + 1, Module.ClientKeySeedHash, 20) != 0) { sLog->outWarn(LOG_FILTER_WARDEN, "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; } sLog->outDebug(LOG_FILTER_WARDEN, "Request hash reply: succeed"); // Change keys here memcpy(_inputKey, Module.ClientKeySeed, 16); memcpy(_outputKey, Module.ServerKeySeed, 16); _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); _initialized = true; _previousTimestamp = getMSTime(); }
void WardenMac::HandleHashResult(ByteBuffer &buff) { // test int keyIn[4]; uint8 mod_seed[16] = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE }; for (int i = 0; i < 4; ++i) { keyIn[i] = *(int*)(&mod_seed[0] + i * 4); } int keyOut[4]; int keyIn1, keyIn2; keyOut[0] = keyIn[0]; keyIn[0] ^= 0xDEADBEEFu; keyIn1 = keyIn[1]; keyIn[1] -= 0x35014542u; keyIn2 = keyIn[2]; keyIn[2] += 0x5313F22u; keyIn[3] *= 0x1337F00Du; keyOut[1] = keyIn1 - 0x6A028A84; keyOut[2] = keyIn2 + 0xA627E44; keyOut[3] = 0x1337F00D * keyIn[3]; // end test buff.rpos(buff.wpos()); SHA1Hash sha1; sha1.UpdateData((uint8*)keyIn, 16); sha1.Finalize(); //const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E }; // Verify key if (memcmp(buff.contents() + 1, sha1.GetDigest(), 20) != 0) { sLog->outWarn(LOG_FILTER_WARDEN, "%s failed hash reply. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; } sLog->outDebug(LOG_FILTER_WARDEN, "Request hash reply: succeed"); // client 7F96EEFDA5B63D20A4DF8E00CBF48304 //const uint8 client_key[16] = { 0x7F, 0x96, 0xEE, 0xFD, 0xA5, 0xB6, 0x3D, 0x20, 0xA4, 0xDF, 0x8E, 0x00, 0xCB, 0xF4, 0x83, 0x04 }; // server C2B7ADEDFCCCA9C2BFB3F85602BA809B //const uint8 server_key[16] = { 0xC2, 0xB7, 0xAD, 0xED, 0xFC, 0xCC, 0xA9, 0xC2, 0xBF, 0xB3, 0xF8, 0x56, 0x02, 0xBA, 0x80, 0x9B }; // change keys here memcpy(_inputKey, keyIn, 16); memcpy(_outputKey, keyOut, 16); _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); _initialized = true; _previousTimestamp = getMSTime(); }
void WardenWin::HandleData(ByteBuffer &buff) { sLog->outWarden("Handle data"); _dataSent = false; _clientResponseTimer = 0; // DEBUG CODE if (_requestSent < time(NULL) - 30) { sLog->outError("WARDEN: Player %s (guid: %u, account: %u) took %s to respond to warden check request", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), secsToTimeString(uint32(time(NULL)- _requestSent), true).c_str()); } uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); sLog->outWarden("CHECKSUM FAIL"); sLog->outError("WARDEN: Player %s (guid: %u, account: %u) failed checksum. Action: %s", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), Penalty().c_str()); return; } // TIMING_CHECK { uint8 result; buff >> result; // TODO: test it. if (result == 0x00) { sLog->outWarden("TIMING CHECK FAIL result 0x00"); sLog->outError("WARDEN: Player %s (guid: %u, account: %u) failed timing check. Action: %s", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), Penalty().c_str()); return; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks); sLog->outWarden("ServerTicks %u", ticksNow); // Now sLog->outWarden("RequestTicks %u", _serverTicks); // At request sLog->outWarden("Ticks %u", newClientTicks); // At response sLog->outWarden("Ticks diff %u", ourTicks - newClientTicks); } WardenCheckResult *rs; WardenCheck *rd; uint8 type; uint32 checkFailed = 0; for (std::list<uint32>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr) { rd = sWardenCheckMgr->GetWardenDataById(*itr); rs = sWardenCheckMgr->GetWardenResultById(*itr); type = rd->Type; switch (type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if (Mem_Result != 0) { sLog->outWarden("RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), rd->Length) != 0) { sLog->outWarden("RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog->outWarden("RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outWarden("RESULT PAGE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == MODULE_CHECK) sLog->outWarden("RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == DRIVER_CHECK) sLog->outWarden("RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 1); continue; } buff.rpos(buff.rpos() + 1); if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outWarden("RESULT PAGE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == MODULE_CHECK) sLog->outWarden("RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == DRIVER_CHECK) sLog->outWarden("RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if (Lua_Result != 0) { sLog->outWarden("RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } uint8 luaStrLen; buff >> luaStrLen; if (luaStrLen != 0) { char *str = new char[luaStrLen + 1]; memset(str, 0, luaStrLen + 1); memcpy(str, buff.contents() + buff.rpos(), luaStrLen); sLog->outWarden("Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // Skip string sLog->outWarden("RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if (Mpq_Result != 0) { sLog->outWarden("RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), 20) != 0) // SHA1 { sLog->outWarden("RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog->outWarden("RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } default: // Should never happen break; } } if (checkFailed > 0) { sLog->outError("WARDEN: Player %s (guid: %u, account: %u) failed Warden check %u. Action: %s", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), checkFailed, Penalty().c_str()); } // Set hold off timer _checkTimer = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF); }
void WardenWin::HandleHashResult(ByteBuffer &buff) { buff.rpos(buff.wpos()); const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E }; // verify key not equal kick player if (memcmp(buff.contents() + 1, validHash, sizeof(validHash)) != 0) { sLog->outWarden("Request hash reply: failed"); sLog->outError("WARDEN: Player %s (guid: %u, account: %u) failed hash reply. Action: %s", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), Penalty().c_str()); return; } sLog->outWarden("Request hash reply: succeed"); // client 7F96EEFDA5B63D20A4DF8E00CBF48304 const uint8 client_key[16] = { 0x7F, 0x96, 0xEE, 0xFD, 0xA5, 0xB6, 0x3D, 0x20, 0xA4, 0xDF, 0x8E, 0x00, 0xCB, 0xF4, 0x83, 0x04 }; // server C2B7ADEDFCCCA9C2BFB3F85602BA809B const uint8 server_key[16] = { 0xC2, 0xB7, 0xAD, 0xED, 0xFC, 0xCC, 0xA9, 0xC2, 0xBF, 0xB3, 0xF8, 0x56, 0x02, 0xBA, 0x80, 0x9B }; // change keys here memcpy(_inputKey, client_key, 16); memcpy(_outputKey, server_key, 16); _inputCrypto.Init(_inputKey); _outputCrypto.Init(_outputKey); _initialized = true; _previousTimestamp = getMSTime(); }
void WardenWin::HandleData(ByteBuffer &buff) { sLog->outDebug(LOG_FILTER_WARDEN, "Handle data"); _dataSent = false; _clientResponseTimer = 0; uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); sLog->outWarn(LOG_FILTER_WARDEN, "%s failed checksum. Action: %s", _session->GetPlayerName(false).c_str(), Penalty().c_str()); return; } // TIMING_CHECK { uint8 result; buff >> result; // TODO: test it. if (result == 0x00) { sLog->outWarn(LOG_FILTER_WARDEN, "%s failed timing check. Action: %s", _session->GetPlayerName(false).c_str(), Penalty().c_str()); return; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks); sLog->outDebug(LOG_FILTER_WARDEN, "ServerTicks %u", ticksNow); // Now sLog->outDebug(LOG_FILTER_WARDEN, "RequestTicks %u", _serverTicks); // At request sLog->outDebug(LOG_FILTER_WARDEN, "Ticks %u", newClientTicks); // At response sLog->outDebug(LOG_FILTER_WARDEN, "Ticks diff %u", ourTicks - newClientTicks); } 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) { rd = sWardenCheckMgr->GetWardenDataById(*itr); rs = sWardenCheckMgr->GetWardenResultById(*itr); type = rd->Type; switch (type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if (Mem_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), rd->Length) != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { 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()); if (type == MODULE_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == DRIVER_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 1); continue; } buff.rpos(buff.rpos() + 1); 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()); else if (type == MODULE_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == DRIVER_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if (Lua_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } uint8 luaStrLen; buff >> luaStrLen; if (luaStrLen != 0) { char *str = new char[luaStrLen + 1]; memset(str, 0, luaStrLen + 1); memcpy(str, buff.contents() + buff.rpos(), luaStrLen); sLog->outDebug(LOG_FILTER_WARDEN, "Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // Skip string sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if (Mpq_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), 20) != 0) // SHA1 { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } default: // Should never happen break; } } if (checkFailed > 0) { WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed); sLog->outWarn(LOG_FILTER_WARDEN, "%s failed Warden check %u. Action: %s", _session->GetPlayerName(false).c_str(), checkFailed, Penalty(check).c_str()); // TriniChat Extension if (Player* player = _session->GetPlayer()) { // Make sure to keep the signal/noise ratio in tact by ignoring checks that are not necessarily cheats if (checkFailed != 88 // Undocumented Check && checkFailed != 134 // Undocumented Check && checkFailed != 261 // Undocumented Check && checkFailed != 437 // Login State - (May be false positive) && checkFailed != 777) // Undocumented Check { std::ostringstream string; string << "PRIVMSG ChanServ :TOPIC #wowteam \x02\x03" << "4[Warden]\x03 (" << uint16(player->getLevel()) << ") " << player->GetName() << "\x02 (GUID: " << player->GetGUIDLow() << ", Account: " << _session->GetAccountId() << ")"; string << " \x03" << "4-\x03 \x02" << "Failed Check " << checkFailed << " (" << check->Comment << ")" << " \x02"; string << " \x03" << "4-\x03 \x02" << "Position:\x02 " << player->GetPositionX() << " " << player->GetPositionY() << " " << player->GetPositionZ() << " " << player->GetMapId(); string << " \x03" << "4-\x03 \x02" << "Latency:\x02 " << _session->GetLatency() << " ms"; sIRC.SendIRC(string.str()); } } // TriniChat Extension END } // Set hold off timer, minimum timer should at least be 1 second uint32 holdOff = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF); _checkTimer = (holdOff < 1 ? 1 : holdOff) * IN_MILLISECONDS; }
void WardenWin::HandleData(ByteBuffer &buff) { sLog.outWarden("Handle data"); _dataSent = false; _clientResponseTimer = 0; uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); sLog.outWarden("%s failed checksum. Action: %s", _session->GetPlayerName(), Penalty().c_str()); return; } // TIMING_CHECK { uint8 result; buff >> result; /// @todo test it. if (result == 0x00) { sLog.outWarden("%s failed timing check. Action: %s", _session->GetPlayerName(), Penalty().c_str()); return; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = WorldTimer::getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks); sLog.outWarden("ServerTicks %u, RequestTicks %u, CLientTicks %u", ticksNow, _serverTicks, newClientTicks); // Now, At request, At response sLog.outWarden("Waittime %u", ourTicks - newClientTicks); } 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) { rd = sWardenCheckMgr->GetWardenDataById(_session->GetClientBuild(), *itr); rs = sWardenCheckMgr->GetWardenResultById(_session->GetClientBuild(), *itr); type = rd->Type; switch (type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if (Mem_Result != 0) { sLog.outWarden("RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), rd->Length) != 0) { sLog.outWarden("RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog.outWarden("RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog.outWarden("RESULT PAGE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == MODULE_CHECK) sLog.outWarden("RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == DRIVER_CHECK) sLog.outWarden("RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 1); continue; } buff.rpos(buff.rpos() + 1); if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog.outWarden("RESULT PAGE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == MODULE_CHECK) sLog.outWarden("RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == DRIVER_CHECK) sLog.outWarden("RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if (Lua_Result != 0) { sLog.outWarden("RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); 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 sLog.outWarden("Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // Skip string sLog.outWarden("RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if (Mpq_Result != 0) { sLog.outWarden("RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), 20) != 0) // SHA1 { sLog.outWarden("RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog.outWarden("RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } default: // Should never happen break; } } if (checkFailed > 0) { WardenCheck* check = sWardenCheckMgr->GetWardenDataById(_session->GetClientBuild(), checkFailed); //note it IS NOT NULL here sLog.outWarden("%s failed Warden check %u. Action: %s", _session->GetPlayerName(), checkFailed, Penalty(check).c_str()); LogPositiveToDB(check); } Warden::HandleData(buff); }
void Warden::Update() { if (_initialized) { uint32 ticks = getMSTime(); uint32 diff = ticks - _previousTimestamp; _previousTimestamp = ticks; if (_dataSent) { uint32 maxClientResponseDelay = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_RESPONSE_DELAY); if (maxClientResponseDelay > 0) { // Kick player if client response delays more than set in config if (_clientResponseTimer > maxClientResponseDelay * IN_MILLISECONDS) { sLog->outError("WARDEN: Player %s (guid: %u, account: %u) exceeded Warden module response delay. Action: %s (Latency: %u, IP: %s)", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), Penalty().c_str(), _session->GetLatency(), _session->GetRemoteAddress().c_str()); // If action is set to "none" we reset the client response timer to prevent this condition from triggering repeatedly if (sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_FAIL_ACTION) == 0) { _clientResponseTimer = 0; _clientRespExceedCounter++; // DEBUG CODE } } else _clientResponseTimer += diff; } } else if (_checkTimer > 0) { if (diff >= _checkTimer) { RequestData(); uint32 period = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_CHECK_PERIOD); _checkTimer = irand(period - 5, period + 5) * IN_MILLISECONDS; } else _checkTimer -= diff; } } }