From 8985076bc2b151f7a1c9e2ac1687048d47af3bab Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 15 Mar 2022 14:48:19 +0000 Subject: [PATCH 1/4] Elevators & more --- src/game/game.cpp | 13 +++++++ src/game/game.hpp | 12 +++++++ src/game/structs.hpp | 65 +++++++++++++++++++++++++++++++++- src/module/player_movement.cpp | 64 +++++++++++++++++++++++++++++++++ src/module/player_movement.hpp | 13 +++++++ 5 files changed, 166 insertions(+), 1 deletion(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index 901758a..e7525dc 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -65,6 +65,12 @@ namespace game CM_TransformedCapsuleTrace_t CM_TransformedCapsuleTrace; + Weapon_RocketLauncher_Fire_t Weapon_RocketLauncher_Fire; + + PM_playerTrace_t PM_playerTrace; + + PM_trace_t PM_trace; + Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand; decltype(longjmp)* _longjmp; @@ -669,6 +675,13 @@ namespace game native::CM_TransformedCapsuleTrace = native::CM_TransformedCapsuleTrace_t( SELECT_VALUE(0x4F9B80, 0x541340, 0x0)); + native::Weapon_RocketLauncher_Fire = native::Weapon_RocketLauncher_Fire_t( + SELECT_VALUE(0x48C920, 0x5305D0, 0x0)); + + native::PM_playerTrace = native::PM_playerTrace_t(SELECT_VALUE(0x4CE600, 0x421F00, 0x0)); + + native::PM_trace = native::PM_trace_t(SELECT_VALUE(0x544BF0, 0x41CEB0, 0x0)); + native::Cmd_ExecuteSingleCommand = native::Cmd_ExecuteSingleCommand_t( SELECT_VALUE(0x4D6960, 0x5462B0, 0x4CC360)); diff --git a/src/game/game.hpp b/src/game/game.hpp index e662c9e..6334e11 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -105,6 +105,18 @@ namespace game const float* origin, const float* angles); extern CM_TransformedCapsuleTrace_t CM_TransformedCapsuleTrace; + typedef gentity_s* (*Weapon_RocketLauncher_Fire_t)(gentity_s* ent, const Weapon weapon, float spread, + weaponParms* wp, const float* gunVel, missileFireParms* fireParms, missileFireParms* magicBullet); + extern Weapon_RocketLauncher_Fire_t Weapon_RocketLauncher_Fire; + + typedef void (*PM_playerTrace_t)(pmove_t* pm, trace_t* results, const float* start, const float* end, + const Bounds* bounds, int passEntityNum, int contentMask); + extern PM_playerTrace_t PM_playerTrace; + + typedef void (*PM_trace_t)(const pmove_t* pm, trace_t* results, const float* start, const float* end, + const Bounds* bounds, int passEntityNum, int contentMask); + extern PM_trace_t PM_trace; + typedef void (*Cmd_ExecuteSingleCommand_t)(LocalClientNum_t localClientNum, int controllerIndex, const char* text); extern Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand; diff --git a/src/game/structs.hpp b/src/game/structs.hpp index 7c96b1a..351ad99 100644 --- a/src/game/structs.hpp +++ b/src/game/structs.hpp @@ -709,6 +709,21 @@ namespace game static_assert(sizeof(Weapon) == 4); + struct weaponParms + { + float forward[3]; + float right[3]; + float up[3]; + float muzzleTrace[3]; + float gunForward[3]; + Weapon weapon; + bool isAlternate; + const void* weapDef; + const void* weapCompleteDef; + }; + + static_assert(sizeof(weaponParms) == 0x4C); + enum ViewLockTypes { PLAYERVIEWLOCK_NONE = 0x0, @@ -745,12 +760,49 @@ namespace game struct playerState_s { - unsigned char __pad0[0x4EC]; + int commandTime; + int pm_type; + int pm_time; + int pm_flags; + int otherFlags; + int linkFlags; + int bobCycle; + float origin[3]; + float velocity[3]; + unsigned char __pad0[0x4B8]; unsigned int perks[0x2]; unsigned int perkSlots[0x9]; unsigned char __pad1[0x2DE8]; }; + static_assert(sizeof(playerState_s) == 0x3300); + + struct pmove_t + { + playerState_s* ps; + usercmd_s cmd; + usercmd_s oldcmd; + int tracemask; + int numtouch; + int touchents[32]; + Bounds bounds; + float speed; + int proneChange; + float maxSprintTimeMultiplier; + bool mantleStarted; + float mantleEndPos[3]; + int mantleDuration; + int viewChangeTime; + float viewChange; + float fTorsoPitch; + float fWaistPitch; + int remoteTurretFireTime; + int lastUpdateCMDServerTime; + unsigned char handler; + }; + + static_assert(sizeof(pmove_t) == 0x138); + struct gclient_s { playerState_s ps; @@ -835,6 +887,17 @@ namespace game static_assert(sizeof(gentity_s) == 0x274); + struct missileFireParms + { + gentity_s* target; + float targetPosOrOffset[3]; + float autoDetonateTime; + bool lockon; + bool topFire; + }; + + static_assert(sizeof(missileFireParms) == 0x18); + enum clientState_t { CS_FREE = 0, diff --git a/src/module/player_movement.cpp b/src/module/player_movement.cpp index d49e8a5..fe07cb6 100644 --- a/src/module/player_movement.cpp +++ b/src/module/player_movement.cpp @@ -7,6 +7,8 @@ const game::native::dvar_t* player_movement::player_sustainAmmo; const game::native::dvar_t* player_movement::pm_bounces; const game::native::dvar_t* player_movement::pm_playerEjection; const game::native::dvar_t* player_movement::pm_playerCollision; +const game::native::dvar_t* player_movement::pm_rocketJump; +const game::native::dvar_t* player_movement::pm_elevators; void player_movement::pm_weapon_use_ammo(game::native::playerState_s* ps, const game::native::Weapon weapon, bool is_alternate, int amount, game::native::PlayerHandIndex hand) @@ -92,6 +94,45 @@ void player_movement::cm_transformed_capsule_trace_stub(game::native::trace_t* r } } +game::native::gentity_s* player_movement::weapon_rocket_launcher_fire_stub(game::native::gentity_s* ent, + const game::native::Weapon weapon, float spread, game::native::weaponParms* wp, const float* gun_vel, + game::native::missileFireParms* fire_parms, game::native::missileFireParms* magic_bullet) +{ + auto* result = game::native::Weapon_RocketLauncher_Fire(ent, weapon, spread, wp, + gun_vel, fire_parms, magic_bullet); + + if (ent->client != nullptr && player_movement::pm_rocketJump->current.enabled) + { + ent->client->ps.velocity[0] += (0 - wp->forward[0]) * 64.0f; + ent->client->ps.velocity[1] += (0 - wp->forward[1]) * 64.0f; + ent->client->ps.velocity[2] += (0 - wp->forward[2]) * 64.0f; + } + + return result; +} + +void player_movement::pm_player_trace_stub(game::native::pmove_t* pm, game::native::trace_t* results, + const float* start, const float* end, const game::native::Bounds* bounds, int pass_entity_num, int content_mask) +{ + game::native::PM_playerTrace(pm, results, start, end, bounds, pass_entity_num, content_mask); + + if (player_movement::pm_elevators->current.enabled) + { + results->startsolid = false; + } +} + +void player_movement::pm_trace(const game::native::pmove_t* pm, game::native::trace_t* results, + const float* start, const float* end, const game::native::Bounds* bounds, int pass_entity_num, int content_mask) +{ + game::native::PM_trace(pm, results, start, end, bounds, pass_entity_num, content_mask); + + if (player_movement::pm_elevators->current.enabled) + { + results->allsolid = false; + } +} + const game::native::dvar_t* player_movement::dvar_register_player_sustain_ammo(const char* dvar_name, bool value, unsigned __int16 /*flags*/, const char* description) { @@ -105,6 +146,8 @@ void player_movement::patch_mp() { player_movement::pm_playerEjection = game::native::Dvar_RegisterBool("pm_playerEjection", true, game::native::DVAR_CODINFO, "Push intersecting players away from each other"); + player_movement::pm_rocketJump = game::native::Dvar_RegisterBool("pm_rocketJump", + false, game::native::DVAR_CODINFO, "CoD4 rocket jumps"); utils::hook(0x418D9C, &player_movement::dvar_register_player_sustain_ammo, HOOK_CALL).install()->quick(); @@ -117,6 +160,15 @@ void player_movement::patch_mp() utils::hook(0x4F9EFB, &player_movement::stuck_in_client_stub, HOOK_CALL).install()->quick(); // ClientEndFrame utils::hook(0x57CF45, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity utils::hook(0x482C1B, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity + + utils::hook(0x530CCB, &player_movement::weapon_rocket_launcher_fire_stub, HOOK_CALL).install()->quick(); // FireWeapon + + utils::hook(0x422861, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint + utils::hook(0x4228B5, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint + + utils::hook(0x41F995, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x41F8D8, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x41F941, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck } void player_movement::patch_sp() @@ -132,10 +184,20 @@ void player_movement::patch_sp() utils::hook(0x41F9A6, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // SV_ClipMoveToEntity utils::hook(0x57B14F, &player_movement::cm_transformed_capsule_trace_stub, HOOK_CALL).install()->quick(); // CG_ClipMoveToEntity + + utils::hook(0x643F84, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint + utils::hook(0x643FDB, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint + + utils::hook(0x64181A, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x641701, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x6417A9, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck } void player_movement::post_load() { + // Un-cheat missileMacross. It seems it retained its functionality + utils::hook::set(SELECT_VALUE(0x44DFED, 0x50DDDD, 0x48C16F), 0x0); + if (game::is_dedi()) { return; @@ -145,6 +207,8 @@ void player_movement::post_load() game::native::dvar_flags::DVAR_CODINFO, "CoD4 Bounces"); player_movement::pm_playerCollision = game::native::Dvar_RegisterBool("pm_playerCollision", true, game::native::DVAR_CODINFO, "Push intersecting players away from each other"); + player_movement::pm_elevators = game::native::Dvar_RegisterBool("pm_elevators", + false, game::native::DVAR_CODINFO, "CoD4 Elevators"); if (game::is_mp()) this->patch_mp(); else if (game::is_sp()) this->patch_sp(); diff --git a/src/module/player_movement.hpp b/src/module/player_movement.hpp index 5d0b6ac..02f9abc 100644 --- a/src/module/player_movement.hpp +++ b/src/module/player_movement.hpp @@ -12,6 +12,8 @@ private: static const game::native::dvar_t* pm_bounces; static const game::native::dvar_t* pm_playerEjection; static const game::native::dvar_t* pm_playerCollision; + static const game::native::dvar_t* pm_rocketJump; + static const game::native::dvar_t* pm_elevators; static void pm_weapon_use_ammo(game::native::playerState_s* ps, const game::native::Weapon weapon, bool isAlternate, int amount, game::native::PlayerHandIndex hand); @@ -27,6 +29,17 @@ private: const float* end, const game::native::Bounds* bounds, const game::native::Bounds* capsule, int contents, const float* origin, const float* angles); + static game::native::gentity_s* weapon_rocket_launcher_fire_stub(game::native::gentity_s* ent, + const game::native::Weapon weapon, float spread, game::native::weaponParms* wp, + const float* gun_vel, game::native::missileFireParms* fire_parms, game::native::missileFireParms* magic_bullet); + + static void pm_player_trace_stub(game::native::pmove_t* pm, game::native::trace_t* results, + const float* start, const float* end, const game::native::Bounds* bounds, + int pass_entity_num, int content_mask); + + static void pm_trace(const game::native::pmove_t* pm, game::native::trace_t* results, + const float* start, const float* end, const game::native::Bounds* bounds, int pass_entity_num, int content_mask); + static void patch_mp(); static void patch_sp(); }; From eb3198f70065bf04d77bbfb66fc0cff6c2922760 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 15 Mar 2022 14:59:24 +0000 Subject: [PATCH 2/4] rename pm_trace to pm_trace_stub --- src/module/player_movement.cpp | 14 +++++++------- src/module/player_movement.hpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/module/player_movement.cpp b/src/module/player_movement.cpp index fe07cb6..65c2654 100644 --- a/src/module/player_movement.cpp +++ b/src/module/player_movement.cpp @@ -122,7 +122,7 @@ void player_movement::pm_player_trace_stub(game::native::pmove_t* pm, game::nati } } -void player_movement::pm_trace(const game::native::pmove_t* pm, game::native::trace_t* results, +void player_movement::pm_trace_stub(const game::native::pmove_t* pm, game::native::trace_t* results, const float* start, const float* end, const game::native::Bounds* bounds, int pass_entity_num, int content_mask) { game::native::PM_trace(pm, results, start, end, bounds, pass_entity_num, content_mask); @@ -166,9 +166,9 @@ void player_movement::patch_mp() utils::hook(0x422861, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint utils::hook(0x4228B5, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint - utils::hook(0x41F995, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck - utils::hook(0x41F8D8, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck - utils::hook(0x41F941, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x41F995, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x41F8D8, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x41F941, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck } void player_movement::patch_sp() @@ -188,9 +188,9 @@ void player_movement::patch_sp() utils::hook(0x643F84, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint utils::hook(0x643FDB, &player_movement::pm_player_trace_stub, HOOK_CALL).install()->quick(); // PM_JitterPoint - utils::hook(0x64181A, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck - utils::hook(0x641701, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck - utils::hook(0x6417A9, &player_movement::pm_trace, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x64181A, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x641701, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck + utils::hook(0x6417A9, &player_movement::pm_trace_stub, HOOK_CALL).install()->quick(); // PM_CheckDuck } void player_movement::post_load() diff --git a/src/module/player_movement.hpp b/src/module/player_movement.hpp index 02f9abc..c105c30 100644 --- a/src/module/player_movement.hpp +++ b/src/module/player_movement.hpp @@ -37,7 +37,7 @@ private: const float* start, const float* end, const game::native::Bounds* bounds, int pass_entity_num, int content_mask); - static void pm_trace(const game::native::pmove_t* pm, game::native::trace_t* results, + static void pm_trace_stub(const game::native::pmove_t* pm, game::native::trace_t* results, const float* start, const float* end, const game::native::Bounds* bounds, int pass_entity_num, int content_mask); static void patch_mp(); From 8b4b63f3cc8fb123764b058caf4cce833b72ab49 Mon Sep 17 00:00:00 2001 From: FutureRave Date: Tue, 15 Mar 2022 15:41:51 +0000 Subject: [PATCH 3/4] Also add quit to mp & sp --- src/game/game.cpp | 4 ++++ src/game/game.hpp | 3 +++ src/module/command.cpp | 12 ++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/game/game.cpp b/src/game/game.cpp index e7525dc..9ce3ab2 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -73,6 +73,8 @@ namespace game Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand; + Com_Quit_f_t Com_Quit_f; + decltype(longjmp)* _longjmp; CmdArgs* sv_cmd_args; @@ -685,6 +687,8 @@ namespace game native::Cmd_ExecuteSingleCommand = native::Cmd_ExecuteSingleCommand_t( SELECT_VALUE(0x4D6960, 0x5462B0, 0x4CC360)); + native::Com_Quit_f = native::Com_Quit_f_t(SELECT_VALUE(0x4F48B0, 0x5556B0, 0x4D95B0)); + native::_longjmp = reinterpret_cast(SELECT_VALUE(0x73AC20, 0x7363BC, 0x655558)); native::sv_cmd_args = reinterpret_cast(SELECT_VALUE(0x1757218, 0x1CAA998, 0x1B5E7D8)); diff --git a/src/game/game.hpp b/src/game/game.hpp index 6334e11..2f1d5c9 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -120,6 +120,9 @@ namespace game typedef void (*Cmd_ExecuteSingleCommand_t)(LocalClientNum_t localClientNum, int controllerIndex, const char* text); extern Cmd_ExecuteSingleCommand_t Cmd_ExecuteSingleCommand; + typedef void (*Com_Quit_f_t)(); + extern Com_Quit_f_t Com_Quit_f; + extern decltype(longjmp)* _longjmp; constexpr auto CMD_MAX_NESTING = 8; diff --git a/src/module/command.cpp b/src/module/command.cpp index 912a971..2b4e78a 100644 --- a/src/module/command.cpp +++ b/src/module/command.cpp @@ -323,14 +323,18 @@ void command::add_sp_commands() void command::post_load() { + if (game::is_dedi()) + { + utils::hook(0x4F96B5, &command::client_command_dedi_stub, HOOK_CALL).install()->quick(); // SV_ExecuteClientCommand + return; + } + + add("quit", game::native::Com_Quit_f); + if (game::is_mp()) { utils::hook(0x57192A, &command::client_command_stub, HOOK_CALL).install()->quick(); // SV_ExecuteClientCommand } - else if (game::is_dedi()) - { - utils::hook(0x4F96B5, &command::client_command_dedi_stub, HOOK_CALL).install()->quick(); // SV_ExecuteClientCommand - } else { utils::hook(0x44BB50, &command::client_command_sp_stub, HOOK_JUMP).install()->quick(); From d1ae131717e4f7f1d54f4c4f5ea6615e3fa441de Mon Sep 17 00:00:00 2001 From: Edo Date: Tue, 15 Mar 2022 18:34:27 +0000 Subject: [PATCH 4/4] Use latest actions/checkout version Why not --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9afe1d6..de3a770 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Check out files - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: true fetch-depth: 0