Raised This Month: $12 Target: $400
 3% 

Solved How to set SDKHook on round_start correctly?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 10-23-2018 , 12:31   How to set SDKHook on round_start correctly?
Reply With Quote #1

Hi,

Let's say I'm using SDKHook_OnTakeDamage to block some damage on all SURVIVORS (2) team (L4D).

It require to set hook on each individual client:

Code:
SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
No problem. But, on round_end, game engine automatically remove that hook.
So I need to set it again once player is fully-ingame (I guess) on next round_start.

For this reason, I'm using "player_team" event and check if "team == 2" (don't need extra unnecessary hooks).

Everything work ok. I just curious are there a simpler way than my monstro-code?

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

bool g_bHooked[MAXPLAYERS+1];

public void OnPluginStart()
{
	HookEvent("round_end", 				Event_RoundEnd,		EventHookMode_PostNoCopy);
	HookEvent("finale_win", 			Event_RoundEnd,		EventHookMode_PostNoCopy);
	HookEvent("mission_lost", 			Event_RoundEnd,		EventHookMode_PostNoCopy);
	HookEvent("map_transition", 		Event_RoundEnd,		EventHookMode_PostNoCopy);
	HookEvent("player_team", Event_Player_Team);

}

public Action Event_RoundEnd(Event event, char[] name, bool dontBroadcast)
{
	ResetHookFlag();
}

public void OnMapEnd()
{
	ResetHookFlag();
}

void ResetHookFlag()
{
	for (int i = 1; i <= MaxClients; i++)
	{
		g_bHooked[i] = false;
	}
}

void Set_SDKHook(int client)
{
	if (!g_bHooked[client])
	{
		SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
		g_bHooked[client] = true;
	}
}

void Remove_SDKHook(int client)
{
	if (g_bHooked[client])
	{
		SDKUnhook(client, SDKHook_OnTakeDamage, OnTakeDamage);
		g_bHooked[client] = false;
	}
}

public Action Event_Player_Team(Event event, char[] name, bool dontBroadcast)
{
	int UserId = event.GetInt("userid");
	if (UserId != 0)
	{
		int client = GetClientOfUserId(UserId);

		if (client != 0)
		{
			int team = event.GetInt("team");

			if (team == 2) // joined to survivor
			{
				Set_SDKHook(client);
			}
			else {
				int oldteam = event.GetInt("oldteam");
				if (oldteam == 2 || oldteam == 1) // desconnected from survivors or spectators
				{
					bool bDisconnect = event.GetBool("disconnect");
					if (bDisconnect)
					{
						Remove_SDKHook(client);
					}
				}
			}
		}
	}
}

public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3])
{
...
//return Plugin_Handled;
//return Plugin_Continue;
}
(and yea, I know about "player_hurt" / "player_hurt_concise" non-SDK hooks)

P.S. I saw some people use OnClientPutInServer() to set hook, but it's extra hooks (e.g. here also clients with team == 3).
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]

Last edited by Dragokas; 10-23-2018 at 16:59.
Dragokas is offline
8guawong
AlliedModders Donor
Join Date: Dec 2013
Location: BlackMarke7
Old 10-23-2018 , 13:13   Re: How to set SDKHook on round_start correctly?
Reply With Quote #2

how do you know the game engine unhooks after round end?
__________________
8guawong is offline
Powerlord
AlliedModders Donor
Join Date: Jun 2008
Location: Seduce Me!
Old 10-23-2018 , 14:20   Re: How to set SDKHook on round_start correctly?
Reply With Quote #3

Quote:
Originally Posted by 8guawong View Post
how do you know the game engine unhooks after round end?
Given that this is L4D, I bet round end also means map change.
__________________
Not currently working on SourceMod plugin development.
Powerlord is offline
8guawong
AlliedModders Donor
Join Date: Dec 2013
Location: BlackMarke7
Old 10-23-2018 , 14:42   Re: How to set SDKHook on round_start correctly?
Reply With Quote #4

