diff --git a/resources/hacks/level.json b/resources/hacks/level.json index 981ec9d..20ddf43 100644 --- a/resources/hacks/level.json +++ b/resources/hacks/level.json @@ -289,6 +289,10 @@ { "type": "embedded", "hack": "hitboxes" + }, + { + "type": "embedded", + "hack": "respawn_delay" } ] } diff --git a/src/shared/hacks/hacks.cpp b/src/shared/hacks/hacks.cpp index 49b4bfc..75f6f38 100644 --- a/src/shared/hacks/hacks.cpp +++ b/src/shared/hacks/hacks.cpp @@ -20,6 +20,7 @@ #include "random-seed/random-seed.hpp" #include "menu-gameplay/menu-gameplay.hpp" #include "hitboxes/hitboxes.hpp" +#include "respawn-delay/respawn-delay.hpp" namespace openhack::hacks { void ToggleComponent::onInit() { @@ -243,6 +244,7 @@ namespace openhack::hacks { new RandomSeed(), new MenuGameplay(), new Hitboxes(), + new RespawnDelay(), }; std::vector embeddedHacksCopy = embeddedHacks; diff --git a/src/shared/hacks/respawn-delay/respawn-delay.cpp b/src/shared/hacks/respawn-delay/respawn-delay.cpp new file mode 100644 index 0000000..b4e0da3 --- /dev/null +++ b/src/shared/hacks/respawn-delay/respawn-delay.cpp @@ -0,0 +1,53 @@ +#include "respawn-delay.hpp" +#include "../../menu/menu.hpp" + +namespace openhack::hacks { + + float RespawnDelay::delay = 0.5f; + static ToggleComponent* s_respawnDelay = nullptr; + + inline void togglePatch() { + if (!s_respawnDelay) return; + bool enabled = config::get("hack.respawn_delay.enabled"); + s_respawnDelay->applyPatch(enabled); + } + + void RespawnDelay::onInit() { + // Set default values + config::setIfEmpty("hack.respawn_delay.enabled", false); + config::setIfEmpty("hack.respawn_delay.delay", 0.5f); + delay = config::get("hack.respawn_delay.delay"); + + // Initialize toggle + std::vector opcodes = gd::sigscan::match( + "F30F1005^????68????C6", + utils::bytesToHex(utils::getBytes((uintptr_t)&delay))); + auto customBypass = gd::sigscan::match("84C0^7410F30F10", "EB"); + + if (opcodes.empty() || customBypass.empty()) { + L_WARN("Failed to find signature for RespawnDelay"); + return; + } + + opcodes.push_back(customBypass[0]); + s_respawnDelay = new ToggleComponent("", "", opcodes); + togglePatch(); + } + + void RespawnDelay::onDraw() { + gui::callback([](){ + gui::tooltip("Allows you to change the default respawn time"); + }); + if (gui::toggleSetting("Respawn Delay", "hack.respawn_delay.enabled", []() { + gui::width(100); + if (gui::inputFloat("Delay", "hack.respawn_delay.delay", 0.0f, FLT_MAX, "%.3f sec.")) { + delay = config::get("hack.respawn_delay.delay"); + } + gui::tooltip("The delay before respawning"); + gui::width(); + }, ImVec2(0, 0))) { + togglePatch(); + } + } + +} \ No newline at end of file diff --git a/src/shared/hacks/respawn-delay/respawn-delay.hpp b/src/shared/hacks/respawn-delay/respawn-delay.hpp new file mode 100644 index 0000000..2834ac7 --- /dev/null +++ b/src/shared/hacks/respawn-delay/respawn-delay.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "../hacks.hpp" + +namespace openhack::hacks { + + /// @brief Allows to change default respawn time + class RespawnDelay : public EmbeddedHack { + public: + RespawnDelay() : EmbeddedHack("Respawn Delay", "respawn_delay") {} + + void onInit() override; + void onDraw() override; + void update() override {} + bool isCheating() override { return false; } + + public: + static float delay; + }; + +} \ No newline at end of file diff --git a/src/shared/utils.hpp b/src/shared/utils.hpp index b9a8b9b..9c0d788 100644 --- a/src/shared/utils.hpp +++ b/src/shared/utils.hpp @@ -264,6 +264,15 @@ namespace openhack::utils { return (uintptr_t) strtol(hexCopy.c_str(), nullptr, 16); } + /// @brief Convert a value to a vector of bytes. + /// @tparam T The type of the value. + /// @param value The value. + /// @return The vector of bytes. + template + inline std::vector getBytes(T value) { + return std::vector((uint8_t *) &value, (uint8_t *) &value + sizeof(T)); + } + /// @brief Convert a vector of bytes to a string of hex characters. /// @param bytes The vector of bytes. /// @return The string of hex characters.