View Single Post
Author Message
eyal282
Veteran Member
Join Date: Aug 2011
Old 02-05-2018 , 14:48   [L4D2] SDKCall CCharge::MarkSurvivorAsHit crashes server
Reply With Quote #1

This code is designed to remove the annoying bug that is apparently a feature where when you impact a survivor once, you can't impact again, the SDKCall MarkSurvivorAsHit crashes the server ( accelerator's crash reporter )

Code:
#include <sourcemod>
#include <sdktools>

new LastImpact[MAXPLAYERS] = 0;

new bool:TimeShield[MAXPLAYERS];

public Plugin:myinfo = {
	name = "Charger infinite impacts",
	author = "Eyal282 ( FuckTheSchool )",
	description = "Chargers will no longer run in place if touching a survivor they already impacted",
	version = "1.0",
	url = "NULL"
};

new Handle:sdk_ClearChargeAbilityHits = INVALID_HANDLE;
new Handle:sdk_MarkSurvivorAsHit = INVALID_HANDLE;


new const String:const_LinuxClearAllSurvivorHits[] = "_ZN7CCharge20ClearAllSurvivorHitsEv";
new const String:const_LinuxMarkSurvivorAsHit[] = "_ZN7CCharge17MarkSurvivorAsHitEi";
new const String:const_GameDataFile[] = "ChargerInfiniteImpact";

public OnPluginStart()
{
	HookEvent("charger_impact", Event_ChargerImpact, EventHookMode_Post);
	new String:FileName[300], Handle:hGameConf;

	BuildPath(Path_SM, FileName, sizeof(FileName), "gamedata/%s.txt", const_GameDataFile);
	if( !FileExists(FileName) )
	{
		
		new Handle:FileHandle = OpenFile(FileName, "a+");
		
		if(FileHandle == INVALID_HANDLE)
			SetFailState("Could not create gamedata file.");
		
		
		WriteFileLine(FileHandle, "\"Games\""); 
		WriteFileLine(FileHandle, "{");
		WriteFileLine(FileHandle, "	\"left4dead2\"");
		WriteFileLine(FileHandle, "	{");
		WriteFileLine(FileHandle, "		\"Signatures\"");
		WriteFileLine(FileHandle, "		{");
		WriteFileLine(FileHandle, "			\"CCharge::ClearAllSurvivorHits\"");
		WriteFileLine(FileHandle, "			{");
		WriteFileLine(FileHandle, "				\"library\" \"server\"");
		WriteFileLine(FileHandle, "				\"linux\" \"@%s\"", const_LinuxClearAllSurvivorHits);
		WriteFileLine(FileHandle, "			}");
		WriteFileLine(FileHandle, "			\"CCharge::MarkSurvivorAsHit\"");
		WriteFileLine(FileHandle, "			{");
		WriteFileLine(FileHandle, "				\"library\" \"server\"");
		WriteFileLine(FileHandle, "				\"linux\" \"@%s\"", const_LinuxMarkSurvivorAsHit);
		WriteFileLine(FileHandle, "			}");
		WriteFileLine(FileHandle, "		}");
		WriteFileLine(FileHandle, "	}");
		WriteFileLine(FileHandle, "}");

		CloseHandle(FileHandle);

		hGameConf = LoadGameConfigFile(const_GameDataFile);
	}
	else
		hGameConf = LoadGameConfigFile(const_GameDataFile);
	
	StartPrepSDKCall(SDKCall_Entity);
	PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "CCharge::ClearAllSurvivorHits");
	
	sdk_ClearChargeAbilityHits = EndPrepSDKCall();
	
	StartPrepSDKCall(SDKCall_Entity);
	PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "CCharge::MarkSurvivorAsHit");
	
	PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
	sdk_MarkSurvivorAsHit = EndPrepSDKCall();

	if(sdk_ClearChargeAbilityHits == INVALID_HANDLE)
	{
		SetFailState("Could not find signature CCharge::ClearAllSurvivorHits");
		return;
	}
	else if(sdk_MarkSurvivorAsHit == INVALID_HANDLE)
	{
		SetFailState("Could not find signature CCharge::MarkSurvivorAsHit");
		return;
	}
}

public Action:Event_ChargerImpact(Handle:hEvent, const String:Name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(hEvent, "userid"));
	new victim = GetClientOfUserId(GetEventInt(hEvent, "victim"));
	
	TimeShield[victim] = true;
	LastImpact[victim] = client;
	CreateTimer(1.0, RemoveTimeShield, victim);
}

public Action:RemoveTimeShield(Handle:hTimer, victim)
{
	TimeShield[victim] = false;
}

public OnGameFrame()
{
	for(new i=1;i <= MaxClients;i++)
	{
		if(LastImpact[i] == 0)
			continue;
			
		else if(TimeShield[i])
			continue;
		
		else if(!IsClientInGame(i))
			continue;
		
		else if(!IsPlayerAlive(i))	
			continue;
			
		else if(GetClientTeam(i) != 2)
			continue;
			
		else if(!(GetEntityFlags(i) & FL_ONGROUND))
			continue;
			
		RemoveAbilityHit(i, LastImpact[i]);
	}
}

RemoveAbilityHit(victim, charger)
{
	if(!IsClientInGame(charger))
		return;

	else if(GetClientTeam(charger) != 3)
		return;
	
	else if(GetEntProp(charger, Prop_Send, "m_zombieClass") != 6)
		return;
		
	new abilityEntity = GetEntPropEnt(charger, Prop_Send, "m_customAbility");
	
	if(abilityEntity == -1)
		return;
		
	else if(!IsValidEntity(abilityEntity))
		return;
	
	SDKCall(sdk_ClearChargeAbilityHits, abilityEntity);
	
	for(new i=1;i <= MaxClients;i++)
	{
		if(i == victim)
			continue;
		
		else if(!IsClientInGame(i))
			continue;
			
		else if(GetClientTeam(i) != 2)
			continue;
	
		else if(!IsPlayerAlive(i))
			continue;
			
		if(LastImpact[i] == charger)
			SDKCall(sdk_MarkSurvivorAsHit, abilityEntity, i);
	}
	LastImpact[victim] = 0;
}
__________________
I am available to make plugins for pay.

Discord: Eyal282#1334

Last edited by eyal282; 02-06-2018 at 18:09.
eyal282 is offline