From 41172e10e65f234bc3c59275d2f9bb6855ae136b Mon Sep 17 00:00:00 2001 From: m Date: Thu, 3 Mar 2022 06:56:46 -0600 Subject: [PATCH] add filesystem + executing custom cfg files --- src/client/component/filesystem.cpp | 94 +++++++++++++++++++++++++++++ src/client/component/filesystem.hpp | 19 ++++++ src/client/component/patches.cpp | 29 ++++++--- 3 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 src/client/component/filesystem.cpp create mode 100644 src/client/component/filesystem.hpp diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp new file mode 100644 index 00000000..da11d2e4 --- /dev/null +++ b/src/client/component/filesystem.cpp @@ -0,0 +1,94 @@ +#include +#include "loader/component_loader.hpp" +#include "filesystem.hpp" +#include "game_module.hpp" + +#include "game/game.hpp" +#include "dvars.hpp" + +#include +#include + +namespace filesystem +{ + namespace + { + bool custom_path_registered = false; + + std::string get_binary_directory() + { + const auto dir = game_module::get_host_module().get_folder(); + return utils::string::replace(dir, "/", "\\"); + } + + void register_custom_path_stub(const char* path, const char* dir) + { + if (!custom_path_registered) + { + custom_path_registered = true; + + const auto launcher_dir = get_binary_directory(); + game::FS_AddLocalizedGameDirectory(launcher_dir.data(), "data"); + } + + game::FS_AddLocalizedGameDirectory(path, dir); + } + + void fs_startup_stub(const char* gamename) + { + custom_path_registered = false; + game::FS_Startup(gamename); + } + } + + file::file(std::string name) + : name_(std::move(name)) + { + char* buffer{}; + const auto size = game::FS_ReadFile(this->name_.data(), &buffer); + + if (size >= 0 && buffer) + { + this->valid_ = true; + this->buffer_.append(buffer, size); + game::FS_FreeFile(buffer); + } + } + + bool file::exists() const + { + return this->valid_; + } + + const std::string& file::get_buffer() const + { + return this->buffer_; + } + + const std::string& file::get_name() const + { + return this->name_; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // Set fs_basegame + dvars::override::register_string("fs_basegame", "h1-mod", game::DVAR_FLAG_WRITE); + + utils::hook::call(SELECT_VALUE(0x1403B76E2, 0x1404ED3E2), fs_startup_stub); + if (game::environment::is_mp()) + { + utils::hook::call(0x1404ED823, fs_startup_stub); + } + + utils::hook::call(SELECT_VALUE(0x1403B8D31, 0x1404EE3D0), register_custom_path_stub); + utils::hook::call(SELECT_VALUE(0x1403B8D51, 0x1404EE3F0), register_custom_path_stub); + utils::hook::call(SELECT_VALUE(0x1403B8D90, 0x1404EE42F), register_custom_path_stub); + } + }; +} + +REGISTER_COMPONENT(filesystem::component) \ No newline at end of file diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp new file mode 100644 index 00000000..6cec8c87 --- /dev/null +++ b/src/client/component/filesystem.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace filesystem +{ + class file + { + public: + file(std::string name); + + bool exists() const; + const std::string& get_buffer() const; + const std::string& get_name() const; + + private: + bool valid_ = false; + std::string name_; + std::string buffer_; + }; +} \ No newline at end of file diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index a8ee11fc..e9aaf21a 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -7,6 +7,7 @@ #include "console.hpp" #include "network.hpp" #include "scheduler.hpp" +#include "filesystem.hpp" #include "game/game.hpp" #include "game/dvars.hpp" @@ -77,16 +78,27 @@ namespace patches } // CG_SetClientDvarFromServer - reinterpret_cast(0x140236120)(a1, a2, dvar, value); + utils::hook::invoke(0x140236120, a1, a2, dvar, value); } - /*void aim_assist_add_to_target_list(void* a1, void* a2) + const char* db_read_raw_file_stub(const char* filename, char* buf, const int size) { - if (!dvars::aimassist_enabled->current.enabled) - return; + std::string file_name = filename; + if (file_name.find(".cfg") == std::string::npos) + { + file_name.append(".cfg"); + } - game::AimAssist_AddToTargetList(a1, a2); - }*/ + const auto file = filesystem::file(file_name); + if (file.exists()) + { + snprintf(buf, size, "%s\n", file.get_buffer().data()); + return buf; + } + + // DB_ReadRawFile + return utils::hook::invoke(SELECT_VALUE(0x1401CD4F0, 0x1402BEF10), filename, buf, size); + } void bsp_sys_error_stub(const char* error, const char* arg1) { @@ -131,7 +143,7 @@ namespace patches return; } - reinterpret_cast(0x140481A00)(client, msg); + utils::hook::invoke(0x140481A00, client, msg); } void aim_assist_add_to_target_list(void* a1, void* a2) @@ -172,6 +184,9 @@ namespace patches utils::hook::nop(SELECT_VALUE(0x14018797E, 0x14024EF60), 2); utils::hook::nop(SELECT_VALUE(0x1401856DC, 0x14024C6B0), 6); + // Allow executing custom cfg files with the "exec" command + utils::hook::call(SELECT_VALUE(0x140343855, 0x140403E28), db_read_raw_file_stub); + if (!game::environment::is_sp()) { patch_mp();