Quote:
Originally Posted by Powerlord View Post
Given that this is L4D, I bet round end also means map change.
Ahhh didn't know that
__________________
8guawong is offline
MasterMind420
BANNED
Join Date: Nov 2010
Old 10-23-2018 , 15:27   Re: How to set SDKHook on round_start correctly?
Reply With Quote #5

In l4d2 i use onclientputinserver....it either rehooks it on everymap load or never unhooks it to begin with...not really sure but it always works between map changes or round end. .i havent tried a client loop in on round start but the problem with that is not all clients may be available to hook at that time...not sure though...could use player spawn event...set a bool in round end and check...but i think onclientputinserver is what u want.
MasterMind420 is offline
Psyk0tik
Veteran Member
Join Date: May 2012
Location: Homeless
Old 10-23-2018 , 16:39   Re: How to set SDKHook on round_start correctly?
Reply With Quote #6

Quote:
Originally Posted by MasterMind420 View Post
In l4d2 i use onclientputinserver....it either rehooks it on everymap load or never unhooks it to begin with...not really sure but it always works between map changes or round end. .i havent tried a client loop in on round start but the problem with that is not all clients may be available to hook at that time...not sure though...could use player spawn event...set a bool in round end and check...but i think onclientputinserver is what u want.
Seconded.

OnClientPutInServer() is the way to go.

For late loads, you can use a for () loop on OnPluginStart() or OnMapStart().
__________________
Psyk0tik is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 10-23-2018 , 16:47   Re: How to set SDKHook on round_start correctly?
Reply With Quote #7

8guawong, thanks. You are right. I made a problem myself by Unhooking on "disconnect" reason.
I thought player_team set that reason when player is really disconnect from the server.

Looks like my main question is over. After hooking it once, engine never unhook it again itself.

So, how to recognize is it disconnection because client quit the game or because map ends?
OnClientDisconnect() forward is also called for all clients just right before map ends.

EDIT.
Ohh, MasterMind, Crasher, thanks too.
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]

Last edited by Dragokas; 10-23-2018 at 16:52.
Dragokas is offline
Psyk0tik
Veteran Member
Join Date: May 2012
Location: Homeless
Old 10-23-2018 , 17:20   Re: How to set SDKHook on round_start correctly?
Reply With Quote #8

Quote:
Originally Posted by Dragokas View Post
8guawong, thanks. You are right. I made a problem myself by Unhooking on "disconnect" reason.
I thought player_team set that reason when player is really disconnect from the server.

Looks like my main question is over. After hooking it once, engine never unhook it again itself.

So, how to recognize is it disconnection because client quit the game or because map ends?
OnClientDisconnect() forward is also called for all clients just right before map ends.

EDIT.
Ohh, MasterMind, Crasher, thanks too.
You could try using the player_disconnect event. It's only called when a player disconnects from the server, so it shouldn't be called across map change. Same with the player_connect event.
__________________
Psyk0tik is offline
eyal282
Veteran Member
Join Date: Aug 2011
Old 10-23-2018 , 17:24   Re: How to set SDKHook on round_start correctly?
Reply With Quote #9

Just hook in onclientputinserver and check there if team == 3
__________________
I am available to make plugins for pay.

Discord: Eyal282#1334
eyal282 is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 10-24-2018 , 06:36   Re: How to set SDKHook on round_start correctly?
Reply With Quote #10

Quote:
Originally Posted by eyal282 View Post
Just hook in onclientputinserver and check there if team == 3
Impossible. GetClientTeam == 0 at that point of time.

Looks like the only opportunity is player_team or round_start + timer.

Quote:
You could try using the player_disconnect event. It's only called when a player disconnects from the server, so it shouldn't be called across map change. Same with the player_connect event.
Right.

... All right. It's enough info for me. Thanks @all.
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]
Dragokas is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 09:08.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode