From fc4d36ceb6d9dbdfbb5dd53aeb0713352801b021 Mon Sep 17 00:00:00 2001 From: Forgetest <33988868+jensewe@users.noreply.github.com> Date: Wed, 25 Mar 2026 01:02:56 +0800 Subject: [PATCH 1/3] Add `l4d_fix_rocket_jump` --- .../gamedata/l4d_fix_rocket_jump.txt | 72 ++++++++ .../scripting/l4d_fix_rocket_jump.sp | 154 ++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 addons/sourcemod/gamedata/l4d_fix_rocket_jump.txt create mode 100644 addons/sourcemod/scripting/l4d_fix_rocket_jump.sp diff --git a/addons/sourcemod/gamedata/l4d_fix_rocket_jump.txt b/addons/sourcemod/gamedata/l4d_fix_rocket_jump.txt new file mode 100644 index 000000000..53186b32f --- /dev/null +++ b/addons/sourcemod/gamedata/l4d_fix_rocket_jump.txt @@ -0,0 +1,72 @@ +"Games" +{ + "#default" + { + "Functions" + { + "CGameMovement::SetGroundEntity" + { + "signature" "CGameMovement::SetGroundEntity" + "linux" + { + "callconv" "cdecl" + } + "windows" + { + "callconv" "stdcall" + } + "return" "void" + "arguments" + { + "this" + { + "type" "objectptr" + "windows" + { + "register" "ecx" + } + } + "a1" + { + "type" "objectptr" + } + } + } + } + + "Signatures" + { + "CGameMovement::SetGroundEntity" + { + "library" "server" + "linux" "@_ZN13CGameMovement15SetGroundEntityEP10CGameTrace" + } + } + } + + "left4dead" + { + "Signatures" + { + "CGameMovement::SetGroundEntity" + { + "library" "server" + "windows" "\x83\xEC\x0C\x53\x55\x8B\x6C\x24\x18\x85\xED\x56\x8B\xD9" + // 83 EC 0C 53 55 8B 6C 24 18 85 ED 56 8B D9 + } + } + } + + "left4dead2" + { + "Signatures" + { + "CGameMovement::SetGroundEntity" + { + "library" "server" + "windows" "\x55\x8B\xEC\x8B\x45\x08\x83\xEC\x0C\x53\x56\x57\x8B\xF9" + // 55 8B EC 8B 45 08 83 EC 0C 53 56 57 8B F9 + } + } + } +} \ No newline at end of file diff --git a/addons/sourcemod/scripting/l4d_fix_rocket_jump.sp b/addons/sourcemod/scripting/l4d_fix_rocket_jump.sp new file mode 100644 index 000000000..93a0c8753 --- /dev/null +++ b/addons/sourcemod/scripting/l4d_fix_rocket_jump.sp @@ -0,0 +1,154 @@ +#pragma semicolon 1 +#pragma newdecls required + +#include +#include + +#define PLUGIN_VERSION "1.0" + +public Plugin myinfo = +{ + name = "[L4D & 2] Fix Rocket Jump", + author = "Forgetest", + description = "Fix some \"grounds\" launching survivors into the air.", + version = PLUGIN_VERSION, + url = "https://github.com/Target5150/MoYu_Server_Stupid_Plugins", +} + +methodmap GameDataWrapper < GameData { + public GameDataWrapper(const char[] file) { + GameData gd = new GameData(file); + if (!gd) SetFailState("Missing gamedata \"%s\"", file); + return view_as(gd); + } + public DynamicDetour CreateDetourOrFail( + const char[] name, + DHookCallback preHook = INVALID_FUNCTION, + DHookCallback postHook = INVALID_FUNCTION) { + DynamicDetour hSetup = DynamicDetour.FromConf(this, name); + if (!hSetup) + SetFailState("Missing detour setup \"%s\"", name); + if (preHook != INVALID_FUNCTION && !hSetup.Enable(Hook_Pre, preHook)) + SetFailState("Failed to pre-detour \"%s\"", name); + if (postHook != INVALID_FUNCTION && !hSetup.Enable(Hook_Post, postHook)) + SetFailState("Failed to post-detour \"%s\"", name); + return hSetup; + } +} + +public void OnPluginStart() +{ + GameDataWrapper gd = new GameDataWrapper("l4d_fix_rocket_jump"); + delete gd.CreateDetourOrFail("CGameMovement::SetGroundEntity", DTR_SetGroundEntity, DTR_SetGroundEntity_Post); + delete gd; +} + +// https://github.com/ValveSoftware/source-sdk-2013/blob/39f6dde8fbc238727c020d13b05ecadd31bda4c0/src/game/shared/gamemovement.cpp#L3611 +static bool g_bRestore[MAXPLAYERS+1]; +static float g_vecSavedBaseVel[MAXPLAYERS+1][3]; +MRESReturn DTR_SetGroundEntity(DHookParam hParams) +{ + int client = hParams.GetObjectVar(1, 4, ObjectValueType_CBaseEntityPtr); + + int oldground = GetEntPropEnt(client, Prop_Send, "m_hGroundEntity"); + int newground = !hParams.IsNull(2) ? hParams.GetObjectVar(2, 76, ObjectValueType_CBaseEntityPtr) : -1; + + g_bRestore[client] = false; + + if ((oldground == -1 && newground != -1) || (oldground != -1 && newground == -1)) + { + g_bRestore[client] = !PassStandableGround(client, newground == -1 ? oldground : newground); + } + + if (g_bRestore[client]) + { + GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", g_vecSavedBaseVel[client]); + } + + return MRES_Ignored; +} + +MRESReturn DTR_SetGroundEntity_Post(DHookParam hParams) +{ + int client = hParams.GetObjectVar(1, 4, ObjectValueType_CBaseEntityPtr); + + if (g_bRestore[client]) + { + SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", g_vecSavedBaseVel[client]); + } + + return MRES_Ignored; +} + +bool PassStandableGround(int client, int entity) +{ + if (entity > MaxClients) + { + char cls[64]; + GetEntityClassname(entity, cls, sizeof(cls)); + + if (!strcmp(cls, "witch") || !strcmp(cls, "infected")) + return false; + + if (StrContains(cls, "_projectile") != -1) + return false; + } + else if (entity > 0) + { + if (GetClientTeam(client) == 2 && GetClientTeam(entity) == 3) + return false; + } + + return true; +} + +// Reverse bot's aim pitch for solo testing GL jump with "bot_mimic" on. +/* +#include + +methodmap CUserCmd +{ + property float viewangles_x { + public get() { return LoadFromAddress(view_as
(this) + view_as
(12), NumberType_Int32); } + public set(float x) { StoreToAddress(view_as
(this) + view_as
(12), x, NumberType_Int32); } + } +} + +int g_iRestoreMimic = -1; +public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2]) +{ + static ConVar bot_mimic = null; + if (bot_mimic == null) + bot_mimic = FindConVar("bot_mimic"); + + if (!IsClientInGame(client) || !IsFakeClient(client)) + return Plugin_Continue; + + int player = bot_mimic.IntValue; + if (player <= 0 || player > MaxClients || !IsClientInGame(player)) + return Plugin_Continue; + + g_iRestoreMimic = player; + GetPlayerLastCommand(player).viewangles_x = -GetPlayerLastCommand(player).viewangles_x; + return Plugin_Continue; +} + +public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2]) +{ + if (g_iRestoreMimic != -1) + { + GetPlayerLastCommand(g_iRestoreMimic).viewangles_x = -GetPlayerLastCommand(g_iRestoreMimic).viewangles_x; + g_iRestoreMimic = -1; + } +} + +CUserCmd GetPlayerLastCommand(int player) +{ + static int s_iOffs_m_LastCmd = -1; + if (s_iOffs_m_LastCmd == -1) + s_iOffs_m_LastCmd = FindDataMapInfo(player, "m_hViewModel") + + 4*2; // CHandle * MAX_VIEWMODELS + + return view_as(GetEntityAddress(player) + view_as
(s_iOffs_m_LastCmd)); +} +*/ \ No newline at end of file From 79fc5bd086914b132fcb62e25a10379c0c2b91b6 Mon Sep 17 00:00:00 2001 From: Forgetest <33988868+jensewe@users.noreply.github.com> Date: Wed, 25 Mar 2026 01:04:09 +0800 Subject: [PATCH 2/3] Archive old `l4d2_fix_rocketjump` --- .../plugins/fixes/l4d2_fix_rocketjump.smx | Bin 4723 -> 0 bytes .../{ => archive}/l4d2_fix_rocketjump.sp | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 addons/sourcemod/plugins/fixes/l4d2_fix_rocketjump.smx rename addons/sourcemod/scripting/{ => archive}/l4d2_fix_rocketjump.sp (100%) diff --git a/addons/sourcemod/plugins/fixes/l4d2_fix_rocketjump.smx b/addons/sourcemod/plugins/fixes/l4d2_fix_rocketjump.smx deleted file mode 100644 index 5e7e072fb82b0047ed73b99052693117b1ef1182..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4723 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 Date: Wed, 25 Mar 2026 01:04:43 +0800 Subject: [PATCH 3/3] Update generalfixes.cfg --- cfg/generalfixes.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cfg/generalfixes.cfg b/cfg/generalfixes.cfg index db039efac..0066a519e 100644 --- a/cfg/generalfixes.cfg +++ b/cfg/generalfixes.cfg @@ -49,7 +49,7 @@ sm plugins load fixes/annoyance_exploit_fixes.smx sm plugins load fixes/l4d_fix_shove_duration.smx sm plugins load fixes/l4d2_jockey_hitbox_fix.smx sm plugins load fixes/l4d_consistent_escaperoute.smx -sm plugins load fixes/l4d2_fix_rocketjump.smx +sm plugins load fixes/l4d_fix_rocket_jump.smx sm plugins load fixes/l4d2_charge_target_fix.smx sm plugins load fixes/l4d2_shove_fix.smx sm plugins load fixes/l4d2_scripted_tank_stage_fix.smx