diff --git a/addons/sourcemod/gamedata/l4d_fix_stagger_dir.txt b/addons/sourcemod/gamedata/l4d_fix_stagger_dir.txt new file mode 100644 index 000000000..5fdbc695f --- /dev/null +++ b/addons/sourcemod/gamedata/l4d_fix_stagger_dir.txt @@ -0,0 +1,109 @@ +"Games" +{ + "#default" + { + "Functions" + { + "CTerrorPlayer::OnStaggered" + { + "signature" "CTerrorPlayer::OnStaggered" + "callconv" "thiscall" + "return" "void" + "this" "entity" + "arguments" + { + "a1" + { + "type" "cbaseentity" + } + "a2" + { + "type" "vectorptr" + } + } + } + } + } + + "left4dead" + { + "Offsets" + { + "CTerrorPlayer::m_PlayerAnimState" + { + "linux" "6024" + "windows" "6004" + } + + "m_flEyeYaw" + { + "linux" "112" + "windows" "116" + } + } + + "Signatures" + { + // Stolen from left4dhooks thanks to Silvers + /* + * CTerrorPlayer::OnStaggered(CBaseEntity *, Vector const) + */ + "CTerrorPlayer::OnStaggered" + { + "library" "server" + "linux" "@_ZN13CTerrorPlayer11OnStaggeredEP11CBaseEntityPK6Vector" + "windows" "\x83\x2A\x2A\x2A\x8B\x2A\xE8\x2A\x2A\x2A\x2A\x84\x2A\x0F\x85\x2A\x2A\x2A\x2A\x8B\x2A\x8B" + /* 83 ? ? ? 8B ? E8 ? ? ? ? 84 ? 0F 85 ? ? ? ? 8B ? 8B */ + /* Search: "Player.Shoved" */ + } + } + } + + "left4dead2" + { + "Offsets" + { + /* Windows offset: + * + * Search string "PlayerLedgeHangMiddle", which will lead you to "CTerrorPlayerAnimState::HandleActivity_Incapacitated". + * Go to its only xref function, and again, then you are at vtable of "CTerrorPlayerAnimState". + * Double click on the first virtual function "CTerrorPlayerAnimState::ClearAnimationState". + * Go to its function xref 3 times, and you will meet with an enormous constructor function. + * + * 1. Generate pseudocode and you can easily find the offset where the cursor is. + * 2. See the "mov" instruction below the highlighted "call". + */ + + "CTerrorPlayer::m_PlayerAnimState" + { + "linux" "10512" + "windows" "10524" + } + + "m_flEyeYaw" + { + "linux" "228" + "windows" "228" + } + } + + "Signatures" + { + // Stolen from left4dhooks thanks to Silvers + /* + * CTerrorPlayer::OnStaggered(CBaseEntity *, Vector const*) - used by L4D2 on Survivors, causes staggering (e.g. Charger Impact nearby) + * + * - string "PlayerShoved" has 3 refs, the one furthest into a function should be this one. + */ + "CTerrorPlayer::OnStaggered" + { + "library" "server" + "linux" "@_ZN13CTerrorPlayer11OnStaggeredEP11CBaseEntityPK6Vector" + "windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x83\x2A\x2A\x83\x2A\x2A\x55\x8B\x2A\x2A\x89\x2A\x2A\x2A\x8B\x2A\x83\x2A\x2A\x56\x57\x8B\x2A\xE8\x2A\x2A\x2A\x2A\x84\x2A\x0F\x85\x2A\x2A\x2A\x2A\x8B\x2A\x8B" + /* ? ? ? ? ? ? 83 ? ? 83 ? ? 55 8B ? ? 89 ? ? ? 8B ? 83 ? ? 56 57 8B ? E8 ? ? ? ? 84 ? 0F 85 ? ? ? ? 8B ? 8B + * Using a long local jump as the unique portion (last few bytes of sig) + */ + } + } + } +} \ No newline at end of file diff --git a/addons/sourcemod/plugins/fixes/l4d_fix_stagger_dir.smx b/addons/sourcemod/plugins/fixes/l4d_fix_stagger_dir.smx new file mode 100644 index 000000000..662881ea4 Binary files /dev/null and b/addons/sourcemod/plugins/fixes/l4d_fix_stagger_dir.smx differ diff --git a/addons/sourcemod/scripting/l4d_fix_stagger_dir.sp b/addons/sourcemod/scripting/l4d_fix_stagger_dir.sp new file mode 100644 index 000000000..78a3e00b1 --- /dev/null +++ b/addons/sourcemod/scripting/l4d_fix_stagger_dir.sp @@ -0,0 +1,81 @@ +#pragma semicolon 1 +#pragma newdecls required + +#include +#include + +#define PLUGIN_VERSION "1.0" + +public Plugin myinfo = +{ + name = "[L4D & 2] Fix Stagger Direction", + author = "Forgetest", + description = "Fix survivors getting stumbled to the \"opposite\" direction.", + 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); + } + property GameData Super { + public get() { return view_as(this); } + } + public int GetOffset(const char[] key) { + int offset = this.Super.GetOffset(key); + if (offset == -1) SetFailState("Missing offset \"%s\"", key); + return offset; + } + 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; + } +} + +int g_iOffs_m_PlayerAnimState; +int g_iOffs_m_flEyeYaw; + +methodmap Address {} +methodmap PlayerAnimState < Address { + public static PlayerAnimState FromPlayer(int client) { + return view_as(GetEntData(client, g_iOffs_m_PlayerAnimState)); + } + + property float m_flEyeYaw { + public set(float flAimYaw) { StoreToAddress(this + view_as
(g_iOffs_m_flEyeYaw), flAimYaw, NumberType_Int32); } + } +} + +public void OnPluginStart() +{ + GameDataWrapper gd = new GameDataWrapper("l4d_fix_stagger_dir"); + g_iOffs_m_PlayerAnimState = gd.GetOffset("CTerrorPlayer::m_PlayerAnimState"); + g_iOffs_m_flEyeYaw = gd.GetOffset("m_flEyeYaw"); + + delete gd.CreateDetourOrFail("CTerrorPlayer::OnStaggered", DTR_OnStaggered); + delete gd; +} + +MRESReturn DTR_OnStaggered(int client, DHookParam hParams) +{ + if (IsClientInGame(client) && GetClientTeam(client) == 2) + { + float ang[3]; + GetClientAbsAngles(client, ang); + PlayerAnimState.FromPlayer(client).m_flEyeYaw = ang[1]; + } + + return MRES_Ignored; +} \ No newline at end of file diff --git a/cfg/generalfixes.cfg b/cfg/generalfixes.cfg index 787ec8f2f..0bbcb07bb 100644 --- a/cfg/generalfixes.cfg +++ b/cfg/generalfixes.cfg @@ -67,6 +67,7 @@ sm plugins load fixes/l4d2_tank_flying_incap.smx sm plugins load fixes/l4d2_tank_spawn_antirock_protect.smx sm plugins load fixes/l4d_fix_rotated_physblocker.smx sm plugins load fixes/firebulletsfix.smx +sm plugins load fixes/l4d_fix_stagger_dir.smx // Anti-Cheat. sm plugins load anticheat/l4d2_noghostcheat.smx