Add cheats. Console activation is done when main menu is reached.

This commit is contained in:
2026-04-11 09:36:12 +02:00
parent 093d797db7
commit 74242c97e6

View File

@@ -1,14 +1,18 @@
#include <unordered_set>
#include "CommonHeaders.h"
#include "CommonUEHeaders.h"
#include "SDK/CJ_classes.hpp"
#include "SDK/BP_VehicleBase_classes.hpp"
#include "SDK/BP_NitroComponent_classes.hpp"
using namespace SDK;
// Constants
const std::string PLUGIN_NAME = "Samson";
const std::string PLUGIN_LOG = PLUGIN_NAME + ".log";
constexpr ULONGLONG DEFAULT_DELAY_BETWEEN_TICK = 100; // Used ProcessEvent
constexpr ULONGLONG DEFAULT_DELAY_BETWEEN_TICK = 100; // Used in ProcessEvent
constexpr ULONGLONG DEFAULT_DELAY_BETWEEN_WTD_TICK = 100; // Used for World time dilation
constexpr ULONGLONG DEFAULT_DELAY_BETWEEN_TD_TICK = 200; // Used for AActor custom time dilation
// Logger
std::shared_ptr<spdlog::logger> logger;
@@ -31,6 +35,7 @@ static std::atomic<bool> g_Fog_fix_enabled = false;
static std::atomic<bool> g_TimeDilation_fix_enabled = false;
static std::atomic<bool> g_GodMode_fix_enabled = false;
static std::atomic<bool> g_Stealth_fix_enabled = false;
static std::atomic<bool> g_Nitro_fix_enabled = false;
static int g_AdditionalFOVValue = 0;
static float g_CameraMultiplier = 1.f;
static float g_WorldTimeDilationValue = 1.f;
@@ -125,7 +130,6 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled, bool init) {
// Setters for Reshade addon call
extern "C" __declspec(dllexport) void SetFixesEnabled(GameFixes fix, bool enabled) { // Set each fix individually
bool bVisual = g_fix_enabled && enabled;
if (fix == GameFixes::DevConsole) { EnableConsole(); }
if (fix == GameFixes::FOV) { g_fov_fix_enabled = enabled; FOVFixEnabled(); }
if (fix == GameFixes::Camera) { g_Camera_fix_enabled = enabled; CameraFixEnabled(); }
if (fix == GameFixes::Cutscenes) { g_Letterboxing_fix_enabled = enabled; }
@@ -136,6 +140,7 @@ extern "C" __declspec(dllexport) void SetFixesEnabled(GameFixes fix, bool enable
if (fix == GameFixes::TimeDilation) { g_TimeDilation_fix_enabled = enabled; EnableCheats(Cheat::TimeDilation); }
if (fix == GameFixes::GodMode) { g_GodMode_fix_enabled = enabled; EnableCheats(Cheat::GodMode); }
if (fix == GameFixes::Stealth) { g_Stealth_fix_enabled = enabled; EnableCheats(Cheat::Stealth); }
if (fix == GameFixes::Boost) { g_Nitro_fix_enabled = enabled; EnableCheats(Cheat::Boost); }
}
extern "C" __declspec(dllexport) void SetValues(GameSetting setting, float value) {
@@ -173,29 +178,12 @@ std::unordered_set<UUserWidget*> g_TrackedLeftSidedWidgets;
std::unordered_set<UUserWidget*> g_TrackedRightSidedWidgets;
// Left, right sided and centered widgets
std::unordered_set<std::string> g_LeftSidedWidgets = {
//"WBP_PlayerHUD_C"
"WBP_MiniMap_C",
"WBP_HUD_HealthStatus_C", // Health pills and more
"WBP_HUD_CurrentLocation_C", // Location bar (vies ...)
//"WBP_HUD_ProgressBar_C", // Health bar etc
//"WBP_HUD_Objective_C", // ??
//"WBP_HUD_VehicleWidget_C", // Compte tour etc...
//"WBP_TailOnFoot_C", // ??
//"WBP_HUD_Mission_C", // ??
//"WBP_HUD_HudIcons_C", // Crosshair
"WBP_HUD_MissionGameplay_C",
//"WBP_MissionGameplay_C", // ??
//"WBP_HUD_Skills_C",
"WBP_HUD_HintItem_C", // Hint voiture à garder
"WBP_LocateItem_C", // Location in the map
"WBP_TimeTrialTimeItem_C",
//"WBP_HUD_Timer_C"
//"WBP_HUD_MissionGameplay_C", // ?
//"WBP_OnboardingInstruction_C" // Instructions à virer
"WBP_MiniMap_C", "WBP_HUD_MissionGameplay_C", "WBP_TimeTrialTimeItem_C",
"WBP_HUD_HealthStatus_C", "WBP_HUD_CurrentLocation_C", "WBP_HUD_HintItem_C",
"WBP_LocateItem_C",
};
std::unordered_set<std::string> g_CenteredUIWidgets = { // WBP_CrimeScene_Map_C
"WBP_StartMenu_C",
"WBP_GameMenu_C"
std::unordered_set<std::string> g_CenteredUIWidgets = {
"WBP_StartMenu_C", "WBP_GameMenu_C"
};
std::unordered_set<std::string> g_RightSidedWidgets = {
"WBP_HUD_VehicleWidget_C", "WBP_HUD_HourToHour_C",
@@ -222,9 +210,6 @@ static void ProcessEvent() {
const std::string className = object->Class->GetName();
const std::string objectFullName = object->GetFullName();
//if (className == "WBP_HUD_ProgressBar_C" && funcName != "Tick") // Debug
// logger->debug("WBP_HUD_ProgressBar_C - {} - function: {}",object->GetFullName(), funcName);
if (object->IsA(UUserWidget::StaticClass())) {
auto* widget = static_cast<UUserWidget*>(object);
@@ -232,20 +217,21 @@ static void ProcessEvent() {
TrackWidgetConstruct(widget);
if (g_LeftSidedWidgets.contains(className)) g_TrackedLeftSidedWidgets.insert(widget);
if (objectFullName.find("ExitProgressBar") != std::string::npos) {
if (objectFullName.find("ExitProgressBar") != std::string::npos)
g_TrackedLeftSidedWidgets.insert(widget);
logger->debug("ExitProgressBar tracked");
}
if (g_RightSidedWidgets.contains(className)) g_TrackedRightSidedWidgets.insert(widget);
if (g_CenteredUIWidgets.contains(className)) g_TrackedCenteredUIWidgets.insert(widget);
if (g_fix_enabled && g_HUD_fix_enabled)
HUDUpdate(false); // Called once
if (className == "WBP_Letterbox_Overlay_C") {
if (className == "WBP_Letterbox_Overlay_C") { // Letterboxing removal
letterBoxWidget = widget;
if (UKismetSystemLibrary::IsValid(widget) && g_fix_enabled && g_Letterboxing_fix_enabled)
if (IsValidUObj(widget) && g_fix_enabled && g_Letterboxing_fix_enabled)
widget->SetVisibility(ESlateVisibility::Collapsed);
}
if (className == "WBP_StartMenu_C") EnableConsole(); // Enable console only when Main menu is reached
}
if (funcName == "Destruct") {
@@ -261,29 +247,25 @@ static void ProcessEvent() {
}
// -- HUD positionning --
static void HUDUpdate(bool writeLog) {
//return;
if (writeLog) logger->info("HUD fix {}", g_fix_enabled && g_HUD_fix_enabled ? "enabled" : "disabled");
float UIoffset = g_fix_enabled && g_HUD_fix_enabled ? g_UIOffsets : 0;
float HUDoffset = g_fix_enabled && g_HUD_fix_enabled ? g_HUDOffsets : 0;
float HUDoffset = g_fix_enabled && g_HUD_fix_enabled ? (float)g_HUDOffsets : 0.f;
// Copy sets to avoid race conditions
std::unordered_set<UUserWidget*> copyLeftWidgets = g_TrackedLeftSidedWidgets;
std::unordered_set<UUserWidget*> copyRightWidgets = g_TrackedRightSidedWidgets;
for (auto* widget : copyLeftWidgets) {
if (!UKismetSystemLibrary::IsValid(widget)) continue; // Ensure the widget is valid
if (!IsValidUObj(widget)) continue; // Ensure the widget is valid
ApplyTransformOffset(widget, HUDoffset);
}
for (auto* widget : copyRightWidgets) {
if (!UKismetSystemLibrary::IsValid(widget)) continue; // Ensure the widget is valid
if (!IsValidUObj(widget)) continue; // Ensure the widget is valid
ApplyTransformOffset(widget, -HUDoffset);
}
}
static void FOVFixEnabled() {
//if (g_fov_fix_enabled) // Here to track Widgets
// DumpUIAnalysis(logger);
//else ClearWidgetTracking();
if (!CameraComponentaddress) return;
if (!FOVHook) { // Hook only once
FOVHook = safetyhook::create_mid(CameraComponentaddress + 0xa,
@@ -315,18 +297,18 @@ static void CameraFixEnabled() {
}
// -- Cheats --
static ULONGLONG lastScanWTDTick = 0; // Last time tick was called
static void EnableCheats(Cheat cheat) {
if (WorldTimedilationaddress && !WorldTimeDilationHook) {
WorldTimeDilationHook = safetyhook::create_mid(WorldTimedilationaddress + 0x19,
[](SafetyHookContext& ctx) { // From AWorldSettings retrieved from world->K2_GetWorldSettings()
ctx.xmm0.f32[0] *= g_TimeDilation_fix_enabled ? g_WorldTimeDilationValue : 1.f;
static ULONGLONG lastScanWTDTick = 0; // Last time tick was called
ULONGLONG now = GetTickCount64();
if (now - lastScanWTDTick >= DEFAULT_DELAY_BETWEEN_WTD_TICK) { // Delay between each tick to avoid ProcessEvent stuttering
lastScanWTDTick = now;
if (UKismetSystemLibrary::IsValid(letterBoxWidget))
if (IsValidUObj(letterBoxWidget))
letterBoxWidget->SetVisibility(g_fix_enabled && g_Letterboxing_fix_enabled ?
ESlateVisibility::Collapsed : ESlateVisibility::Visible);
}
@@ -349,12 +331,54 @@ static void EnableCheats(Cheat cheat) {
UObject* object = (UObject*)ctx.rbx;
if (!object || !object->Class) return;
if (object->IsA(ACJCharacter::StaticClass())) {
ACJCharacter* character = static_cast<ACJCharacter*>(object);
if (!IsValidUObj(character)) return;
if (character->IsPlayer()) {
static ULONGLONG lastScanTDTick = 0; // Last time tick was called
ULONGLONG now = GetTickCount64();
if (now - lastScanTDTick >= DEFAULT_DELAY_BETWEEN_TD_TICK) { // Delay between each tick to avoid spamming
lastScanTDTick = now;
if (g_GodMode_fix_enabled && IsValidUObj(character->HealthComponent)) // God mode
character->HealthComponent->FullyRestore();
g_PlayerHealth = character->GetHealth(); // Retrieves player health
if (auto vehicle = character->GetVehicle()) {
if (g_GodMode_fix_enabled && IsValidUObj(vehicle) && IsValidUObj(vehicle->DestructionComponent)) // Indestructible vehicle
vehicle->DestructionComponent->RestoreVehicle();
if (g_Nitro_fix_enabled && vehicle->IsA(ABP_VehicleBase_C::StaticClass())) {
if (auto vehicleBase = static_cast<ABP_VehicleBase_C*>(vehicle)) {
auto nitro = vehicleBase->BP_NitroComponent;
// IsValidUObj alias SDK::UKismetSystemLibrary::IsValid
if (IsValidUObj(nitro)) { // Infinite nitro
nitro->ReplenishNitrous();
nitro->UpdateNitrousState();
}
}
}
}
}
if (g_Stealth_fix_enabled && IsValidUObj(character->StimEventSourceComponent) &&
IsValidUObj(character->SpatialAwarenessComponent)) { // Stealth
character->StimEventSourceComponent->ActiveStimEvents = {};
character->StimEventSourceComponent->Deactivate();
character->SpatialAwarenessComponent->Deactivate();
}
}
else if (!character->bIsPedestrian) // Apply only time dilation to enemies
character->CustomTimeDilation = g_TimeDilation_fix_enabled ? g_AITimeDilationValue : 1.f;
}
});
}
if (cheat == Cheat::TimeDilation) logger->info("Time dilation cheat {}", g_TimeDilation_fix_enabled ? "enabled" : "disabled");
if (cheat == Cheat::GodMode) logger->info("God mode cheat {}", g_GodMode_fix_enabled ? "enabled" : "disabled");
if (cheat == Cheat::Stealth) logger->info("Stealth cheat {}", g_Stealth_fix_enabled ? "enabled" : "disabled");
if (cheat == Cheat::Boost) logger->info("Nitro cheat {}", g_Nitro_fix_enabled ? "enabled" : "disabled");
}
// UE Console creation