From 61f0374d108fbbe9cefa4387c143ade2d48bd9f6 Mon Sep 17 00:00:00 2001 From: diamante0018 Date: Wed, 21 May 2025 18:47:56 +0200 Subject: [PATCH] chore: update --- src/client/component/dvar_cheats.cpp | 25 +++++----- src/client/component/gsc/script_error.cpp | 27 +++++++++++ src/client/component/gsc/script_loading.cpp | 2 +- src/client/component/logger.cpp | 2 +- src/client/component/mods.cpp | 8 ++-- src/client/component/patches.cpp | 4 +- src/client/component/renderer.cpp | 5 +- src/client/game/structs.hpp | 1 + src/client/game/symbols.hpp | 1 + src/common/utils/string.cpp | 8 ++++ src/common/utils/string.hpp | 51 +++++++++++---------- 11 files changed, 86 insertions(+), 48 deletions(-) diff --git a/src/client/component/dvar_cheats.cpp b/src/client/component/dvar_cheats.cpp index a06000b..d17ec07 100644 --- a/src/client/component/dvar_cheats.cpp +++ b/src/client/component/dvar_cheats.cpp @@ -112,23 +112,24 @@ namespace dvar_cheats void cg_set_client_dvar_from_server(const int local_client_num, game::mp::cg_s* cg, const char* dvar_id, const char* value) { - if (dvar_id == "cg_fov"s || dvar_id == "com_maxfps"s) - { - return; - } - const auto* dvar = game::Dvar_FindVar(dvar_id); - if (dvar) - { - // If we send as string, it can't be set with source SERVERCMD because the game only allows that source on real server cmd dvars. - // Just use external instead as if it was being set by the console - game::Dvar_SetFromStringByNameFromSource(dvar_id, value, game::DvarSetSource::DVAR_SOURCE_EXTERNAL); - } - else + + if (!dvar) { // Not a dvar name, assume it is an id and the game will handle normally game::CG_SetClientDvarFromServer(local_client_num, cg, dvar_id, value); + return; } + + if (dvar && ((dvar->flags & game::DVAR_FLAG_SAVED) != 0)) + { + console::info("Not allowing server to override archive dvar '%s'\n", dvar->name); + return; + } + + // If we send as string, it can't be set with source SERVERCMD because the game only allows that source on real server cmd dvars. + // Just use external instead as if it was being set by the console + game::Dvar_SetFromStringByNameFromSource(dvar_id, value, game::DVAR_SOURCE_EXTERNAL); } void set_client_dvar_by_string(const int entity_num, const char* value) diff --git a/src/client/component/gsc/script_error.cpp b/src/client/component/gsc/script_error.cpp index 62027a7..5cb1072 100644 --- a/src/client/component/gsc/script_error.cpp +++ b/src/client/component/gsc/script_error.cpp @@ -113,6 +113,26 @@ namespace gsc return res; } + + bool player_cmd_set_client_dvar_is_valid_name(const char* dvar_name) + { + if (!game::Dvar_IsValidName(dvar_name)) + { + scr_error(va("%s is an invalid dvar name", dvar_name)); + } + + return true; + } + + void player_cmd_set_client_dvar_server_dvar() + { + scr_error("server dvar cannot be set as a client dvar"); + } + + void player_cmd_set_client_dvar_non_writable_dvar() + { + scr_error("non-writable dvar cannot be set as a client dvar"); + } } unsigned int scr_get_object(unsigned int index) @@ -300,6 +320,13 @@ namespace gsc utils::hook::jump(SELECT_VALUE(0x1403DE150, 0x1404390B0), scr_get_pointer_type); utils::hook::jump(SELECT_VALUE(0x1403DE320, 0x140439280), scr_get_type); utils::hook::jump(SELECT_VALUE(0x1403DE390, 0x1404392F0), scr_get_type_name); + + if (game::environment::is_mp()) + { + utils::hook::call(0x14038A4F7, player_cmd_set_client_dvar_is_valid_name); + utils::hook::call(0x14038A52F, player_cmd_set_client_dvar_server_dvar); + utils::hook::call(0x14038A53A, player_cmd_set_client_dvar_non_writable_dvar); + } } void pre_destroy() override diff --git a/src/client/component/gsc/script_loading.cpp b/src/client/component/gsc/script_loading.cpp index f7cb7cb..0e04a6e 100644 --- a/src/client/component/gsc/script_loading.cpp +++ b/src/client/component/gsc/script_loading.cpp @@ -347,7 +347,7 @@ namespace gsc build = static_cast(static_cast(build) | static_cast(xsk::gsc::build::dev_blocks)); } - gsc_ctx->init(build, []([[maybe_unused]] auto const* ctx, const auto& included_path) -> std::pair> + gsc_ctx->init(build, []([[maybe_unused]] const auto* ctx, const auto& included_path) -> std::pair> { const auto script_name = std::filesystem::path(included_path).replace_extension().string(); diff --git a/src/client/component/logger.cpp b/src/client/component/logger.cpp index b36a374..0cdf0f7 100644 --- a/src/client/component/logger.cpp +++ b/src/client/component/logger.cpp @@ -116,7 +116,7 @@ namespace logger // Make havok script's print function actually print utils::hook::jump(SELECT_VALUE(0x1406283A4, 0x140732184), print); - logger_dev = game::Dvar_RegisterBool("logger_dev", false, game::DVAR_FLAG_SAVED, "Print dev stuff"); + logger_dev = game::Dvar_RegisterBool("logger_dev", false, game::DVAR_FLAG_NONE, "Print dev stuff"); } }; } diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp index d992e82..aea4be0 100644 --- a/src/client/component/mods.cpp +++ b/src/client/component/mods.cpp @@ -16,7 +16,7 @@ namespace mods { utils::hook::detour sys_create_file_hook; - void db_build_os_path_from_source(const char* zone_name, game::FF_DIR source, int size, char* filename) + void db_build_os_path_from_source(const char* zone_name, const game::FF_DIR source, const int size, char* filename) { char user_map[MAX_PATH]{}; @@ -41,9 +41,9 @@ namespace mods } } - game::Sys_File sys_create_file_stub(const char* dir, const char* filename) + game::Sys_File sys_create_file_stub(game::Sys_Folder folder, const char* base_filename) { - auto result = sys_create_file_hook.invoke(dir, filename); + auto result = sys_create_file_hook.invoke(folder, base_filename); if (result.handle != INVALID_HANDLE_VALUE) { @@ -56,7 +56,7 @@ namespace mods } // .ff extension was added previously - if (!std::strcmp(filename, "mod.ff") && mods::db_mod_file_exists()) + if (!std::strcmp(base_filename, "mod.ff") && mods::db_mod_file_exists()) { char file_path[MAX_PATH]{}; db_build_os_path_from_source("mod", game::FFD_MOD_DIR, sizeof(file_path), file_path); diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 640fe03..b58e53c 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -166,11 +166,11 @@ namespace patches game::AimAssist_AddToTargetList(a1, a2); } - game::dvar_t* register_cg_fov_stub(const char* name, float value, float min, float /*max*/, + game::dvar_t* register_cg_fov_stub(const char* name, const float value, const float min, [[maybe_unused]] const float max, const unsigned int flags, const char* description) { - return game::Dvar_RegisterFloat(name, value, min, 160, flags | 1, description); + return game::Dvar_RegisterFloat(name, value, min, 160, flags, description); } void bsp_sys_error_stub(const char* error, const char* arg1) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index 0f20e45..163b47c 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -46,12 +46,11 @@ namespace renderer return; } - dvars::r_fullbright = game::Dvar_RegisterBool("r_fullbright", false, game::DvarFlags::DVAR_FLAG_SAVED, + dvars::r_fullbright = game::Dvar_RegisterBool("r_fullbright", false, game::DVAR_FLAG_CHEAT, "Toggles rendering without lighting"); r_init_draw_method_hook.create(SELECT_VALUE(0x1404FF600, 0x1405CB470), &r_init_draw_method_stub); - r_update_front_end_dvar_options_hook.create( - SELECT_VALUE(0x140535FF0, 0x140603240), &r_update_front_end_dvar_options_stub); + r_update_front_end_dvar_options_hook.create(SELECT_VALUE(0x140535FF0, 0x140603240), &r_update_front_end_dvar_options_stub); } }; } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 84a21e5..461dfd9 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1181,6 +1181,7 @@ namespace game DVAR_FLAG_LATCHED = 0x2, DVAR_FLAG_CHEAT = 0x4, DVAR_FLAG_REPLICATED = 0x8, + DVAR_FLAG_SCRIPTINFO = 0x10, DVAR_FLAG_INTERNAL = 0x80, DVAR_FLAG_EXTERNAL = 0x100, DVAR_FLAG_SERVERINFO = 0x400, diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index b90bd78..14a7a4e 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -91,6 +91,7 @@ namespace game WEAK symbol Dvar_SetFromStringByNameFromSource{0x14042D000, 0x1404F00B0}; WEAK symbol Dvar_Sort{0x14042DEF0, 0x1404F1210}; WEAK symbol Dvar_ValueToString{0x14042E710, 0x1404F1A30}; + WEAK symbol Dvar_IsValidName{0x0, 0x1404ED0E0}; WEAK symbol FS_ReadFile{0x14041D0B0, 0x1404DE900}; WEAK symbol FS_FreeFile{0x14041D0A0, 0x1404DE8F0}; diff --git a/src/common/utils/string.cpp b/src/common/utils/string.cpp index 649c590..89b573d 100644 --- a/src/common/utils/string.cpp +++ b/src/common/utils/string.cpp @@ -67,6 +67,14 @@ namespace utils::string return std::equal(substring.rbegin(), substring.rend(), text.rbegin()); } + bool compare(const std::string& lhs, const std::string& rhs) + { + return std::ranges::equal(lhs, rhs, [](const unsigned char a, const unsigned char b) + { + return std::tolower(a) == std::tolower(b); + }); + } + bool is_numeric(const std::string& text) { return std::to_string(atoi(text.data())) == text; diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index c579118..6909e3e 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -22,78 +22,79 @@ namespace utils::string ++this->current_buffer_ %= ARRAY_COUNT(this->string_pool_); auto entry = &this->string_pool_[this->current_buffer_]; - if (!entry->size || !entry->buffer) + if (!entry->size_ || !entry->buffer_) { throw std::runtime_error("String pool not initialized"); } while (true) { - const int res = vsnprintf(entry->buffer, entry->size, format, ap); + const int res = vsnprintf(entry->buffer_, entry->size_, format, ap); if (res > 0) break; // Success if (res == 0) return nullptr; // Error entry->double_size(); } - return entry->buffer; + return entry->buffer_; } private: class entry final { public: - explicit entry(const size_t _size = MinBufferSize) : size(_size), buffer(nullptr) + explicit entry(const size_t size = MinBufferSize) : size_(size), buffer_(nullptr) { - if (this->size < MinBufferSize) this->size = MinBufferSize; + this->size_ = std::max(this->size_, MinBufferSize); this->allocate(); } ~entry() { - if (this->buffer) memory::get_allocator()->free(this->buffer); - this->size = 0; - this->buffer = nullptr; + if (this->buffer_) memory::get_allocator()->free(this->buffer_); + this->size_ = 0; + this->buffer_ = nullptr; } void allocate() { - if (this->buffer) memory::get_allocator()->free(this->buffer); - this->buffer = memory::get_allocator()->allocate_array(this->size + 1); + if (this->buffer_) memory::get_allocator()->free(this->buffer_); + this->buffer_ = memory::get_allocator()->allocate_array(this->size_ + 1); } void double_size() { - this->size *= 2; + this->size_ *= 2; this->allocate(); } - size_t size; - char* buffer; + size_t size_; + char* buffer_; }; size_t current_buffer_; entry string_pool_[Buffers]; }; - const char* va(const char* fmt, ...); + [[nodiscard]] const char* va(const char* fmt, ...); - std::vector split(const std::string& s, char delim); + [[nodiscard]] std::vector split(const std::string& s, char delim); - std::string to_lower(const std::string& text); - std::string to_upper(const std::string& text); - bool starts_with(const std::string& text, const std::string& substring); - bool ends_with(const std::string& text, const std::string& substring); - bool is_numeric(const std::string& text); + [[nodiscard]] std::string to_lower(const std::string& text); + [[nodiscard]] std::string to_upper(const std::string& text); + [[nodiscard]] bool starts_with(const std::string& text, const std::string& substring); + [[nodiscard]] bool ends_with(const std::string& text, const std::string& substring); + [[nodiscard]] bool compare(const std::string& lhs, const std::string& rhs); + [[nodiscard]] bool is_numeric(const std::string& text); - std::string dump_hex(const std::string& data, const std::string& separator = " "); + [[nodiscard]] std::string dump_hex(const std::string& data, const std::string& separator = " "); - std::string get_clipboard_data(); + [[nodiscard]] std::string get_clipboard_data(); void strip(const char* in, char* out, size_t max); - std::string convert(const std::wstring& wstr); - std::wstring convert(const std::string& str); + [[nodiscard]] std::string convert(const std::wstring& wstr); + [[nodiscard]] std::wstring convert(const std::string& str); - std::string replace(std::string str, const std::string& from, const std::string& to); + [[nodiscard]] std::string replace(std::string str, const std::string& from, const std::string& to); }