From ac19219bf0f18bd80177f176ef02ce81bc6c576a Mon Sep 17 00:00:00 2001 From: Diavolo Date: Tue, 28 Jun 2022 11:56:21 +0200 Subject: [PATCH] Restore timescale dvars --- src/game/demonware/services/bdDediAuth.cpp | 4 +- src/game/demonware/services/bdDediRSAAuth.cpp | 4 +- src/game/game.cpp | 6 +- src/game/game.hpp | 2 + src/game/structs.hpp | 5 +- src/module/fov.cpp | 12 ++- src/module/gameplay.cpp | 74 +++++++++++++++++++ src/module/player_movement.cpp | 6 +- 8 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 src/module/gameplay.cpp diff --git a/src/game/demonware/services/bdDediAuth.cpp b/src/game/demonware/services/bdDediAuth.cpp index 19c5bd6..79e42f8 100644 --- a/src/game/demonware/services/bdDediAuth.cpp +++ b/src/game/demonware/services/bdDediAuth.cpp @@ -15,12 +15,12 @@ namespace demonware buffer.read_bool(&more_data); buffer.set_use_data_types(true); - uint32_t seed, title_id, ticket_size; + uint32_t seed, title_id; buffer.read_uint32(&seed); buffer.read_uint32(&title_id); uint8_t ticket[1024]; - buffer.read_bytes(std::min(ticket_size, static_cast(sizeof(ticket))), ticket); + buffer.read_bytes(sizeof(ticket), ticket); game::native::bdAuthTicket auth_ticket{}; std::memset(&auth_ticket, 0xA, sizeof auth_ticket); diff --git a/src/game/demonware/services/bdDediRSAAuth.cpp b/src/game/demonware/services/bdDediRSAAuth.cpp index e4a2523..df05bf1 100644 --- a/src/game/demonware/services/bdDediRSAAuth.cpp +++ b/src/game/demonware/services/bdDediRSAAuth.cpp @@ -15,7 +15,7 @@ namespace demonware buffer.read_bool(&more_data); buffer.set_use_data_types(true); - uint32_t seed, title_id, ticket_size; + uint32_t seed, title_id; buffer.read_uint32(&seed); buffer.read_uint32(&title_id); @@ -23,7 +23,7 @@ namespace demonware buffer.read_bytes(sizeof(rsa_key), rsa_key); uint8_t ticket[1024]; - buffer.read_bytes(std::min(ticket_size, static_cast(sizeof(ticket))), ticket); + buffer.read_bytes(sizeof(ticket), ticket); game::native::bdAuthTicket auth_ticket{}; std::memset(&auth_ticket, 0xA, sizeof auth_ticket); diff --git a/src/game/game.cpp b/src/game/game.cpp index f666e36..194109d 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -105,6 +105,8 @@ namespace game DeferredQueue* deferredQueue; + float* com_codeTimeScale; + namespace mp { SV_GetGuid_t SV_GetGuid; @@ -306,7 +308,7 @@ namespace game dvar_value.value = value; - return dvar_register_variant_dedicated(dvarName, dvar_type::DVAR_TYPE_FLOAT, + return dvar_register_variant_dedicated(dvarName, DVAR_TYPE_FLOAT, flags, dvar_value, domain, description); } @@ -819,5 +821,7 @@ namespace game native::level = reinterpret_cast(SELECT_VALUE(0x0, 0x1C6D4D8, 0x1B21A20)); native::deferredQueue = reinterpret_cast(SELECT_VALUE(0x0, 0x1D55438, 0x0)); + + native::com_codeTimeScale = reinterpret_cast(SELECT_VALUE(0x1769F1C, 0x1CEF554, 0x1B9CEC0)); } } diff --git a/src/game/game.hpp b/src/game/game.hpp index 5e3f0c8..1917f9e 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -186,6 +186,8 @@ namespace game extern DeferredQueue* deferredQueue; + extern float* com_codeTimeScale; + // PM Global Definitions & Functions constexpr auto JUMP_LAND_SLOWDOWN_TIME = 1800; diff --git a/src/game/structs.hpp b/src/game/structs.hpp index 8536b94..3035749 100644 --- a/src/game/structs.hpp +++ b/src/game/structs.hpp @@ -610,9 +610,10 @@ namespace game DVAR_CHEAT = 1 << 2, DVAR_CODINFO = 1 << 3, DVAR_SCRIPTINFO = 1 << 4, + DVAR_SAVED = 1 << 6, DVAR_SERVERINFO = 1 << 10, - DVAR_WRITEPROTECTED = 1 << 11, - DVAR_READONLY = 1 << 13, + DVAR_INIT = 1 << 11, + DVAR_ROM = 1 << 13, DVAR_AUTOEXEC = 1 << 15, }; // Incomplete diff --git a/src/module/fov.cpp b/src/module/fov.cpp index 5fca813..95e5693 100644 --- a/src/module/fov.cpp +++ b/src/module/fov.cpp @@ -12,7 +12,7 @@ public: if (game::is_dedi()) return; // Set dvar flag - utils::hook::set(SELECT_VALUE(0x4302C5, 0x455155, 0), 0x1 | (game::is_mp() ? 0x40 : 0)); + utils::hook::set(SELECT_VALUE(0x4302C5, 0x455155, 0), game::native::DVAR_ARCHIVE | (game::is_mp() ? game::native::DVAR_SAVED : 0)); if (game::is_mp()) { @@ -26,12 +26,16 @@ public: } private: - static void set_server_command_dvar_stub(const char* dvar, const char* value) + static void set_server_command_dvar_stub(const char* dvar_name, const char* value) { - if (strcmp(dvar, "cg_fov") != 0) + const auto* dvar = game::native::Dvar_FindVar(dvar_name); + if (dvar != nullptr && ((dvar->flags & game::native::DVAR_ARCHIVE) != 0)) { - game::native::Dvar_SetFromStringByName(dvar, value); + printf("Not allowing server to override archive dvar '%s'\n", dvar_name); + return; } + + game::native::Dvar_SetFromStringByName(dvar_name, value); } }; diff --git a/src/module/gameplay.cpp b/src/module/gameplay.cpp new file mode 100644 index 0000000..fe4e587 --- /dev/null +++ b/src/module/gameplay.cpp @@ -0,0 +1,74 @@ +#include +#include +#include + +#include "game/game.hpp" + +static const game::native::dvar_t** com_fixedtime = nullptr; + +static const game::native::dvar_t* com_timescale = nullptr; +static const game::native::dvar_t* dev_timescale = nullptr; + +static const game::native::dvar_t* dvar_register_com_timescale(const char* dvar_name, float value, + float min, float max, unsigned __int16 /*flags*/, const char* description) +{ + // Remove DVAR_ROM & DVAR_CHEAT + com_timescale = game::native::Dvar_RegisterFloat(dvar_name, value, + min, max, game::native::DVAR_CODINFO | game::native::DVAR_SAVED, description); + + return com_timescale; +} + +static const game::native::dvar_t* dvar_register_dev_timescale(const char* dvar_name, float value, + float min, float max, unsigned __int16 /*flags*/, const char* description) +{ + // Remove DVAR_CHEAT + dev_timescale = game::native::Dvar_RegisterFloat(dvar_name, value, + min, max, game::native::DVAR_CODINFO, description); + + return dev_timescale; +} + +static float com_get_timescale_for_snd() +{ + const auto fixed_time = (*com_fixedtime)->current.integer; + if (fixed_time != 0) + { + return static_cast(fixed_time); + } + + return dev_timescale->current.value * com_timescale->current.value; +} + +static float com_get_timescale_for_sv() +{ + assert(com_timescale != nullptr); + + if (dev_timescale->current.value == 1.0f && com_timescale->current.value == 1.0f + && *game::native::com_codeTimeScale == 1.0f) + { + return 1.0f; + } + + return dev_timescale->current.value * com_timescale->current.value * (*game::native::com_codeTimeScale); +} + +class gameplay final : public module +{ +public: + void post_load() override + { + // com_timescale && timescale are already implemented on SP + if (game::is_mp()) + { + com_fixedtime = reinterpret_cast(0x1CEF568); + utils::hook(0x55419F, &dvar_register_com_timescale, HOOK_CALL).install()->quick(); + utils::hook(0x5541CF, &dvar_register_dev_timescale, HOOK_CALL).install()->quick(); + + utils::hook(0x6C66CB, &com_get_timescale_for_snd, HOOK_CALL).install()->quick(); + utils::hook(0x6A71E0, &com_get_timescale_for_sv, HOOK_JUMP).install()->quick(); + } + } +}; + +REGISTER_MODULE(gameplay) diff --git a/src/module/player_movement.cpp b/src/module/player_movement.cpp index 1235f8f..f341dc4 100644 --- a/src/module/player_movement.cpp +++ b/src/module/player_movement.cpp @@ -316,9 +316,7 @@ void player_movement::pm_project_velocity_stub(const float* vel_in, const float* if (std::fabsf(normal[2]) < 0.001f || length_squared_2d == 0.0f) { - vel_out[0] = vel_in[0]; - vel_out[1] = vel_in[1]; - vel_out[2] = vel_in[2]; + std::memcpy(vel_out, vel_in, sizeof(std::float_t[3])); return; } @@ -590,7 +588,7 @@ void player_movement::patch_sp() void player_movement::register_common_dvars() { - // Pm dvars + // pm dvars pm_bounces = game::native::Dvar_RegisterBool("pm_bounces", false, game::native::DVAR_CODINFO, "CoD4 Bounces"); pm_bouncesAllAngles = game::native::Dvar_RegisterBool("pm_bouncesAllAngles", false,