diff --git a/Samson/dllmain.cpp b/Samson/dllmain.cpp index 210ba4c..402f9fe 100644 --- a/Samson/dllmain.cpp +++ b/Samson/dllmain.cpp @@ -1,14 +1,18 @@ #include #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 logger; @@ -31,6 +35,7 @@ static std::atomic g_Fog_fix_enabled = false; static std::atomic g_TimeDilation_fix_enabled = false; static std::atomic g_GodMode_fix_enabled = false; static std::atomic g_Stealth_fix_enabled = false; +static std::atomic 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 g_TrackedLeftSidedWidgets; std::unordered_set g_TrackedRightSidedWidgets; // Left, right sided and centered widgets std::unordered_set 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 g_CenteredUIWidgets = { // WBP_CrimeScene_Map_C - "WBP_StartMenu_C", - "WBP_GameMenu_C" +std::unordered_set g_CenteredUIWidgets = { + "WBP_StartMenu_C", "WBP_GameMenu_C" }; std::unordered_set 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(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 copyLeftWidgets = g_TrackedLeftSidedWidgets; std::unordered_set 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(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(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