From 2099fc78a7e02b3289c9b248edcdfefa4e97ddce Mon Sep 17 00:00:00 2001 From: BrentVL-1952840 <70229620+Brentdevent@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:09:09 +0100 Subject: [PATCH 1/4] Kill deleting archive dvars debug names function --- src/client/component/dvars.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index 1e74871d..ece4ed70 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -2,13 +2,12 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" +#include "scheduler.hpp" #include #include #include -#include "scheduler.hpp" - namespace dvars { namespace @@ -114,12 +113,6 @@ namespace dvars { return false; } - - //TODO: Fix archive dvars not stripping names from registered dvars - if (dvar->debugName == "cg_unlockall_loot"s || dvar->debugName == "cg_unlockall_purchases"s || dvar->debugName == "cg_unlockall_attachments"s || dvar->debugName == "cg_unlockall_camos"s) - { - return true; - } return (dvar->flags & game::DVAR_ARCHIVE); } @@ -217,6 +210,8 @@ namespace dvars utils::hook::nop(game::select(0x142152227, 0x140509797), 6); // Show all dvars in dvardump command utils::hook::nop(game::select(0x142151BF9, 0x140509179), 6); + // Stops game from deleting debug names from archive dvars + utils::hook::set(game::select(0x1422C5DE0, 0x1405786D0), 0xC3); } }; } From 8379f314fda1f3330704acb3cca7ed41452a939a Mon Sep 17 00:00:00 2001 From: BrentVL-1952840 <70229620+Brentdevent@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:12:53 +0100 Subject: [PATCH 2/4] Add dvars patches --- src/client/component/dvars_patches.cpp | 82 ++++++++++++++++++++++++++ src/client/component/scheduler.hpp | 69 +++++++++++----------- src/client/game/structs.hpp | 5 +- src/client/game/symbols.hpp | 5 +- src/client/game/utils.cpp | 64 ++++++++++++++++++++ src/client/game/utils.hpp | 7 +++ 6 files changed, 196 insertions(+), 36 deletions(-) create mode 100644 src/client/component/dvars_patches.cpp diff --git a/src/client/component/dvars_patches.cpp b/src/client/component/dvars_patches.cpp new file mode 100644 index 00000000..45047310 --- /dev/null +++ b/src/client/component/dvars_patches.cpp @@ -0,0 +1,82 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/utils.hpp" +#include "scheduler.hpp" + +#include + +namespace dvars_patches +{ + namespace + { + void patch_dvars() + { + if (game::is_server()) + { + game::register_dvar_bool("com_pauseSupported", false, game::DVAR_NONE, "Whether is pause is ever supported by the game mode"); + } + } + + void patch_flags() + { + game::dvar_set_flags("com_pauseSupported", game::DVAR_SERVERINFO); + + if (game::is_client()) + { + game::dvar_set_flags("r_dof_enable", game::DVAR_ARCHIVE); + game::dvar_set_flags("r_lodbiasrigid", game::DVAR_ARCHIVE); + game::dvar_set_flags("gpad_stick_deadzone_max", game::DVAR_ARCHIVE); + game::dvar_set_flags("gpad_stick_deadzone_min", game::DVAR_ARCHIVE); + } + + scheduler::execute(scheduler::pipeline::dvars_flags_patched); + } + + void dof_enabled_stub(utils::hook::assembler& a) + { + const auto update_ads_dof = a.newLabel(); + + a.pushad64(); + a.push(rax); + + a.mov(rax, qword_ptr(0x14AE95478_g)); // r_dof_enable + a.cmp(byte_ptr(rax, 0x28), 1); + + a.pop(rax); + a.je(update_ads_dof); + + a.popad64(); + a.jmp(0x141116ECB_g); + + a.bind(update_ads_dof); + a.lea(rdx, ptr(rbx, 0x131EB4)); + a.mov(ecx, esi); + a.call_aligned(0x141107EC0_g); // CG_UpdateAdsDof + + a.popad64(); + a.jmp(0x141116F49_g); + } + } + + class component final : public generic_component + { + public: + void post_unpack() override + { + patch_dvars(); + scheduler::once(patch_flags, scheduler::pipeline::main, 10s); + + if (game::is_server()) + { + return; + } + + // toggle ADS dof based on r_dof_enable + utils::hook::jump(0x141116EBB_g, utils::hook::assemble(dof_enabled_stub), true); + } + }; +} + +REGISTER_COMPONENT(dvars_patches::component) diff --git a/src/client/component/scheduler.hpp b/src/client/component/scheduler.hpp index ac5c3f06..8949b6e4 100644 --- a/src/client/component/scheduler.hpp +++ b/src/client/component/scheduler.hpp @@ -1,38 +1,41 @@ -#pragma once - -namespace scheduler -{ - enum pipeline - { - // Asynchronuous pipeline, disconnected from the game - async = 0, - - // The game's rendering pipeline - renderer, - - // The game's server thread - server, - - // The game's main thread +#pragma once + +namespace scheduler +{ + enum pipeline + { + // Asynchronuous pipeline, disconnected from the game + async = 0, + + // The game's rendering pipeline + renderer, + + // The game's server thread + server, + + // The game's main thread main, + // Dvars flags have been patched, ready to be set from config file + dvars_flags_patched, + // Dvars are done loading from the config file - dvars_loaded, - - count, - }; - - static const bool cond_continue = false; + dvars_loaded, + + count, + }; + + static const bool cond_continue = false; static const bool cond_end = true; - void execute(const pipeline type); - - void schedule(const std::function& callback, pipeline type = pipeline::async, - std::chrono::milliseconds delay = 0ms); - void loop(const std::function& callback, pipeline type = pipeline::async, - std::chrono::milliseconds delay = 0ms); - void once(const std::function& callback, pipeline type = pipeline::async, - std::chrono::milliseconds delay = 0ms); - void on_game_initialized(const std::function& callback, pipeline type = pipeline::async, - std::chrono::milliseconds delay = 0ms); -} + void execute(const pipeline type); + + void schedule(const std::function& callback, pipeline type = pipeline::async, + std::chrono::milliseconds delay = 0ms); + void loop(const std::function& callback, pipeline type = pipeline::async, + std::chrono::milliseconds delay = 0ms); + void once(const std::function& callback, pipeline type = pipeline::async, + std::chrono::milliseconds delay = 0ms); + void on_game_initialized(const std::function& callback, pipeline type = pipeline::async, + std::chrono::milliseconds delay = 0ms); +} diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index f420fd68..ff759ff0 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -646,10 +646,11 @@ namespace game enum dvarFlags_e { + DVAR_NONE = 0, DVAR_ARCHIVE = 1 << 0, DVAR_USERINFO = 1 << 1, - DVAR_SYSTEMINFO = 1 << 2, - DVAR_CODINFO = 1 << 3, + DVAR_SERVERINFO = 1 << 2, + DVAR_SYSTEMINFO = 1 << 3, DVAR_LATCH = 1 << 4, DVAR_ROM = 1 << 5, DVAR_SAVED = 1 << 6, diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 741a07e5..a97fa2be 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -106,7 +106,7 @@ namespace game WEAK symbol Dvar_GetBool{0x1422BCED0}; WEAK symbol Dvar_RegisterBool{ - 0x1422D0900 + 0x1422D0900, 0x14057B500 }; WEAK symbol Dvar_RegisterString{ @@ -116,6 +116,9 @@ namespace game WEAK symbol Dvar_SetFromStringByName{ 0x1422C7500 }; + WEAK symbol Dvar_GetSessionModeSpecificDvar{ + 0x1422BF500, 0x140575D90 + }; // UI WEAK symbol UI_CoD_Init{0x141F29010, 0x1404A0A50}; diff --git a/src/client/game/utils.cpp b/src/client/game/utils.cpp index 143c73f4..da6401d7 100644 --- a/src/client/game/utils.cpp +++ b/src/client/game/utils.cpp @@ -26,4 +26,68 @@ namespace game return dvar->current.value.integer; } + + bool get_dvar_bool(const char* dvar_name) + { + const auto dvar = Dvar_FindVar(dvar_name); + if (!dvar) + { + return {}; + } + + return dvar->current.value.enabled; + } + + dvar_t* register_dvar_bool(const char* dvar_name, const bool value, const dvarFlags_e flags, const char* description) + { + const auto hash = Dvar_GenerateHash(dvar_name); + auto registered_dvar = Dvar_RegisterBool(hash, dvar_name, value, flags, description); + + if (registered_dvar) + { + registered_dvar->debugName = dvar_name; + } + + return registered_dvar; + } + + void dvar_add_flags(const char* dvar_name, const dvarFlags_e flags) + { + auto dvar = Dvar_FindVar(dvar_name); + + if (!dvar) + { + return; + } + + auto dvar_to_change = dvar; + + if (dvar_to_change->type == DVAR_TYPE_SESSIONMODE_BASE_DVAR) + { + const auto mode = Com_SessionMode_GetMode(); + dvar_to_change = Dvar_GetSessionModeSpecificDvar(dvar_to_change, mode); + } + + dvar_to_change->flags |= flags; + } + + void dvar_set_flags(const char* dvar_name, const dvarFlags_e flags) + { + auto dvar = Dvar_FindVar(dvar_name); + + if (!dvar) + { + return; + } + + auto dvar_to_change = dvar; + + if (dvar_to_change->type == DVAR_TYPE_SESSIONMODE_BASE_DVAR) + { + const auto mode = Com_SessionMode_GetMode(); + dvar_to_change = Dvar_GetSessionModeSpecificDvar(dvar_to_change, mode); + } + + dvar_to_change->flags = flags; + } } diff --git a/src/client/game/utils.hpp b/src/client/game/utils.hpp index 5bd1a9a4..bcb1d2a2 100644 --- a/src/client/game/utils.hpp +++ b/src/client/game/utils.hpp @@ -1,7 +1,14 @@ #pragma once +#include "structs.hpp" + namespace game { std::string get_dvar_string(const char* dvar_name); int get_dvar_int(const char* dvar_name); + bool get_dvar_bool(const char* dvar_name); + + dvar_t* register_dvar_bool(const char* dvar_name, bool value, dvarFlags_e flags, const char* description); + void dvar_add_flags(const char* dvar, dvarFlags_e flags); + void dvar_set_flags(const char* dvar_name, dvarFlags_e flags); } From c42f333b9911559bd407475b8da69a33a6e4fea9 Mon Sep 17 00:00:00 2001 From: BrentVL-1952840 <70229620+Brentdevent@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:14:33 +0100 Subject: [PATCH 3/4] Update dvars.cpp --- src/client/component/dvars.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index ece4ed70..c6e7ee38 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -194,7 +194,7 @@ namespace dvars { if (!game::is_server()) { - scheduler::once(read_archive_dvars, scheduler::pipeline::main); + scheduler::once(read_archive_dvars, scheduler::pipeline::dvars_flags_patched); dvar_set_variant_hook.create(0x1422C9030_g, dvar_set_variant_stub); // Show all known dvars in console From 7cc80c71ec6319fc5da33b69b9d159193b5d2031 Mon Sep 17 00:00:00 2001 From: BrentVL-1952840 <70229620+Brentdevent@users.noreply.github.com> Date: Thu, 16 Mar 2023 13:14:58 +0100 Subject: [PATCH 4/4] Refactor --- src/client/component/loot.cpp | 13 +++++-------- src/client/component/party.cpp | 2 -- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/client/component/loot.cpp b/src/client/component/loot.cpp index d2afb1c2..25df9f64 100644 --- a/src/client/component/loot.cpp +++ b/src/client/component/loot.cpp @@ -5,6 +5,7 @@ #include "scheduler.hpp" #include "game/game.hpp" +#include "game/utils.hpp" namespace loot { @@ -95,14 +96,10 @@ namespace loot { void post_unpack() override { - dvar_cg_unlockall_loot = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_loot"), "cg_unlockall_loot", false, (game::dvarFlags_e)0x0, "Unlocks blackmarket loot"); - dvar_cg_unlockall_loot->debugName = "cg_unlockall_loot"; - dvar_cg_unlockall_purchases = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_purchases"), "cg_unlockall_purchases", false, (game::dvarFlags_e)0x0, "Unlock all purchases with tokens"); - dvar_cg_unlockall_purchases->debugName = "cg_unlockall_purchases"; - dvar_cg_unlockall_attachments = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_attachments"), "cg_unlockall_attachments", false, (game::dvarFlags_e)0x0, "Unlocks all attachments"); - dvar_cg_unlockall_attachments->debugName = "cg_unlockall_attachments"; - dvar_cg_cg_unlockall_camos = game::Dvar_RegisterBool(game::Dvar_GenerateHash("cg_unlockall_camos"), "cg_unlockall_camos", false, (game::dvarFlags_e)0x0, "Unlocks all camos"); - dvar_cg_cg_unlockall_camos->debugName = "cg_unlockall_camos"; + dvar_cg_unlockall_loot = game::register_dvar_bool("cg_unlockall_loot", false, game::DVAR_ARCHIVE, "Unlocks blackmarket loot"); + dvar_cg_unlockall_purchases = game::register_dvar_bool("cg_unlockall_purchases", false, game::DVAR_ARCHIVE, "Unlock all purchases with tokens"); + dvar_cg_unlockall_attachments = game::register_dvar_bool("cg_unlockall_attachments", false, game::DVAR_ARCHIVE, "Unlocks all attachments"); + dvar_cg_cg_unlockall_camos = game::register_dvar_bool("cg_unlockall_camos", false, game::DVAR_ARCHIVE, "Unlocks all camos"); loot_getitemquantity_hook.create(0x141E82C00_g, loot_getitemquantity_stub); liveinventory_getitemquantity_hook.create(0x141E09030_g, liveinventory_getitemquantity_stub); diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 793cc8a9..53ecc3bd 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -1,7 +1,6 @@ #include #include "loader/component_loader.hpp" #include "game/game.hpp" -#include "game/utils.hpp" #include "party.hpp" #include "network.hpp" @@ -14,7 +13,6 @@ #include #include - namespace party { namespace