diff --git a/.gitmodules b/.gitmodules index 47b2a88..ffb57fa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "src/vendor/imgui"] path = src/vendor/imgui url = https://github.com/Taiga74164/imgui +[submodule "src/vendor/json"] + path = src/vendor/json + url = https://github.com/nlohmann/json diff --git a/diff.diff b/diff.diff new file mode 100644 index 0000000..df64626 --- /dev/null +++ b/diff.diff @@ -0,0 +1,456 @@ +diff --git a/.gitmodules b/.gitmodules +index 47b2a88..ffb57fa 100644 +--- a/.gitmodules ++++ b/.gitmodules +@@ -10,3 +10,6 @@ + [submodule "src/vendor/imgui"] + path = src/vendor/imgui + url = https://github.com/Taiga74164/imgui ++[submodule "src/vendor/json"] ++ path = src/vendor/json ++ url = https://github.com/nlohmann/json +diff --git a/src/SoloLevelling.vcxproj b/src/SoloLevelling.vcxproj +index 172a403..ef99dde 100644 +--- a/src/SoloLevelling.vcxproj ++++ b/src/SoloLevelling.vcxproj +@@ -49,7 +49,7 @@ + pch.h + true + stdcpp20 +- $(ProjectDir)game\;$(ProjectDir)vendor\CommandMenu\include\;$(ProjectDir)vendor\imgui\;$(ProjectDir)vendor\detours\;$(ProjectDir)vendor\magic_enum\include\magic_enum ++ $(ProjectDir)game\;$(ProjectDir)vendor\CommandMenu\include\;$(ProjectDir)vendor\imgui\;$(ProjectDir)vendor\detours\;$(ProjectDir)vendor\magic_enum\include\magic_enum;$(ProjectDir)vendor\json\single_include\nlohmann + + + Windows +@@ -99,6 +99,8 @@ if %errorlevel% == 0 ( + + + ++ ++ + + + +@@ -174,7 +176,6 @@ if %errorlevel% == 0 ( + + + +- + + + +diff --git a/src/game/ConfigEntry.hpp b/src/game/ConfigEntry.hpp +index 7b9637e..6e2a56e 100644 +--- a/src/game/ConfigEntry.hpp ++++ b/src/game/ConfigEntry.hpp +@@ -1 +1,37 @@ +-#pragma once +\ No newline at end of file ++#pragma once ++ ++#include "ConfigManager.hpp" ++#include ++ ++using json = nlohmann::json; ++ ++#define CONFIG_ENTRY(Type, Name, DefaultValue) ConfigEntry Name = { #Name, DefaultValue } ++ ++template ++class ConfigEntry ++{ ++public: ++ ConfigEntry(const std::string& name, const T& defaultValue) ++ : name_(name), value_(defaultValue) ++ { ++ value_ = ConfigManager::GetInstance().Get(name, defaultValue); ++ } ++ ++ T& value() { return value_; } ++ ++ void SetValue(const T& value) ++ { ++ value_ = value; ++ ConfigManager::GetInstance().Set(name_, value); ++ } ++ ++ ConfigEntry& operator=(const T& newValue) ++ { ++ SetValue(newValue); ++ return *this; ++ } ++ ++private: ++ std::string name_; ++ T value_; ++}; +\ No newline at end of file +diff --git a/src/game/ConfigManager.hpp b/src/game/ConfigManager.hpp +index 17c91df..bd22e55 100644 +--- a/src/game/ConfigManager.hpp ++++ b/src/game/ConfigManager.hpp +@@ -1,6 +1,66 @@ + #pragma once + +-class ConfigManager { ++#include ++#include ++#include ++#include ++ ++#include "Singleton.h" ++ ++using json = nlohmann::json; ++ ++class ConfigManager : public Singleton ++{ + public: ++ ConfigManager() ++ { ++ } + ++ void InitializeConfig(const std::string& path) ++ { ++ configPath_ = path; ++ LoadConfig(); ++ if (config_.empty()) ++ SaveConfig(); ++ } ++ ++ template ++ T Get(const std::string& name, const T& defaultValue) ++ { ++ LoadConfig(); ++ return config_.value(name, defaultValue); ++ } ++ ++ template ++ void Set(const std::string& name, const T& value) ++ { ++ // json newConfig; ++ // newConfig[name] = value; ++ // SaveConfig(newConfig); ++ config_[name] = value; ++ SaveConfig(); ++ } ++ ++ ++private: ++ json config_; ++ std::string configPath_; ++ ++ void LoadConfig() ++ { ++ std::ifstream file(configPath_); ++ if (file) ++ file >> config_; ++ } ++ ++ void SaveConfig() ++ { ++ // for (auto& it : newConfig.items()) ++ // config_[it.key()] = it.value(); ++ // ++ // std::ofstream o(configPath_); ++ // o << config_.dump(4); ++ std::ofstream file(configPath_); ++ file << config_.dump(4); ++ } + }; +diff --git a/src/game/Core/Core.cpp b/src/game/Core/Core.cpp +index 381e3be..e797a71 100644 +--- a/src/game/Core/Core.cpp ++++ b/src/game/Core/Core.cpp +@@ -3,23 +3,30 @@ + #include + #include + #include ++ ++#include "ConfigManager.hpp" + #include "Memory.h" + + #include "appdata/il2cpp-init.h" + #include "cheat/cheat.h" + #include "Render/Renderer.h" + +-void Core::Start() ++void Core::Start(HMODULE hModule) + { + while (!GetModuleHandleA("GameAssembly.dll") && !FindWindowA("UnityWndClass", nullptr)) + { + LOG("[SoloLevelling] game not found, waiting 3 seconds..."); + Sleep(3000); + } +- ++ ++ Utils::SetCurrentPath(Utils::GetModulePath(hModule)); ++ ConfigManager::GetInstance().InitializeConfig((Utils::GetCurrentPath() / "config.json").string()); ++ + Init(Renderer::DXVersion::D3D11); + init_il2cpp(); + init_cheat(); ++ ++ LOG("Config path is at %s", (Utils::GetCurrentPath() / "cfg.json").string().c_str()); + } + + #pragma region Initialization and DLL proxy stuff +@@ -33,7 +40,7 @@ void Core::Initialize(HINSTANCE hModule) + LOG("[SoloLevelling] Initializing..."); + // Get execution path + std::vector pathBuf; +- DWORD copied = 0; ++ DWORD copied; + do + { + pathBuf.resize(pathBuf.size() + MAX_PATH); +diff --git a/src/game/Core/Core.h b/src/game/Core/Core.h +index 40bec43..0f7189c 100644 +--- a/src/game/Core/Core.h ++++ b/src/game/Core/Core.h +@@ -6,7 +6,7 @@ class Core + { + public: + static void Initialize(HINSTANCE hModule); +- static void Start(); ++ static void Start(HMODULE hModule); + + private: + static HMODULE LoadOriginalProxy(const std::filesystem::path& proxyFilepath, const std::wstring& proxyFilepathNoExt); +diff --git a/src/game/Render/Gui/gui.cpp b/src/game/Render/Gui/gui.cpp +index b234136..f8bea74 100644 +--- a/src/game/Render/Gui/gui.cpp ++++ b/src/game/Render/Gui/gui.cpp +@@ -5,6 +5,8 @@ + + void Gui::Render() + { ++ auto& vars = Vars::GetInstance(); ++ + ImGui::Begin("##Taiga74164", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); + { + ImGui::BeginGroup(); +@@ -49,6 +51,8 @@ void Gui::Render() + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + ImGui::BeginGroup(); + ++ // ImGui::CheckboxFill("Test", &vars.b_Test.value()); ++ + ImGui::CheckboxFill("No Cooldown", &vars.b_NoCooldown); + + ImGui::CheckboxFill("God Mode", &vars.b_GodMode); +diff --git a/src/game/Utils.cpp b/src/game/Utils.cpp +index 2e6b62a..517bd2b 100644 +--- a/src/game/Utils.cpp ++++ b/src/game/Utils.cpp +@@ -1,5 +1,4 @@ + #include "Utils.h" +-#include + #include + #include + #include +@@ -179,4 +178,23 @@ namespace Utils + { + ShellExecuteA(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL); + } ++ ++ std::string GetModulePath(HMODULE hModule /*= nullptr*/) ++ { ++ char pathOut[MAX_PATH] = {}; ++ GetModuleFileNameA(hModule, pathOut, MAX_PATH); ++ ++ return std::filesystem::path(pathOut).parent_path().string(); ++ } ++ ++ static std::filesystem::path _currentPath; ++ void SetCurrentPath(const std::filesystem::path& current_path) ++ { ++ _currentPath = current_path; ++ } ++ ++ std::filesystem::path GetCurrentPath() ++ { ++ return _currentPath; ++ } + } +diff --git a/src/game/Utils.h b/src/game/Utils.h +index e97792b..22d1c14 100644 +--- a/src/game/Utils.h ++++ b/src/game/Utils.h +@@ -1,4 +1,6 @@ + #pragma once ++ ++#include + #include + #include + +@@ -42,4 +44,9 @@ namespace Utils + { + memcpy(hexPtr, &value, sizeof(T)); + } ++ ++ std::string GetModulePath(HMODULE hModule = nullptr); ++ ++ void SetCurrentPath(const std::filesystem::path& curren_path); ++ std::filesystem::path GetCurrentPath(); + } +\ No newline at end of file +diff --git a/src/game/cheat/features/DamageHack.cpp b/src/game/cheat/features/DamageHack.cpp +index 31a474e..a61e8da 100644 +--- a/src/game/cheat/features/DamageHack.cpp ++++ b/src/game/cheat/features/DamageHack.cpp +@@ -14,6 +14,8 @@ namespace Cheat::Features + + void DamageHack::PIPHNBOBFEF_KBCIIEFLPGB_Hook(app::PIPHNBOBFEF* __this, app::ESpecialState__Enum specialState, int64_t someInt1, int64_t someInt2, int64_t someInt3, app::String* buffName, MethodInfo* method) + { ++ auto& vars = Vars::GetInstance(); ++ + if (__this->fields.IGFILCLEFHH->fields.EJBODHBGPMG != nullptr) + { + auto entity = __this->fields.IGFILCLEFHH->fields.EJBODHBGPMG; +@@ -56,6 +58,8 @@ namespace Cheat::Features + + int32_t DamageHack::GHINOEFFMPN_EKHGIHBHEPL_Hook(app::SkillIdentity* skillIdentity, void* FKJDKGJBGOD, app::TargetHitData* targetHitData, MethodInfo* method) + { ++ auto& vars = Vars::GetInstance(); ++ + if (skillIdentity->fields.entity->fields.FHNGHHPLPGD == app::eCharGroup__Enum::PLAYER) + { + //auto skillRange = skillIdentity->fields.SkillRange; +diff --git a/src/game/cheat/features/DumbEnemies.cpp b/src/game/cheat/features/DumbEnemies.cpp +index 0c9e23a..933219b 100644 +--- a/src/game/cheat/features/DumbEnemies.cpp ++++ b/src/game/cheat/features/DumbEnemies.cpp +@@ -12,6 +12,8 @@ namespace Cheat::Features + + void DumbEnemies::EvadeProxy_Init_Hook(app::EvadeProxy* __this, app::ENNEJEPMJLJ* character, app::EvadePenetration* DHPMEMDBDMC, MethodInfo* method) + { ++ auto& vars = Vars::GetInstance(); ++ + // Dumb Enemies + if (character->fields.FHNGHHPLPGD == app::eCharGroup__Enum::ENEMY || + character->fields.AJEHLIOMMJN == app::ECharacterType__Enum::Monster) +diff --git a/src/game/cheat/features/FPSUnlock.cpp b/src/game/cheat/features/FPSUnlock.cpp +index 8b1c669..a348cf2 100644 +--- a/src/game/cheat/features/FPSUnlock.cpp ++++ b/src/game/cheat/features/FPSUnlock.cpp +@@ -13,6 +13,8 @@ namespace Cheat::Features + + void FPSUnlock::OnGameUpdate() + { ++ auto& vars = Vars::GetInstance(); ++ + if (m_LastEnableStatus && !vars.b_FPSUnlock) + { + app::Application_set_targetFrameRate(m_OriginFPS, nullptr); +diff --git a/src/game/cheat/features/FPSUnlock.h b/src/game/cheat/features/FPSUnlock.h +index b97530f..0348538 100644 +--- a/src/game/cheat/features/FPSUnlock.h ++++ b/src/game/cheat/features/FPSUnlock.h +@@ -13,6 +13,6 @@ namespace Cheat::Features + + private: + bool m_LastEnableStatus = false; +- int m_OriginFPS = 30; ++ int m_OriginFPS = 60; + }; + } +diff --git a/src/game/cheat/features/FovChanger.cpp b/src/game/cheat/features/FovChanger.cpp +index a253dee..bc5be91 100644 +--- a/src/game/cheat/features/FovChanger.cpp ++++ b/src/game/cheat/features/FovChanger.cpp +@@ -13,6 +13,8 @@ namespace Cheat::Features + + void FovChanger::Camera_set_fieldOfView_Hook(void* __this, float value, MethodInfo* method) + { ++ auto& vars = Vars::GetInstance(); ++ + if (vars.b_FovChanger) + value = vars.f_Fov; + CALL_ORIGIN(Camera_set_fieldOfView_Hook, __this, value, method); +diff --git a/src/game/cheat/features/MissionTime.cpp b/src/game/cheat/features/MissionTime.cpp +index e2c411c..466bccb 100644 +--- a/src/game/cheat/features/MissionTime.cpp ++++ b/src/game/cheat/features/MissionTime.cpp +@@ -12,6 +12,8 @@ namespace Cheat::Features + + void MissionTime::StageReadyPage_EnterUI_Hook(app::StageReadyPage* __this, MethodInfo* method) + { ++ auto& vars = Vars::GetInstance(); ++ + if (vars.b_MissionTime) + __this->fields.FHMGDAMDBHG->fields.m_Timelimit = vars.i_MissionTimeMs; + +diff --git a/src/game/cheat/features/NoCooldown.cpp b/src/game/cheat/features/NoCooldown.cpp +index a654907..bda877f 100644 +--- a/src/game/cheat/features/NoCooldown.cpp ++++ b/src/game/cheat/features/NoCooldown.cpp +@@ -10,6 +10,8 @@ namespace Cheat::Features + + void* NoCooldown::KAAIFMKPKAG_IOFMGMJCCFO_Hook(app::KAAIFMKPKAG* __this, bool DEJNILEHENL, MethodInfo* method) + { ++ auto& vars = Vars::GetInstance(); ++ + if (vars.b_NoCooldown) + { + __this->fields.HPHOOEPCBOJ = 0; +diff --git a/src/game/cheat/features/TimeScale.cpp b/src/game/cheat/features/TimeScale.cpp +index c374934..a6656d9 100644 +--- a/src/game/cheat/features/TimeScale.cpp ++++ b/src/game/cheat/features/TimeScale.cpp +@@ -13,6 +13,8 @@ namespace Cheat::Features + + void TimeScale::OnGameUpdate() + { ++ auto& vars = Vars::GetInstance(); ++ + if (vars.b_TimeScale) + { + app::Time_set_timeScale(vars.f_TimeScaleSpeed, nullptr); +diff --git a/src/game/cheat/features/TimeScale.h b/src/game/cheat/features/TimeScale.h +index 880aefe..57b9d2b 100644 +--- a/src/game/cheat/features/TimeScale.h ++++ b/src/game/cheat/features/TimeScale.h +@@ -10,7 +10,7 @@ namespace Cheat::Features + TimeScale(); + + void OnGameUpdate(); +- ++ + private: + bool m_DidSpeed; + }; +diff --git a/src/game/cheat/vars.h b/src/game/cheat/vars.h +index b330a49..3c3a965 100644 +--- a/src/game/cheat/vars.h ++++ b/src/game/cheat/vars.h +@@ -1,7 +1,18 @@ + #pragma once + +-struct Vars ++#include "ConfigEntry.hpp" ++ ++class Vars final // : public Singleton + { ++public: ++ static ConfigManager& GetInstance() { ++ static ConfigManager instance; ++ return instance; ++ } ++ ++ CONFIG_ENTRY(bool, b_Test, true); ++ CONFIG_ENTRY(bool, b_Test2, true); ++ CONFIG_ENTRY(bool, b_Test3, true); + bool b_PlayerSpeed = true; + bool b_NoCooldown = true; + bool b_GodMode = true; +@@ -18,6 +29,6 @@ struct Vars + float f_Fov = 60.0f; + + bool b_SkipIntroMovie = true; +-}; +- +-extern Vars vars; +\ No newline at end of file ++private: ++ Vars() = default; ++}; +\ No newline at end of file diff --git a/src/SoloLevelling.vcxproj b/src/SoloLevelling.vcxproj index 172a403..ef99dde 100644 --- a/src/SoloLevelling.vcxproj +++ b/src/SoloLevelling.vcxproj @@ -49,7 +49,7 @@ pch.h true stdcpp20 - $(ProjectDir)game\;$(ProjectDir)vendor\CommandMenu\include\;$(ProjectDir)vendor\imgui\;$(ProjectDir)vendor\detours\;$(ProjectDir)vendor\magic_enum\include\magic_enum + $(ProjectDir)game\;$(ProjectDir)vendor\CommandMenu\include\;$(ProjectDir)vendor\imgui\;$(ProjectDir)vendor\detours\;$(ProjectDir)vendor\magic_enum\include\magic_enum;$(ProjectDir)vendor\json\single_include\nlohmann Windows @@ -99,6 +99,8 @@ if %errorlevel% == 0 ( + + @@ -174,7 +176,6 @@ if %errorlevel% == 0 ( - diff --git a/src/game/ConfigEntry.hpp b/src/game/ConfigEntry.hpp new file mode 100644 index 0000000..5f511ae --- /dev/null +++ b/src/game/ConfigEntry.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "ConfigManager.hpp" +#include + +using json = nlohmann::json; + +#define CONFIG_ENTRY(Type, Name, DefaultValue) ConfigEntry Name = { #Name, DefaultValue } + +template +class ConfigEntry +{ +public: + ConfigEntry(const std::string& name, const T& defaultValue) + : name_(name), value_(defaultValue) + { + value_ = ConfigManager::GetInstance().Get(name, defaultValue, true); + } + + T& value() + { + // Goofy ahhhhh. + ConfigManager::GetInstance().Set(name_, value_); + return value_; + } + + void SetValue(const T& value) + { + if (value_ == value) return; + + value_ = value; + ConfigManager::GetInstance().Set(name_, value); + } + + ConfigEntry& operator=(const T& newValue) + { + SetValue(newValue); + return *this; + } + +private: + std::string name_; + T value_; +}; \ No newline at end of file diff --git a/src/game/ConfigManager.hpp b/src/game/ConfigManager.hpp new file mode 100644 index 0000000..310661d --- /dev/null +++ b/src/game/ConfigManager.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include +#include +#include +#include + +#include "Singleton.h" + +using json = nlohmann::json; + +class ConfigManager : public Singleton +{ +public: + ConfigManager() + { + } + + void InitializeConfig(const std::string& path) + { + configPath_ = path; + LoadConfig(); + if (config_.empty()) + SaveConfig(); + } + + template + T Get(const std::string& name, const T& defaultValue, bool affectConfig = false) + { + LoadConfig(); + if (!config_.contains(name) && affectConfig) + { + config_[name] = defaultValue; + SaveConfig(); + } + return config_.value(name, defaultValue); + } + + template + void Set(const std::string& name, const T& value) + { + // json newConfig; + // newConfig[name] = value; + // SaveConfig(newConfig); + config_[name] = value; + SaveConfig(); + } + + +private: + json config_; + std::string configPath_; + + void LoadConfig() + { + std::ifstream file(configPath_); + if (file.peek() == std::ifstream::traits_type::eof()) + { + SaveConfig(); + return; + } + else + { + file >> config_; + } + + file.close(); + } + + void SaveConfig() + { + // for (auto& it : newConfig.items()) + // config_[it.key()] = it.value(); + // + // std::ofstream o(configPath_); + // o << config_.dump(4); + std::ofstream file(configPath_); + file << config_.dump(4); + file.close(); + } +}; diff --git a/src/game/Core/Core.cpp b/src/game/Core/Core.cpp index 381e3be..e797a71 100644 --- a/src/game/Core/Core.cpp +++ b/src/game/Core/Core.cpp @@ -3,23 +3,30 @@ #include #include #include + +#include "ConfigManager.hpp" #include "Memory.h" #include "appdata/il2cpp-init.h" #include "cheat/cheat.h" #include "Render/Renderer.h" -void Core::Start() +void Core::Start(HMODULE hModule) { while (!GetModuleHandleA("GameAssembly.dll") && !FindWindowA("UnityWndClass", nullptr)) { LOG("[SoloLevelling] game not found, waiting 3 seconds..."); Sleep(3000); } - + + Utils::SetCurrentPath(Utils::GetModulePath(hModule)); + ConfigManager::GetInstance().InitializeConfig((Utils::GetCurrentPath() / "config.json").string()); + Init(Renderer::DXVersion::D3D11); init_il2cpp(); init_cheat(); + + LOG("Config path is at %s", (Utils::GetCurrentPath() / "cfg.json").string().c_str()); } #pragma region Initialization and DLL proxy stuff @@ -33,7 +40,7 @@ void Core::Initialize(HINSTANCE hModule) LOG("[SoloLevelling] Initializing..."); // Get execution path std::vector pathBuf; - DWORD copied = 0; + DWORD copied; do { pathBuf.resize(pathBuf.size() + MAX_PATH); diff --git a/src/game/Core/Core.h b/src/game/Core/Core.h index 40bec43..0f7189c 100644 --- a/src/game/Core/Core.h +++ b/src/game/Core/Core.h @@ -6,7 +6,7 @@ class Core { public: static void Initialize(HINSTANCE hModule); - static void Start(); + static void Start(HMODULE hModule); private: static HMODULE LoadOriginalProxy(const std::filesystem::path& proxyFilepath, const std::wstring& proxyFilepathNoExt); diff --git a/src/game/Render/Gui/gui.cpp b/src/game/Render/Gui/gui.cpp index b234136..93199f7 100644 --- a/src/game/Render/Gui/gui.cpp +++ b/src/game/Render/Gui/gui.cpp @@ -5,6 +5,8 @@ void Gui::Render() { + auto& vars = Vars::GetInstance(); + ImGui::Begin("##Taiga74164", nullptr, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar); { ImGui::BeginGroup(); @@ -49,24 +51,24 @@ void Gui::Render() ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); ImGui::BeginGroup(); - ImGui::CheckboxFill("No Cooldown", &vars.b_NoCooldown); + ImGui::CheckboxFill("No Cooldown", &vars.NoCooldown.value()); - ImGui::CheckboxFill("God Mode", &vars.b_GodMode); + ImGui::CheckboxFill("God Mode", &vars.GodMode.value()); - ImGui::CheckboxFill("Damage Hack", &vars.b_DamageHack); HELPMAKER("Only works for certain weapons"); - if (vars.b_DamageHack) - ImGui::SliderFloat("Value", &vars.f_DamageHackValue, 200.0f, 5000.0f, "%1.0f"); + ImGui::CheckboxFill("Damage Hack", &vars.DamageHack.value()); HELPMAKER("Only works for certain weapons"); + if (vars.DamageHack.value()) + ImGui::SliderFloat("Value", &vars.DamageHackValue.value(), 200.0f, 5000.0f, "%1.0f"); - ImGui::CheckboxFill("Dumb Enemies", &vars.b_DumbEnemies); HELPMAKER("This will prevent enemies from attacking or moving towards you"); + ImGui::CheckboxFill("Dumb Enemies", &vars.DumbEnemies.value()); HELPMAKER("This will prevent enemies from attacking or moving towards you"); - ImGui::CheckboxFill("Mission Time", &vars.b_MissionTime); HELPMAKER("Make sure this is enabled before starting a mission"); - if (vars.b_MissionTime) - ImGui::SliderInt("Time (ms)", &vars.i_MissionTimeMs, 180000, 3600000, "%d"); + ImGui::CheckboxFill("Mission Time", &vars.MissionTime.value()); HELPMAKER("Make sure this is enabled before starting a mission"); + if (vars.MissionTime.value()) + ImGui::SliderInt("Time (ms)", &vars.MissionTimeMs.value(), 180000, 3600000, "%d"); + + ImGui::CheckboxFill("Time Scale", &vars.TimeScale.value()); + if (vars.TimeScale.value()) + ImGui::SliderFloat("Speed", &vars.TimeScaleSpeed.value(), 1.0f, 10.0f, "%.1f"); - ImGui::CheckboxFill("Time Scale", &vars.b_TimeScale); - if (vars.b_TimeScale) - ImGui::SliderFloat("Speed", &vars.f_TimeScaleSpeed, 1.0f, 10.0f, "%.1f"); - ImGui::EndGroup(); ImGui::PopStyleVar(); break; @@ -74,14 +76,15 @@ void Gui::Render() ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); ImGui::BeginGroup(); - ImGui::CheckboxFill("FPS Unlock", &vars.b_FPSUnlock); - if (vars.b_FPSUnlock) - ImGui::SliderInt("FPS", &vars.i_FPS, 5, 360, "%d"); - ImGui::CheckboxFill("Fov Changer", &vars.b_FovChanger); - if (vars.b_FovChanger) - ImGui::SliderFloat("Fov", &vars.f_Fov, 1.0f, 360.0f, "%.1f"); + ImGui::CheckboxFill("FPS Unlock", &vars.FPSUnlock.value()); + if (vars.FPSUnlock.value()) + ImGui::SliderInt("FPS", &vars.FPSValue.value(), 5, 360, "%d"); + + ImGui::CheckboxFill("Fov Changer", &vars.FovChanger.value()); + if (vars.FovChanger.value()) + ImGui::SliderFloat("Fov", &vars.Fov.value(), 1.0f, 360.0f, "%.1f"); - ImGui::CheckboxFill("Skip Intro Movie", &vars.b_SkipIntroMovie); HELPMAKER("This will skip the intro movie when you start the game"); + ImGui::CheckboxFill("Skip Intro Movie", &vars.SkipIntroMovie.value()); HELPMAKER("This will skip the intro movie when you start the game"); ImGui::EndGroup(); ImGui::PopStyleVar(); diff --git a/src/game/Utils.cpp b/src/game/Utils.cpp index 2e6b62a..517bd2b 100644 --- a/src/game/Utils.cpp +++ b/src/game/Utils.cpp @@ -1,5 +1,4 @@ #include "Utils.h" -#include #include #include #include @@ -179,4 +178,23 @@ namespace Utils { ShellExecuteA(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL); } + + std::string GetModulePath(HMODULE hModule /*= nullptr*/) + { + char pathOut[MAX_PATH] = {}; + GetModuleFileNameA(hModule, pathOut, MAX_PATH); + + return std::filesystem::path(pathOut).parent_path().string(); + } + + static std::filesystem::path _currentPath; + void SetCurrentPath(const std::filesystem::path& current_path) + { + _currentPath = current_path; + } + + std::filesystem::path GetCurrentPath() + { + return _currentPath; + } } diff --git a/src/game/Utils.h b/src/game/Utils.h index e97792b..22d1c14 100644 --- a/src/game/Utils.h +++ b/src/game/Utils.h @@ -1,4 +1,6 @@ #pragma once + +#include #include #include @@ -42,4 +44,9 @@ namespace Utils { memcpy(hexPtr, &value, sizeof(T)); } + + std::string GetModulePath(HMODULE hModule = nullptr); + + void SetCurrentPath(const std::filesystem::path& curren_path); + std::filesystem::path GetCurrentPath(); } \ No newline at end of file diff --git a/src/game/cheat/features/DamageHack.cpp b/src/game/cheat/features/DamageHack.cpp index 31a474e..a3d4570 100644 --- a/src/game/cheat/features/DamageHack.cpp +++ b/src/game/cheat/features/DamageHack.cpp @@ -14,6 +14,8 @@ namespace Cheat::Features void DamageHack::PIPHNBOBFEF_KBCIIEFLPGB_Hook(app::PIPHNBOBFEF* __this, app::ESpecialState__Enum specialState, int64_t someInt1, int64_t someInt2, int64_t someInt3, app::String* buffName, MethodInfo* method) { + auto& vars = Vars::GetInstance(); + if (__this->fields.IGFILCLEFHH->fields.EJBODHBGPMG != nullptr) { auto entity = __this->fields.IGFILCLEFHH->fields.EJBODHBGPMG; @@ -28,7 +30,7 @@ namespace Cheat::Features if (entity->fields.FHNGHHPLPGD == app::eCharGroup__Enum::PLAYER) { // God Mode - if (vars.b_GodMode) + if (vars.GodMode.value()) { if (specialState == app::ESpecialState__Enum::None || specialState == app::ESpecialState__Enum::DotDamage) @@ -43,7 +45,7 @@ namespace Cheat::Features if (entity->fields.FHNGHHPLPGD == app::eCharGroup__Enum::ENEMY) { - if (vars.b_DamageHack) + if (vars.DamageHack.value()) CALL_ORIGIN(PIPHNBOBFEF_KBCIIEFLPGB_Hook, __this, app::ESpecialState__Enum::CriticalRate, 2i64, 99999999i64, 0i64, buffName, method); // CALL_ORIGIN(PIPHNBOBFEF_KBCIIEFLPGB_Hook, __this, app::ESpecialState__Enum::Crash, 2i64, 99999999i64, 0i64, buffName, method); // CALL_ORIGIN(PIPHNBOBFEF_KBCIIEFLPGB_Hook, __this, app::ESpecialState__Enum::Stun, 2i64, 1000i64, 0i64, buffName, method); @@ -56,6 +58,8 @@ namespace Cheat::Features int32_t DamageHack::GHINOEFFMPN_EKHGIHBHEPL_Hook(app::SkillIdentity* skillIdentity, void* FKJDKGJBGOD, app::TargetHitData* targetHitData, MethodInfo* method) { + auto& vars = Vars::GetInstance(); + if (skillIdentity->fields.entity->fields.FHNGHHPLPGD == app::eCharGroup__Enum::PLAYER) { //auto skillRange = skillIdentity->fields.SkillRange; @@ -73,7 +77,7 @@ namespace Cheat::Features //LOG("damageRatio %f", damageRatio); //LOG("damageRatioTotalValue %f", damageRatioTotalValue); - if (vars.b_DamageHack) + if (vars.DamageHack.value()) { skillIdentity->fields.SkillRange = 500.0f; skillIdentity->fields.SkillMinRange = 500.0f; @@ -102,7 +106,7 @@ namespace Cheat::Features //LOG("damageRatio %f", damageRatio); //LOG("damageRatioTotalValue %f", damageRatioTotalValue); - if (vars.b_GodMode) + if (vars.GodMode.value()) { skillIdentity->fields.SkillRange = -1.0f; skillIdentity->fields.SkillMinRange = -1.0f; diff --git a/src/game/cheat/features/DumbEnemies.cpp b/src/game/cheat/features/DumbEnemies.cpp index 0c9e23a..9249254 100644 --- a/src/game/cheat/features/DumbEnemies.cpp +++ b/src/game/cheat/features/DumbEnemies.cpp @@ -12,11 +12,13 @@ namespace Cheat::Features void DumbEnemies::EvadeProxy_Init_Hook(app::EvadeProxy* __this, app::ENNEJEPMJLJ* character, app::EvadePenetration* DHPMEMDBDMC, MethodInfo* method) { + auto& vars = Vars::GetInstance(); + // Dumb Enemies if (character->fields.FHNGHHPLPGD == app::eCharGroup__Enum::ENEMY || character->fields.AJEHLIOMMJN == app::ECharacterType__Enum::Monster) { - if (vars.b_DumbEnemies) + if (vars.DumbEnemies.value()) { character->fields.KFIFBINFDPB->fields.m_pCharBattleInfo->fields.m_SidewalkMinTime = std::numeric_limits::infinity() * -1.0f; character->fields.KFIFBINFDPB->fields.m_pCharBattleInfo->fields.m_SidewalkMaxTime = std::numeric_limits::infinity() * -1.0f; diff --git a/src/game/cheat/features/FPSUnlock.cpp b/src/game/cheat/features/FPSUnlock.cpp index 8b1c669..e901edd 100644 --- a/src/game/cheat/features/FPSUnlock.cpp +++ b/src/game/cheat/features/FPSUnlock.cpp @@ -13,18 +13,20 @@ namespace Cheat::Features void FPSUnlock::OnGameUpdate() { - if (m_LastEnableStatus && !vars.b_FPSUnlock) + auto& vars = Vars::GetInstance(); + + if (m_LastEnableStatus && !vars.FPSUnlock.value()) { app::Application_set_targetFrameRate(m_OriginFPS, nullptr); } - else if (!m_LastEnableStatus && vars.b_FPSUnlock) + else if (!m_LastEnableStatus && vars.FPSUnlock.value()) { m_OriginFPS = app::Application_get_targetFrameRate(nullptr); } - m_LastEnableStatus = vars.b_FPSUnlock; - if (vars.b_FPSUnlock) + m_LastEnableStatus = vars.FPSUnlock.value(); + if (vars.FPSUnlock.value()) { - app::Application_set_targetFrameRate(vars.i_FPS, nullptr); + app::Application_set_targetFrameRate(vars.FPSValue.value(), nullptr); app::QualitySettings_set_vSyncCount(0, nullptr); } } diff --git a/src/game/cheat/features/FPSUnlock.h b/src/game/cheat/features/FPSUnlock.h index b97530f..0348538 100644 --- a/src/game/cheat/features/FPSUnlock.h +++ b/src/game/cheat/features/FPSUnlock.h @@ -13,6 +13,6 @@ namespace Cheat::Features private: bool m_LastEnableStatus = false; - int m_OriginFPS = 30; + int m_OriginFPS = 60; }; } diff --git a/src/game/cheat/features/FovChanger.cpp b/src/game/cheat/features/FovChanger.cpp index a253dee..8e5ef8e 100644 --- a/src/game/cheat/features/FovChanger.cpp +++ b/src/game/cheat/features/FovChanger.cpp @@ -10,11 +10,14 @@ namespace Cheat::Features { HookManager::install(app::Camera_set_fieldOfView, Camera_set_fieldOfView_Hook); } - + void FovChanger::Camera_set_fieldOfView_Hook(void* __this, float value, MethodInfo* method) { - if (vars.b_FovChanger) - value = vars.f_Fov; + auto& vars = Vars::GetInstance(); + + if (vars.FovChanger.value()) + value = vars.Fov.value(); + CALL_ORIGIN(Camera_set_fieldOfView_Hook, __this, value, method); } } diff --git a/src/game/cheat/features/MissionTime.cpp b/src/game/cheat/features/MissionTime.cpp index e2c411c..180a03d 100644 --- a/src/game/cheat/features/MissionTime.cpp +++ b/src/game/cheat/features/MissionTime.cpp @@ -12,8 +12,10 @@ namespace Cheat::Features void MissionTime::StageReadyPage_EnterUI_Hook(app::StageReadyPage* __this, MethodInfo* method) { - if (vars.b_MissionTime) - __this->fields.FHMGDAMDBHG->fields.m_Timelimit = vars.i_MissionTimeMs; + auto& vars = Vars::GetInstance(); + + if (vars.MissionTime.value()) + __this->fields.FHMGDAMDBHG->fields.m_Timelimit = vars.MissionTimeMs.value(); CALL_ORIGIN(StageReadyPage_EnterUI_Hook, __this, method); } diff --git a/src/game/cheat/features/NoCooldown.cpp b/src/game/cheat/features/NoCooldown.cpp index a654907..bd49d22 100644 --- a/src/game/cheat/features/NoCooldown.cpp +++ b/src/game/cheat/features/NoCooldown.cpp @@ -10,7 +10,9 @@ namespace Cheat::Features void* NoCooldown::KAAIFMKPKAG_IOFMGMJCCFO_Hook(app::KAAIFMKPKAG* __this, bool DEJNILEHENL, MethodInfo* method) { - if (vars.b_NoCooldown) + auto& vars = Vars::GetInstance(); + + if (vars.NoCooldown.value()) { __this->fields.HPHOOEPCBOJ = 0; __this->fields.JCJJDJGOBJL = 0; diff --git a/src/game/cheat/features/SkipIntroMovie.cpp b/src/game/cheat/features/SkipIntroMovie.cpp index b6959a4..581950d 100644 --- a/src/game/cheat/features/SkipIntroMovie.cpp +++ b/src/game/cheat/features/SkipIntroMovie.cpp @@ -18,7 +18,9 @@ namespace Cheat::Features } void SkipIntroMovie::IntroMovie_Update_Hook(app::IntroMovie* __this, MethodInfo* method) { - if (vars.b_SkipIntroMovie) + auto& vars = Vars::GetInstance(); + + if (vars.SkipIntroMovie.value()) __this->fields.GFOGMEGIEJN = app::IntroMovie_MHCMCCIDDCE__Enum::FINISH; CALL_ORIGIN(IntroMovie_Update_Hook, __this, method); } diff --git a/src/game/cheat/features/TimeScale.cpp b/src/game/cheat/features/TimeScale.cpp index c374934..59e2754 100644 --- a/src/game/cheat/features/TimeScale.cpp +++ b/src/game/cheat/features/TimeScale.cpp @@ -13,9 +13,11 @@ namespace Cheat::Features void TimeScale::OnGameUpdate() { - if (vars.b_TimeScale) + auto& vars = Vars::GetInstance(); + + if (vars.TimeScale.value()) { - app::Time_set_timeScale(vars.f_TimeScaleSpeed, nullptr); + app::Time_set_timeScale(vars.TimeScaleSpeed.value(), nullptr); m_DidSpeed = true; } else diff --git a/src/game/cheat/features/TimeScale.h b/src/game/cheat/features/TimeScale.h index 880aefe..57b9d2b 100644 --- a/src/game/cheat/features/TimeScale.h +++ b/src/game/cheat/features/TimeScale.h @@ -10,7 +10,7 @@ namespace Cheat::Features TimeScale(); void OnGameUpdate(); - + private: bool m_DidSpeed; }; diff --git a/src/game/cheat/vars.cpp b/src/game/cheat/vars.cpp deleted file mode 100644 index 728dc8c..0000000 --- a/src/game/cheat/vars.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "vars.h" - -Vars vars; \ No newline at end of file diff --git a/src/game/cheat/vars.h b/src/game/cheat/vars.h index b330a49..545206f 100644 --- a/src/game/cheat/vars.h +++ b/src/game/cheat/vars.h @@ -1,23 +1,25 @@ #pragma once -struct Vars -{ - bool b_PlayerSpeed = true; - bool b_NoCooldown = true; - bool b_GodMode = true; - bool b_DamageHack = true; - float f_DamageHackValue = 500.0f; - bool b_DumbEnemies = true; - bool b_MissionTime = true; - int i_MissionTimeMs = 180000; - bool b_TimeScale; - float f_TimeScaleSpeed = 2.0f; - bool b_FPSUnlock = true; - int i_FPS = 120; - bool b_FovChanger = false; - float f_Fov = 60.0f; - - bool b_SkipIntroMovie = true; -}; +#include "ConfigEntry.hpp" -extern Vars vars; \ No newline at end of file +class Vars final : public Singleton +{ +public: + Vars() = default; + + CONFIG_ENTRY(bool, PlayerSpeed, true); + CONFIG_ENTRY(bool, NoCooldown, true); + CONFIG_ENTRY(bool, GodMode, true); + CONFIG_ENTRY(bool, DamageHack, true); + CONFIG_ENTRY(float, DamageHackValue, 500.0f); + CONFIG_ENTRY(bool, DumbEnemies, true); + CONFIG_ENTRY(bool, MissionTime, true); + CONFIG_ENTRY(int, MissionTimeMs, 180000); + CONFIG_ENTRY(bool, TimeScale, false); + CONFIG_ENTRY(float, TimeScaleSpeed, 2.0f); + CONFIG_ENTRY(bool, FPSUnlock, true); + CONFIG_ENTRY(int, FPSValue, 120); + CONFIG_ENTRY(bool, FovChanger, false); + CONFIG_ENTRY(float, Fov, 60.0f); + CONFIG_ENTRY(bool, SkipIntroMovie, true); +}; \ No newline at end of file diff --git a/src/vendor/json b/src/vendor/json new file mode 160000 index 0000000..199dea1 --- /dev/null +++ b/src/vendor/json @@ -0,0 +1 @@ +Subproject commit 199dea11b17c533721b26249e2dcaee6ca1d51d3