From b84daf870ceaaf160e914cefbb11fb780cb49a89 Mon Sep 17 00:00:00 2001 From: BotoX Date: Wed, 5 Jul 2017 22:55:44 +0200 Subject: [PATCH] New plugin: FixPlayerEquip Fix lag/crashes caused by game_player_equip --- .../gamedata/FixPlayerEquip.games.txt | 14 +++ FixPlayerEquip/scripting/FixPlayerEquip.sp | 109 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 FixPlayerEquip/gamedata/FixPlayerEquip.games.txt create mode 100644 FixPlayerEquip/scripting/FixPlayerEquip.sp diff --git a/FixPlayerEquip/gamedata/FixPlayerEquip.games.txt b/FixPlayerEquip/gamedata/FixPlayerEquip.games.txt new file mode 100644 index 00000000..9934e43b --- /dev/null +++ b/FixPlayerEquip/gamedata/FixPlayerEquip.games.txt @@ -0,0 +1,14 @@ +"Games" +{ + "#default" + { + "Signatures" + { + "CCSPlayer_StockPlayerAmmo" + { + "library" "server" + "linux" "@_ZN9CCSPlayer15StockPlayerAmmoEP17CBaseCombatWeapon" + } + } + } +} diff --git a/FixPlayerEquip/scripting/FixPlayerEquip.sp b/FixPlayerEquip/scripting/FixPlayerEquip.sp new file mode 100644 index 00000000..c0337464 --- /dev/null +++ b/FixPlayerEquip/scripting/FixPlayerEquip.sp @@ -0,0 +1,109 @@ +#pragma semicolon 1 +#pragma newdecls required + +#include +#include +#include +#include +#include + +// void CCSPlayer::StockPlayerAmmo( CBaseCombatWeapon *pNewWeapon ) +Handle g_hCCSPlayer_StockPlayerAmmo; + +public Plugin myinfo = +{ + name = "FixPlayerEquip", + author = "BotoX", + description = "Fix lag caused by game_player_equip entity.", + version = "1.0" +} + +public void OnPluginStart() +{ + Handle hGameConf = LoadGameConfigFile("FixPlayerEquip.games"); + if(hGameConf == INVALID_HANDLE) + { + SetFailState("Couldn't load FixPlayerEquip.games game config!"); + return; + } + + // void CCSPlayer::StockPlayerAmmo( CBaseCombatWeapon *pNewWeapon ) + StartPrepSDKCall(SDKCall_Player); + if(!PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "CCSPlayer_StockPlayerAmmo")) + { + CloseHandle(hGameConf); + SetFailState("PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, \"CCSPlayer_StockPlayerAmmo\" failed!"); + return; + } + PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer); + g_hCCSPlayer_StockPlayerAmmo = EndPrepSDKCall(); + + CloseHandle(hGameConf); + + /* Late Load */ + int entity = INVALID_ENT_REFERENCE; + while((entity = FindEntityByClassname(entity, "game_player_equip")) != INVALID_ENT_REFERENCE) + { + OnEntityCreated(entity, "game_player_equip"); + } +} + +public void OnEntityCreated(int entity, const char[] classname) +{ + if(StrEqual(classname, "game_player_equip")) + { + SDKHook(entity, SDKHook_Use, OnUse); + } +} + +public Action OnUse(int entity, int client) +{ + static int s_MaxEquip = -1; + if(s_MaxEquip == -1) + s_MaxEquip = GetEntPropArraySize(entity, Prop_Data, "m_weaponNames"); + + if(client > MaxClients || client <= 0) + return Plugin_Continue; + + bool bGaveAmmo = false; + + for(int i = 0; i < s_MaxEquip; i++) + { + char sWeapon[32]; + GetEntPropString(entity, Prop_Data, "m_weaponNames", sWeapon, sizeof(sWeapon), i); + + if(!sWeapon[0]) + break; + + if(strncmp(sWeapon, "ammo_", 5, false) == 0) + { + if(!bGaveAmmo) + { + int iWeapon = GetPlayerWeaponSlot(client, CS_SLOT_PRIMARY); + if(iWeapon != -1) + StockPlayerAmmo(client, iWeapon); + + iWeapon = GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY); + if(iWeapon != -1) + StockPlayerAmmo(client, iWeapon); + + bGaveAmmo = true; + } + } + else if(StrEqual(sWeapon, "item_kevlar", false)) + { + SetEntProp(client, Prop_Send, "m_ArmorValue", 100, 1); + } + else + { + GivePlayerItem(client, sWeapon); + } + } + + return Plugin_Handled; +} + +int StockPlayerAmmo(int client, int iWeapon) +{ + return SDKCall(g_hCCSPlayer_StockPlayerAmmo, client, iWeapon); +}