From cf6f48fc7e0c486bd36f4157ee1cefceb1b00ec1 Mon Sep 17 00:00:00 2001 From: cH1yoi Date: Mon, 23 Dec 2024 02:34:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=89=9B=E5=84=BF=E5=AD=90?= =?UTF-8?q?=E5=88=9B=E4=B8=8D=E5=8A=A8=E5=90=8C=E6=A0=B7=E7=94=9F=E8=BF=98?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gamedata/charger_collision_patch.txt | 104 +++++++ .../plugins/fixes/Charger_Collision_patch.smx | Bin 0 -> 7158 bytes .../scripting/Charger_Collision_patch.sp | 257 ++++++++++++++++++ cfg/cfgogl/advanced8v8/confogl_plugins.cfg | 3 + cfg/cfgogl/zonemod6v6/confogl_plugins.cfg | 3 + cfg/cfgogl/zonemod8v8/confogl_plugins.cfg | 5 +- 6 files changed, 371 insertions(+), 1 deletion(-) create mode 100644 addons/sourcemod/gamedata/charger_collision_patch.txt create mode 100644 addons/sourcemod/plugins/fixes/Charger_Collision_patch.smx create mode 100644 addons/sourcemod/scripting/Charger_Collision_patch.sp diff --git a/addons/sourcemod/gamedata/charger_collision_patch.txt b/addons/sourcemod/gamedata/charger_collision_patch.txt new file mode 100644 index 000000000..845b245fb --- /dev/null +++ b/addons/sourcemod/gamedata/charger_collision_patch.txt @@ -0,0 +1,104 @@ +"Games" +{ + "left4dead2" + { + "MemPatches" + { + /** + * This patch prevents marking survivors. + * -- + * Example: + * Reversed code of default behavior: pCharge->CCharge.m_hitSurvivors[pPlayer->CTerrorPlayer.m_survivorCharacter] = 1; + * New behavior when patch is enabled: pCharge->CCharge.m_hitSurvivors[pPlayer->CTerrorPlayer.m_survivorCharacter] = 0; + **/ + "CCharge::HandleCustomCollision()::MarkSurvivor" + { + "signature" "CCharge::HandleCustomCollision" + "linux" + { + "offset" "333" + "verify" "\x01" + "patch" "\x00" + + } + "windows" + { + "offset" "305" + "verify" "\x01" + "patch" "\x00" + } + } + } + "Functions" + { + "Lux::ThrowImpactedSurvivor" + { + "signature" "ThrowImpactedSurvivor" + "callconv" "cdecl" + "return" "int" + "this" "ignore" + "arguments" + { + "attacker" + { + "type" "cbaseentity" + } + "victim" + { + "type" "cbaseentity" + } + "charge_progress" + { + "type" "float" + } + "should_damage" + { + "type" "bool" + } + } + } + } + "Signatures" + { + /* + * credit from here for sigs/remarks for finding or outdate sigs + * https://github.com/SilvDev/Left4DHooks/blob/main/sourcemod/gamedata/left4dhooks.l4d2.txt + * https://github.com/Psykotikism/L4D1-2_Signatures/blob/main/l4d2/gamedata/l4d2_signatures.txt + */ + + /* + * CTerrorPlayer::Fling(Vector const&,PlayerAnimEvent_t,CBaseCombatCharacter *,float) + * + * Vector: how target is supposed to fly, Animevent is "76" for chargerbounce, CBasePlayer is attacker, float is Incap Animation time + * + * Find via CCharge::HandleCustomCollision (strings) -> ThrowImpactedSurvivor (strings, structure) -> Fling (feel it out) + * + */ + "CCharge::HandleCustomCollision" + { + "library" "server" + "linux" "@_ZN7CCharge21HandleCustomCollisionEP11CBaseEntityRK6VectorS4_P10CGameTraceP9CMoveData" + "windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x33\x2A\x89\x2A\x2A\x8B\x2A\x2A\x53\x8B\x2A\x89\x2A\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x56\x8B" + /* ? ? ? ? ? ? ? ? ? ? ? ? ? ? 33 ? 89 ? ? 8B ? ? 53 8B ? 89 ? ? 8B ? ? ? ? ? 56 8B */ + } + /* + * ThrowImpactedSurvivor(CTerrorPlayer *, CTerrorPlayer *, float, bool) + * Search: "charger_impact" + */ + "ThrowImpactedSurvivor" + { + "library" "server" + "linux" "@_Z21ThrowImpactedSurvivorP13CTerrorPlayerS0_fb" + "windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x53\x56\x57\x8B\x2A\x2A\x8B\x2A\x2A\x2A\x2A\x2A\xC1\x2A\x2A\x2A\x2A\x74\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x2A\x8B\x2A\x2A\x2A\x2A\x2A\x8B" + /* ? ? ? ? ? ? 53 56 57 8B ? ? 8B ? ? ? ? ? C1 ? ? ? ? 74 ? ? ? ? ? ? ? ? 8B ? ? ? ? ? 8B */ + } + "CBaseEntity::SetAbsVelocity" + { + "library" "server" + "linux" "@_ZN11CBaseEntity14SetAbsVelocityERK6Vector" + "windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x56\x8B\x75\x08\xF3\x0F\x10\x06\x57\x8B\xF9" + /* ? ? ? ? ? ? 56 8B 75 08 F3 0F 10 06 57 8B F9 */ + } + } + } +} \ No newline at end of file diff --git a/addons/sourcemod/plugins/fixes/Charger_Collision_patch.smx b/addons/sourcemod/plugins/fixes/Charger_Collision_patch.smx new file mode 100644 index 0000000000000000000000000000000000000000..ed9ff9b0944533e2edd39de772767196627f4004 GIT binary patch literal 7158 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. +*/ + +#pragma semicolon 1 + +#include +#include +#include +#include +#include + +#pragma newdecls required + +#define GAMEDATA "charger_collision_patch" +#define CHARGE_MARKSURVIVOR_KEY "CCharge::HandleCustomCollision()::MarkSurvivor" +#define CHARGE_ISINCAPPED_KEY "CCharge::HandleCustomCollision()::IsIncap" +#define PLUGIN_VERSION "2.0" + + +#define IMPACT_SND_INTERVAL 0.1 + +enum struct ChargerCharge +{ + int m_Index; + float m_NextImpactSND; + bool m_MarkHit[MAXPLAYERS+1]; + + void Reset() + { + this.m_NextImpactSND = 0.0; + for(int i; i <= MAXPLAYERS; ++i) + { + this.m_MarkHit[i] = false; + } + } +} + +ChargerCharge g_ChargerCharge[MAXPLAYERS+1]; + +MemoryPatch Charge_MarkSurvivor; +Handle g_hSetAbsVelocity; + + +public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) +{ + if(GetEngineVersion() != Engine_Left4Dead2) + { + strcopy(error, err_max, "Plugin only supports Left 4 Dead 2"); + return APLRes_SilentFailure; + } + return APLRes_Success; +} + +public Plugin myinfo = +{ + name = "[L4D2]Charger_Collision_Patch", + author = "Lux", + description = "Fixes charger only allow to his 1 survivor index & allows colliding same target more than once", + version = PLUGIN_VERSION, + url = "forums.alliedmods.net/showthread.php?p=2647017" +}; + + +public void OnPluginStart() +{ + CreateConVar("charger_collision_patch_version", PLUGIN_VERSION, "", FCVAR_NOTIFY|FCVAR_DONTRECORD); + + for(int i; i <= MAXPLAYERS; ++i) + { + g_ChargerCharge[i].m_Index = i; + } + + Handle hGamedata = LoadGameConfigFile(GAMEDATA); + if(hGamedata == null) + { + SetFailState("Failed to load \"%s.txt\" gamedata.", GAMEDATA); + } + + Charge_MarkSurvivor = MemoryPatch.CreateFromConf(hGamedata, CHARGE_MARKSURVIVOR_KEY); + if(!Charge_MarkSurvivor.Validate()) + { + SetFailState("Failed to validate patch \"%s\"", CHARGE_MARKSURVIVOR_KEY); + } + + Handle hDetour; + hDetour = DHookCreateFromConf(hGamedata, "Lux::ThrowImpactedSurvivor"); + if(!hDetour) + { + SetFailState("Failed to find 'Lux::ThrowImpactedSurvivor' signature"); + } + + StartPrepSDKCall(SDKCall_Entity); + if(!PrepSDKCall_SetFromConf(hGamedata, SDKConf_Signature, "CBaseEntity::SetAbsVelocity")) + { + SetFailState("Error finding the 'CBaseEntity::SetAbsVelocity' signature."); + } + + PrepSDKCall_AddParameter(SDKType_Vector, SDKPass_Pointer); + g_hSetAbsVelocity = EndPrepSDKCall(); + if(g_hSetAbsVelocity == null) + { + SetFailState("Unable to prep SDKCall 'CBaseEntity::SetAbsVelocity'"); + } + + if(!DHookEnableDetour(hDetour, false, ThrowImpactedSurvivor)) + { + SetFailState("Failed to detour 'Lux::ThrowImpactedSurvivor'"); + } + + if(Charge_MarkSurvivor.Enable()) + { + PrintToServer("[%s] Enabled \"%s\" patch", GAMEDATA, CHARGE_MARKSURVIVOR_KEY); + } + + delete hGamedata; + + HookEvent("round_start", RoundStart); + HookEvent("charger_charge_start", ClearMarkedSurvivors, EventHookMode_Pre); + HookEvent("charger_charge_end", ClearMarkedSurvivors, EventHookMode_Pre); + AddNormalSoundHook(ImpactSNDHook); + + for(int i = 1; i <= MaxClients; ++i) + { + if(IsClientInGame(i)) + OnClientPutInServer(i); + } +} + +public MRESReturn ThrowImpactedSurvivor(Handle hReturn, Handle hParams) +{ + int iCharger = DHookGetParam(hParams, 1); + int iVictim = DHookGetParam(hParams, 2); + bool ShouldDamage = DHookGetParam(hParams, 4); + + //sanity check everything avoids conflicts + if(!ShouldDamage) + return MRES_Ignored; + + if(iCharger < 1 || iCharger > MaxClients || + GetClientTeam(iCharger) != 3 || !IsPlayerAlive(iCharger)) + { + return MRES_Ignored; + } + + int iAbility = GetEntPropEnt(iCharger, Prop_Send, "m_customAbility"); + if(iAbility == -1 || !HasEntProp(iAbility, Prop_Send, "m_isCharging")) + { + return MRES_Ignored; + } + + if(!GetEntProp(iAbility, Prop_Send, "m_isCharging", 1)) + return MRES_Ignored; + + int iCarryVictim = GetEntPropEnt(iCharger, Prop_Send, "m_carryVictim"); + if(iCarryVictim == -1) + { + DHookSetReturn(hReturn, 1); + return MRES_Supercede; + } + + if(iCarryVictim == iVictim) + { + //PrintToChatAll("illegal damage on %N from %N", iVictim, iCharger); + g_ChargerCharge[iCharger].m_NextImpactSND = GetGameTime() + IMPACT_SND_INTERVAL; + DHookSetReturn(hReturn, 1); + return MRES_Supercede; + } + + //Set velocity to 0 so impulse velocity does not account for current velocity + static float vecNoVel[3] = {0.0, 0.0, 0.0}; + SDKCall(g_hSetAbsVelocity, iVictim, vecNoVel); + + g_ChargerCharge[iCharger].m_NextImpactSND = GetGameTime() + IMPACT_SND_INTERVAL; + if(g_ChargerCharge[iCharger].m_MarkHit[iVictim]) + { + DHookSetParam(hParams, 4, false); + DHookSetReturn(hReturn, 1); + return MRES_ChangedHandled; + } + g_ChargerCharge[iCharger].m_MarkHit[iVictim] = true; + return MRES_Ignored; +} + +public Action ImpactSNDHook(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH], int &iCharger, int &channel, float &volume, int &level, int &pitch, int &flags, char soundEntry[PLATFORM_MAX_PATH], int &seed) +{ + if(iCharger < 1 || iCharger > MaxClients || + GetClientTeam(iCharger) != 3 || !IsPlayerAlive(iCharger)) + { + return Plugin_Continue; + } + + int iAbility = GetEntPropEnt(iCharger, Prop_Send, "m_customAbility"); + if(iAbility == -1 || !HasEntProp(iAbility, Prop_Send, "m_isCharging")) + { + return Plugin_Continue; + } + + if(!GetEntProp(iAbility, Prop_Send, "m_isCharging", 1)) + return Plugin_Continue; + + if(g_ChargerCharge[iCharger].m_NextImpactSND > GetGameTime()) + { + if(StrContains(sample, "player/charger/hit/charger_smash_0", false) != -1) + return Plugin_Handled; + } + + return Plugin_Continue; +} + +public void OnClientPutInServer(int client) +{ + SDKHook(client, SDKHook_SpawnPost, OnSpawnPost); +} + +public void OnSpawnPost(int client) +{ + g_ChargerCharge[client].Reset(); + for(int i; i <= MAXPLAYERS; ++i) + { + g_ChargerCharge[i].m_MarkHit[client] = false; + } +} + +public void RoundStart(Event event, const char[] eventName, bool dontBroadcast) +{ + for(int i; i <= MAXPLAYERS; ++i) + { + g_ChargerCharge[i].Reset(); + } +} + +public void ClearMarkedSurvivors(Event event, const char[] eventName, bool dontBroadcast) +{ + int iCharger = GetClientOfUserId(event.GetInt("userid")); + if(iCharger < 1) + return; + + for(int i; i <= MAXPLAYERS; ++i) + { + g_ChargerCharge[iCharger].m_MarkHit[i] = false; + } +} \ No newline at end of file diff --git a/cfg/cfgogl/advanced8v8/confogl_plugins.cfg b/cfg/cfgogl/advanced8v8/confogl_plugins.cfg index de421a7fc..9740d1b8f 100644 --- a/cfg/cfgogl/advanced8v8/confogl_plugins.cfg +++ b/cfg/cfgogl/advanced8v8/confogl_plugins.cfg @@ -31,6 +31,9 @@ sm plugins load optional/l4d_superversus.smx // 药丸发光 sm plugins load optional/l4d2_random_glow_item.smx +// 修复牛牛创不动同样生还 +sm plugins load fixes/Charger_Collision_patch.smx + // 分算法 sm plugins load optional/l4d2_solidhealthmedkits.smx sm plugins load optional/l4d3_scoremod_DRDK_remake2.smx diff --git a/cfg/cfgogl/zonemod6v6/confogl_plugins.cfg b/cfg/cfgogl/zonemod6v6/confogl_plugins.cfg index b10e0efff..c0ef91752 100644 --- a/cfg/cfgogl/zonemod6v6/confogl_plugins.cfg +++ b/cfg/cfgogl/zonemod6v6/confogl_plugins.cfg @@ -27,5 +27,8 @@ sm plugins load optional/l4d_CreateSurvivorBot.smx // 多人多克插件 sm plugins load optional/l4d_superversus.smx +// 修复牛牛创不动同样生还 +sm plugins load fixes/Charger_Collision_patch.smx + // 药丸发光 sm plugins load optional/l4d2_random_glow_item.smx \ No newline at end of file diff --git a/cfg/cfgogl/zonemod8v8/confogl_plugins.cfg b/cfg/cfgogl/zonemod8v8/confogl_plugins.cfg index fb7ef25d0..177b82429 100644 --- a/cfg/cfgogl/zonemod8v8/confogl_plugins.cfg +++ b/cfg/cfgogl/zonemod8v8/confogl_plugins.cfg @@ -29,4 +29,7 @@ sm plugins load optional/l4d_CreateSurvivorBot.smx sm plugins load optional/l4d_superversus.smx // 药丸发光 -sm plugins load optional/l4d2_random_glow_item.smx \ No newline at end of file +sm plugins load optional/l4d2_random_glow_item.smx + +// 修复牛牛创不动同样生还 +sm plugins load fixes/Charger_Collision_patch.smx \ No newline at end of file