From cdc9c1df1e0da77726f50b470cf0c8bb07da00b9 Mon Sep 17 00:00:00 2001 From: Skull <86374920+skkuull@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:32:49 +0200 Subject: [PATCH 1/2] enable bb & uncheat gpad dvars --- src/client/component/patches.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index ab717eb6..6a66ccea 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -283,6 +283,22 @@ namespace patches // disable cod account dvars::override::register_bool("enable_cod_account", false, game::DVAR_FLAG_READ); + // enable boss battles + dvars::override::register_bool("online_zombie_boss_battle", true, game::DVAR_FLAG_READ); + dvars::override::register_bool("online_zombie_boss_zmb", true, game::DVAR_FLAG_READ); + dvars::override::register_bool("online_zombie_boss_rave", true, game::DVAR_FLAG_READ); + dvars::override::register_bool("online_zombie_boss_disco", true, game::DVAR_FLAG_READ); + dvars::override::register_bool("online_zombie_boss_town", true, game::DVAR_FLAG_READ); + dvars::override::register_bool("online_zombie_boss_final", true, game::DVAR_FLAG_READ); + dvars::override::register_bool("online_zombie_boss_dc", true, game::DVAR_FLAG_READ); + + // uncheat protect gamepad-related dvars + dvars::override::register_float("gpad_button_deadzone", 0.13f, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("gpad_stick_deadzone_min", 0.2f, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("gpad_stick_deadzone_max", 0.01f, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("gpad_stick_pressed", 0.4f, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("gpad_stick_pressed_hysteresis", 0.1f, 0, 1, game::DVAR_FLAG_SAVED); + // block changing name in-game utils::hook::set(0xC4DF90_b, 0xC3); } From caf826b82a363dbcdc92dcc0dcec77fabbd16518 Mon Sep 17 00:00:00 2001 From: Skull <86374920+skkuull@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:40:09 +0200 Subject: [PATCH 2/2] refactor steam_proxy --- src/client/component/steam_proxy.cpp | 333 ++++++++++++++------------- src/client/component/steam_proxy.hpp | 1 + src/client/steam/steam.cpp | 5 + 3 files changed, 183 insertions(+), 156 deletions(-) diff --git a/src/client/component/steam_proxy.cpp b/src/client/component/steam_proxy.cpp index 670d1f29..64ecda83 100644 --- a/src/client/component/steam_proxy.cpp +++ b/src/client/component/steam_proxy.cpp @@ -20,6 +20,18 @@ namespace steam_proxy { utils::binary_resource runner_file(RUNNER, "runner.exe"); + utils::nt::library steam_client_module_{}; + utils::nt::library steam_overlay_module_{}; + + steam::interface client_engine_ {}; + steam::interface client_user_ {}; + steam::interface client_utils_ {}; + + steam::HSteamPipe steam_pipe_ = 0; + steam::HSteamUser global_user_ = 0; + + steam::client* steam_client_ {}; + enum class ownership_state { success, @@ -27,11 +39,146 @@ namespace steam_proxy nosteam, error, }; + + void* load_client_engine() + { + if (!steam_client_module_) return nullptr; + + for (auto i = 1; i > 0; ++i) + { + std::string name = utils::string::va("CLIENTENGINE_INTERFACE_VERSION%03i", i); + auto* const temp_client_engine = steam_client_module_ + .invoke("CreateInterface", name.data(), nullptr); + if (temp_client_engine) return temp_client_engine; + } + + return nullptr; + } + + void load_client() + { + SetEnvironmentVariableA("SteamAppId", std::to_string(steam::SteamUtils()->GetAppID()).data()); + + const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath(); + if (steam_path.empty()) return; + + utils::nt::library::load(steam_path / "tier0_s64.dll"); + utils::nt::library::load(steam_path / "vstdlib_s64.dll"); + steam_overlay_module_ = utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll"); + steam_client_module_ = utils::nt::library::load(steam_path / "steamclient64.dll"); + if (!steam_client_module_) return; + + client_engine_ = load_client_engine(); + if (!client_engine_) return; + + steam_pipe_ = steam_client_module_.invoke("Steam_CreateSteamPipe"); + global_user_ = steam_client_module_.invoke( + "Steam_ConnectToGlobalUser", steam_pipe_); + client_user_ = client_engine_.invoke(8, steam_pipe_, global_user_); + // GetIClientUser + client_utils_ = client_engine_.invoke(14, steam_pipe_); // GetIClientUtils + } + + void do_cleanup() + { + client_engine_ = nullptr; + client_user_ = nullptr; + client_utils_ = nullptr; + + steam_pipe_ = 0; + global_user_ = 0; + + steam_client_ = nullptr; + } + + bool perform_cleanup_if_needed() + { + if (steam_client_) return true; + + if (steam_client_module_ + && steam_pipe_ + && global_user_ + && steam_client_module_.invoke("Steam_BConnected", global_user_, steam_pipe_) + && steam_client_module_.invoke("Steam_BLoggedOn", global_user_, steam_pipe_) + ) + { + return false; + } + + do_cleanup(); + return true; + } + + void clean_up_on_error() + { + scheduler::schedule([]() + { + if (perform_cleanup_if_needed()) + { + return scheduler::cond_end; + } + + return scheduler::cond_continue; + }, scheduler::main); + } + + ownership_state start_mod_unsafe(const std::string& title, size_t app_id) + { + if (!client_utils_ || !client_user_) + { + return ownership_state::nosteam; + } + + if (!client_user_.invoke("BIsSubscribedApp", app_id)) + { + //app_id = 480; // Spacewar + return ownership_state::unowned; + } + + client_utils_.invoke("SetAppIDForCurrentPipe", app_id, false); + + char our_directory[MAX_PATH] = { 0 }; + GetCurrentDirectoryA(sizeof(our_directory), our_directory); + + const auto path = runner_file.get_extracted_file(); + const std::string cmdline = utils::string::va("\"%s\" -proc %d", path.data(), GetCurrentProcessId()); + + steam::game_id game_id; + game_id.raw.type = 1; // k_EGameIDTypeGameMod + game_id.raw.app_id = app_id & 0xFFFFFF; + + const auto* mod_id = "iw7"; + game_id.raw.mod_id = *reinterpret_cast(mod_id) | 0x80000000; + + client_user_.invoke("SpawnProcess", path.data(), cmdline.data(), our_directory, + &game_id.bits, title.data(), 0, 0, 0); + + return ownership_state::success; + } + + ownership_state start_mod(const std::string& title, const size_t app_id) + { + __try + { + return start_mod_unsafe(title, app_id); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + do_cleanup(); + return ownership_state::error; + } + } } class component final : public component_interface { public: + void post_load() override + { + load_client(); + perform_cleanup_if_needed(); + } + void post_unpack() override { if (game::environment::is_dedi()) @@ -39,13 +186,10 @@ namespace steam_proxy return; } - this->load_client(); - this->clean_up_on_error(); - #ifndef DEV_BUILD try { - const auto res = this->start_mod("\xF0\x9F\x8E\xAE" "IW7-Mod", steam::SteamUtils()->GetAppID()); + const auto res = start_mod("\xF0\x9F\x8E\xAE" "IW7-Mod", steam::SteamUtils()->GetAppID()); switch (res) { @@ -66,22 +210,29 @@ namespace steam_proxy TerminateProcess(GetCurrentProcess(), 1234); } #endif + clean_up_on_error(); } void pre_destroy() override { - if (this->steam_client_module_) + if (steam_client_) { - if (this->steam_pipe_) + if (global_user_) { - if (this->global_user_) - { - this->steam_client_module_.invoke("Steam_ReleaseUser", this->steam_pipe_, - this->global_user_); - } - - this->steam_client_module_.invoke("Steam_BReleaseSteamPipe", this->steam_pipe_); + steam_client_->ReleaseUser(steam_pipe_, global_user_); } + + steam_client_->BReleaseSteamPipe(steam_pipe_); + } + else if (steam_client_module_ && steam_pipe_) + { + if (global_user_) + { + steam_client_module_.invoke("Steam_ReleaseUser", steam_pipe_, + global_user_); + } + + steam_client_module_.invoke("Steam_BReleaseSteamPipe", steam_pipe_); } } @@ -89,153 +240,23 @@ namespace steam_proxy { return component_priority::steam_proxy; } - - const utils::nt::library& get_overlay_module() const - { - return steam_overlay_module_; - } - - private: - utils::nt::library steam_client_module_{}; - utils::nt::library steam_overlay_module_{}; - - steam::interface client_engine_ {}; - steam::interface client_user_ {}; - steam::interface client_utils_ {}; - - void* steam_pipe_ = nullptr; - void* global_user_ = nullptr; - - void* load_client_engine() const - { - if (!this->steam_client_module_) return nullptr; - - for (auto i = 1; i > 0; ++i) - { - std::string name = utils::string::va("CLIENTENGINE_INTERFACE_VERSION%03i", i); - auto* const client_engine = this->steam_client_module_ - .invoke("CreateInterface", name.data(), nullptr); - if (client_engine) return client_engine; - } - - return nullptr; - } - - void load_client() - { - const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath(); - if (steam_path.empty()) return; - - utils::nt::library::load(steam_path / "tier0_s64.dll"); - utils::nt::library::load(steam_path / "vstdlib_s64.dll"); - this->steam_overlay_module_ = utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll"); - this->steam_client_module_ = utils::nt::library::load(steam_path / "steamclient64.dll"); - if (!this->steam_client_module_) return; - - this->client_engine_ = load_client_engine(); - if (!this->client_engine_) return; - - this->steam_pipe_ = this->steam_client_module_.invoke("Steam_CreateSteamPipe"); - this->global_user_ = this->steam_client_module_.invoke( - "Steam_ConnectToGlobalUser", this->steam_pipe_); - this->client_user_ = this->client_engine_.invoke(8, this->steam_pipe_, this->global_user_); - // GetIClientUser - this->client_utils_ = this->client_engine_.invoke(14, this->steam_pipe_); // GetIClientUtils - } - - ownership_state start_mod(const std::string& title, const size_t app_id) - { - __try - { - return this->start_mod_unsafe(title, app_id); - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - this->do_cleanup(); - return ownership_state::error; - } - } - - ownership_state start_mod_unsafe(const std::string& title, size_t app_id) - { - if (!this->client_utils_ || !this->client_user_) - { - return ownership_state::nosteam; - } - - if (!this->client_user_.invoke("BIsSubscribedApp", app_id)) - { - //app_id = 480; // Spacewar - return ownership_state::unowned; - } - - this->client_utils_.invoke("SetAppIDForCurrentPipe", app_id, false); - - char our_directory[MAX_PATH] = { 0 }; - GetCurrentDirectoryA(sizeof(our_directory), our_directory); - - const auto path = runner_file.get_extracted_file(); - const std::string cmdline = utils::string::va("\"%s\" -proc %d", path.data(), GetCurrentProcessId()); - - steam::game_id game_id; - game_id.raw.type = 1; // k_EGameIDTypeGameMod - game_id.raw.app_id = app_id & 0xFFFFFF; - - const auto* mod_id = "iw7"; - game_id.raw.mod_id = *reinterpret_cast(mod_id) | 0x80000000; - - this->client_user_.invoke("SpawnProcess", path.data(), cmdline.data(), our_directory, - &game_id.bits, title.data(), 0, 0, 0); - - return ownership_state::success; - } - - void do_cleanup() - { - this->client_engine_ = nullptr; - this->client_user_ = nullptr; - this->client_utils_ = nullptr; - - this->steam_pipe_ = nullptr; - this->global_user_ = nullptr; - - this->steam_client_module_ = utils::nt::library{ nullptr }; - } - - void clean_up_on_error() - { - scheduler::schedule([this]() - { - if (this->steam_client_module_ - && this->steam_pipe_ - && this->global_user_ - && this->steam_client_module_.invoke("Steam_BConnected", this->global_user_, - this->steam_pipe_) - && this->steam_client_module_.invoke("Steam_BLoggedOn", this->global_user_, this->steam_pipe_) - ) - { - return scheduler::cond_continue; - } - - this->client_engine_ = nullptr; - this->client_user_ = nullptr; - this->client_utils_ = nullptr; - - this->steam_pipe_ = nullptr; - this->global_user_ = nullptr; - - this->steam_client_module_ = utils::nt::library{ nullptr }; - - return scheduler::cond_end; - }); - } }; const utils::nt::library& get_overlay_module() { - // TODO: Find a better way to do this - return component_loader::get()->get_overlay_module(); + return steam_overlay_module_; + } + + void initialize() + { + if (client_engine_ || !steam_client_module_) return; + + steam_client_ = steam_client_module_.invoke("CreateInterface", "SteamClient017", nullptr); + if (!steam_client_) return; + + steam_pipe_ = steam_client_->CreateSteamPipe(); + global_user_ = steam_client_->ConnectToGlobalUser(steam_pipe_); } } -REGISTER_COMPONENT(steam_proxy::component) +REGISTER_COMPONENT(steam_proxy::component) \ No newline at end of file diff --git a/src/client/component/steam_proxy.hpp b/src/client/component/steam_proxy.hpp index 8f7d0b8f..95f84f95 100644 --- a/src/client/component/steam_proxy.hpp +++ b/src/client/component/steam_proxy.hpp @@ -4,4 +4,5 @@ namespace steam_proxy { const utils::nt::library& get_overlay_module(); + void initialize(); } \ No newline at end of file diff --git a/src/client/steam/steam.cpp b/src/client/steam/steam.cpp index 2e1391c1..b777a91f 100644 --- a/src/client/steam/steam.cpp +++ b/src/client/steam/steam.cpp @@ -6,6 +6,8 @@ #include "loader/component_loader.hpp" +#include "../component/steam_proxy.hpp" + namespace steam { uint64_t callbacks::call_id_ = 0; @@ -120,6 +122,9 @@ namespace steam ::utils::nt::library::load(steam_path / "vstdlib_s64.dll"); ::utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll"); ::utils::nt::library::load(steam_path / "steamclient64.dll"); + + steam_proxy::initialize(); + return true; }