mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-09-23 22:43:43 +00:00
feat: Add cheat detection knowledge (#2034)
* feat: Add cheat detection knowledge tested that getting kicked correctly displays the reasons why and their corresponding values tested that a user with developer permissions is not kicked for said funness tested that logs are correct for those funness values which i could actually trigger * fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
26
dCommon/dEnums/eFunnessTypes.h
Normal file
26
dCommon/dEnums/eFunnessTypes.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef EFUNNESSTYPES_H
|
||||
#define EFUNNESSTYPES_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// Most of these are guesses from the client, some are unused (maybe server side only?) and
|
||||
// some are really hard to pin a definition down for because they are buried in havok stuff
|
||||
enum class eFunnessTypes : int32_t {
|
||||
DebuggerActive = 1,
|
||||
CharacterPosLength = 2,
|
||||
CharacterVelLength = 5,
|
||||
CharacterRunMultiplier = 6,
|
||||
CharacterGravityScale = 7,
|
||||
Unknown_9 = 9,
|
||||
Unknown_10 = 10,
|
||||
RacingBoostTimeTooLong = 12,
|
||||
SomeRacingManipCheat = 13,
|
||||
FdbFailedChecksum = 14,
|
||||
};
|
||||
|
||||
struct CaughtFunness {
|
||||
eFunnessTypes cheatType{};
|
||||
float cheatInfo{};
|
||||
};
|
||||
|
||||
#endif //!EFUNNESSTYPES_H
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "BitStreamUtils.h"
|
||||
#include "MessageType/Chat.h"
|
||||
#include "StringifiedEnum.h"
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
@@ -127,11 +128,16 @@ void User::SetMuteExpire(time_t value) {
|
||||
m_MuteExpire = value;
|
||||
}
|
||||
|
||||
void User::UserOutOfSync() {
|
||||
void User::UserOutOfSync(const CaughtFunness& funness) {
|
||||
m_CaughtFunness.push_back(funness);
|
||||
m_AmountOfTimesOutOfSync++;
|
||||
if (m_AmountOfTimesOutOfSync > m_MaxDesyncAllowed) {
|
||||
//YEET
|
||||
LOG("User %s was out of sync %i times out of %i, disconnecting for suspected speedhacking.", m_Username.c_str(), m_AmountOfTimesOutOfSync, m_MaxDesyncAllowed);
|
||||
LOG("User %s was out of sync %i times out of %i, disconnecting for the following reasons: {", m_Username.c_str(), m_AmountOfTimesOutOfSync, m_MaxDesyncAllowed);
|
||||
for (const auto [cheatType, cheatInfo] : m_CaughtFunness) {
|
||||
LOG(" Reason %s value %f", StringifiedEnum::ToString(cheatType).data(), cheatInfo);
|
||||
}
|
||||
LOG("}");
|
||||
Game::server->Disconnect(this->m_SystemAddress, eServerDisconnectIdentifiers::PLAY_SCHEDULE_TIME_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <chrono>
|
||||
#include "RakNetTypes.h"
|
||||
#include "dCommonVars.h"
|
||||
#include "eFunnessTypes.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
@@ -55,7 +56,7 @@ public:
|
||||
// Added for GameMessageHandler
|
||||
std::unordered_map<uint32_t, BehaviorParams> uiBehaviorHandles;
|
||||
|
||||
void UserOutOfSync();
|
||||
void UserOutOfSync(const CaughtFunness& funness);
|
||||
|
||||
private:
|
||||
uint32_t m_AccountID;
|
||||
@@ -75,6 +76,7 @@ private:
|
||||
const int m_MaxDesyncAllowed = 12;
|
||||
uint64_t m_MuteExpire;
|
||||
std::chrono::steady_clock::time_point m_LastMuteCheck{};
|
||||
std::vector<CaughtFunness> m_CaughtFunness{};
|
||||
};
|
||||
|
||||
#endif // USER_H
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
#include "SlashCommandHandler.h"
|
||||
#include "InventoryComponent.h"
|
||||
#include "Item.h"
|
||||
#include "eFunnessTypes.h"
|
||||
|
||||
namespace Game {
|
||||
Logger* logger = nullptr;
|
||||
@@ -1427,16 +1428,61 @@ void HandlePacket(Packet* packet) {
|
||||
//Could be insane lag, but I'mma just YEET them as it's usually speedhacking.
|
||||
//This is updated to now count the amount of times we've been caught "speedhacking" to kick with a delay
|
||||
//This is hopefully going to fix the random disconnects people face sometimes.
|
||||
if (Game::config->GetValue("disable_anti_speedhack") == "1") {
|
||||
|
||||
CINSTREAM_SKIP_HEADER;
|
||||
CaughtFunness funness;
|
||||
inStream.Read(funness.cheatInfo);
|
||||
inStream.Read(funness.cheatType);
|
||||
const auto [cheatType, cheatInfo] = funness;
|
||||
LOG_DEBUG("Received cheat type %s with info %f", StringifiedEnum::ToString(cheatType).data(), cheatInfo);
|
||||
const auto disabledCheats = Game::config->GetValue("disable_anti_speedhack") == "1";
|
||||
|
||||
User* user = UserManager::Instance()->GetUser(packet->systemAddress);
|
||||
if (!user) {
|
||||
Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::KICK);
|
||||
return;
|
||||
}
|
||||
|
||||
User* user = UserManager::Instance()->GetUser(packet->systemAddress);
|
||||
if (user) {
|
||||
user->UserOutOfSync();
|
||||
} else {
|
||||
Game::server->Disconnect(packet->systemAddress, eServerDisconnectIdentifiers::KICK);
|
||||
const auto* const character = user->GetLastUsedChar();
|
||||
if (character) {
|
||||
const auto dcUser = [](const User& user, const SystemAddress& sysAddr) {
|
||||
if (user.GetMaxGMLevel() < eGameMasterLevel::DEVELOPER) {
|
||||
Game::server->Disconnect(sysAddr, eServerDisconnectIdentifiers::KICK);
|
||||
}
|
||||
};
|
||||
if (cheatType == eFunnessTypes::DebuggerActive) {
|
||||
LOG("Player %s was detected to be using a debugger (funness thread was %f seconds longer than expected deviation).", character->GetName().c_str(), cheatInfo);
|
||||
// Immediately kick unless they are a gm
|
||||
if (!disabledCheats) dcUser(*user, packet->systemAddress);
|
||||
} else if (cheatType == eFunnessTypes::FdbFailedChecksum) {
|
||||
LOG("Player %s has failed the fdb checksum after passing it to sign into this server, highly likely cheating.", character->GetName().c_str());
|
||||
// Immedately kick unless they are a gm
|
||||
if (!disabledCheats) dcUser(*user, packet->systemAddress);
|
||||
} else if (cheatType == eFunnessTypes::RacingBoostTimeTooLong) {
|
||||
if (cheatInfo == 0.0f) LOG("Player %s has enabled a speedboost for far too long (> 3.501 seconds).", character->GetName().c_str());
|
||||
else if (cheatInfo == 1.0f) LOG("Unknown racing boost/speed variable was tampered with.");
|
||||
else if (cheatInfo == 2.0f) LOG("Player vehicle top speed was tampered with.");
|
||||
if (!disabledCheats) dcUser(*user, packet->systemAddress);
|
||||
} else if (cheatType == eFunnessTypes::SomeRacingManipCheat) {
|
||||
if (cheatInfo >= 0.0f && cheatInfo <= 6.0f) LOG("Cheat RNG value A does not match what it should be %f.", cheatInfo);
|
||||
else if (cheatInfo >= 7.0f && cheatInfo <= 10.0f) LOG("Cheat RNG value B does not match what it should be %f.", cheatInfo);
|
||||
} else if (cheatType == eFunnessTypes::Unknown_9) {
|
||||
LOG("Racing cheat 9 detected with value %f.", cheatInfo);
|
||||
} else if (cheatType == eFunnessTypes::Unknown_10) {
|
||||
LOG("Racing cheat 10 detected with value %f.", cheatInfo);
|
||||
} else if (cheatType == eFunnessTypes::CharacterPosLength) {
|
||||
LOG("Detected pos length of %f which is greater than the expected value 1.0f, not normal!", cheatInfo);
|
||||
} else if (cheatType == eFunnessTypes::CharacterVelLength) {
|
||||
LOG("Detected vel length of %f which is greater than the expected value 1.0f, not normal!", cheatInfo);
|
||||
} else if (cheatType == eFunnessTypes::CharacterGravityScale) {
|
||||
LOG("Detected gravity scale difference of %f which is greater than the expected value of 0.0f, not normal!", cheatInfo);
|
||||
} else if (cheatType == eFunnessTypes::CharacterRunMultiplier) {
|
||||
LOG("Detected run multiplier difference of %f which is greater than the expected value 0.0f, not normal!", cheatInfo);
|
||||
}
|
||||
|
||||
if (!disabledCheats && user->GetMaxGMLevel() < eGameMasterLevel::DEVELOPER) user->UserOutOfSync(funness);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user