diff --git a/src/Cheats.cpp b/src/Cheats.cpp index 994394a1..4d6b6336 100644 --- a/src/Cheats.cpp +++ b/src/Cheats.cpp @@ -52,6 +52,7 @@ Variable sar_disable_weapon_sway("sar_disable_weapon_sway", "0", 0, 1, "Disables Variable sar_disable_viewmodel_shadows("sar_disable_viewmodel_shadows", "0", 0, 1, "Disables the shadows on the viewmodel.\n"); Variable sar_floor_reportals("sar_floor_reportals", "0", "Toggles floor reportals. Requires cheats.\n", FCVAR_CHEAT); Variable sar_loads_coop_dots("sar_loads_coop_dots", "0", "Toggles the loading screen dots during map transitions in coop.\n"); +Variable sar_disable_autograb("sar_disable_autograb", "0", 0, 1, "Disables the auto-grab in coop. Requires host to enable it for everyone that also enables it.\n"); Variable sv_laser_cube_autoaim; Variable ui_loadingscreen_transition_time; @@ -323,6 +324,8 @@ CON_COMMAND_F(sar_challenge_autosubmit_reload_api_key, "sar_challenge_autosubmit Memory::Patch *g_floorReportalPatch; Memory::Patch *g_coopLoadingDotsPatch; +Memory::Patch *g_autoGrabPatchServer; +Memory::Patch *g_autoGrabPatchClient; void Cheats::Init() { sv_laser_cube_autoaim = Variable("sv_laser_cube_autoaim"); @@ -379,6 +382,18 @@ void Cheats::Init() { g_coopLoadingDotsPatch->Restore(); } + g_autoGrabPatchServer = new Memory::Patch(); + g_autoGrabPatchClient = new Memory::Patch(); + auto autoGrabServerBranch = Memory::Scan(MODULE("server"), Offsets::CPortal_Player__PollForUseEntity_CheckMP); + auto autoGrabClientBranch = Memory::Scan(MODULE("client"), Offsets::CPortal_Player__PollForUseEntity_CheckMP); // Note: Same signature as the server. + if (autoGrabServerBranch && autoGrabClientBranch) { + unsigned char autoGrabBranchByte = 0xEB; + g_autoGrabPatchServer->Execute(autoGrabServerBranch, &autoGrabBranchByte, 1); + g_autoGrabPatchServer->Restore(); + g_autoGrabPatchClient->Execute(autoGrabClientBranch, &autoGrabBranchByte, 1); + g_autoGrabPatchClient->Restore(); + } + Variable::RegisterAll(); Command::RegisterAll(); } @@ -398,6 +413,10 @@ void Cheats::Shutdown() { SAFE_DELETE(g_floorReportalPatch); g_coopLoadingDotsPatch->Restore(); SAFE_DELETE(g_coopLoadingDotsPatch); + g_autoGrabPatchServer->Restore(); + SAFE_DELETE(g_autoGrabPatchServer); + g_autoGrabPatchClient->Restore(); + SAFE_DELETE(g_autoGrabPatchClient); } @@ -534,3 +553,34 @@ void Cheats::CheckUICoopDots() { g_coopLoadingDotsPatch->Restore(); } } + +void Cheats::CheckAutoGrab() { + bool enabled = sar_disable_autograb.GetBool(); + if (enabled && (!g_autoGrabPatchServer || !g_autoGrabPatchServer->IsInit())) { + console->Print("sar_disable_autograb is not available (Server).\n"); + sar_disable_autograb.SetValue(0); + return; + } + if (enabled && (!g_autoGrabPatchClient || !g_autoGrabPatchClient->IsInit())) { + console->Print("sar_disable_autograb is not available (Client).\n"); + sar_disable_autograb.SetValue(0); + return; + } + if (!sv_cheats.GetBool() && enabled) { + console->Print("sar_disable_autograb requires sv_cheats 1.\n"); + sar_disable_autograb.SetValue(0); + enabled = false; + } + + if (enabled == g_autoGrabPatchServer->IsPatched() && enabled == g_autoGrabPatchClient->IsPatched()) { + return; + } + + if (enabled) { + g_autoGrabPatchServer->Execute(); + g_autoGrabPatchClient->Execute(); + } else { + g_autoGrabPatchServer->Restore(); + g_autoGrabPatchClient->Restore(); + } +} diff --git a/src/Cheats.hpp b/src/Cheats.hpp index c2db46c3..28141e5e 100644 --- a/src/Cheats.hpp +++ b/src/Cheats.hpp @@ -12,6 +12,7 @@ class Cheats { static void EnsureSlopeBoost(const CHLMoveData *move, void *player, CGameTrace **tr); static void CheckFloorReportals(); static void CheckUICoopDots(); + static void CheckAutoGrab(); }; extern Variable sar_autorecord; @@ -35,6 +36,7 @@ extern Variable sar_disable_weapon_sway; extern Variable sar_disable_viewmodel_shadows; extern Variable sar_floor_reportals; extern Variable sar_loads_coop_dots; +extern Variable sar_disable_autograb; extern Variable sv_laser_cube_autoaim; extern Variable ui_loadingscreen_transition_time; diff --git a/src/Modules/Server.cpp b/src/Modules/Server.cpp index ec9afe2f..fbf2a8cf 100644 --- a/src/Modules/Server.cpp +++ b/src/Modules/Server.cpp @@ -286,6 +286,7 @@ DETOUR(Server::PlayerRunCommand, CUserCmd *cmd, void *moveHelper) { Cheats::AutoStrafe(slot, thisptr, cmd); Cheats::CheckFloorReportals(); Cheats::CheckUICoopDots(); + Cheats::CheckAutoGrab(); inputHud.SetInputInfo(slot, cmd->buttons, {cmd->sidemove, cmd->forwardmove, cmd->upmove}); diff --git a/src/Offsets/Portal 2 9568.hpp b/src/Offsets/Portal 2 9568.hpp index f8cbbac9..31c8b54d 100644 --- a/src/Offsets/Portal 2 9568.hpp +++ b/src/Offsets/Portal 2 9568.hpp @@ -512,6 +512,9 @@ OFFSET_DEFAULT(aircontrol_fling_speedOff, 3, 3) SIGSCAN_DEFAULT(FloorReportalBranch, "75 7D 8B 8E C0 04 00 00", "75 ? 8B 85 ? ? ? ? 8B 0D") // "Portal.open_red" xref(nothing after if) -> CProp_Portal::NewLocation -> first function call CPortal_Base2D::NewLocation -> 4x func call followed by test, [jnz] +// TODO: Linux Support +SIGSCAN_DEFAULT(CPortal_Player__PollForUseEntity_CheckMP, "74 ? ? ? 8B 82 ? ? ? ? FF D0 84 C0 74 ? 8B CE", + "") // CPortal_Player vtable -> Add offset 0x6D8 -> CPortal_Player::PlayerUse -> Second function call from disassembly -> CPortal_Player::PollForUseEntity -> jz instruction // VPhysics OFFSET_EMPTY(DestroyEnvironment)