Raised This Month: $32 Target: $400
 8% 

Solved Check all players are fully in-game


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 10-19-2018 , 01:09   Check all players are fully in-game
Reply With Quote #1

Hi,

please, tip me an algorithm.

After round start usually we can see some players are still connecting / or loading the map.
How to prepare the trigger when all player will be fully in-game?

Maybe something like:
Code:
public void OnClientPostAdminCheck(int client)
{
	bool bAllInGame = true;

	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnected(i) && !IsClientInGame(i))
		{
			bAllInGame = false;
			break;
		}
	}
	if (bAllInGame) call trigger ...
}
?

Thanks.
__________________
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-19-2018 at 10:28.
Dragokas is offline
Neuro Toxin
Veteran Member
Join Date: Oct 2013
Location: { closing the void; }
Old 10-19-2018 , 04:19   Re: Check all players are fully in-game
Reply With Quote #2

Your code looks fine to me. It could trigger if one client fully connects before another starts connecting.

If you know how many players are connecting I would also count the fully connected clients and check its value before triggering.
__________________
Neuro Toxin is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-19-2018 , 04:28   Re: Check all players are fully in-game
Reply With Quote #3

What I think, you need use little timer...

This is my thought. I don't know your game.
*this trigger work now even empty server.

PHP Code:

Handle my_timer
;

public 
void OnPluginStart()
{
    
HookEventEx("round_start"round_startEventHookMode_PostNoCopy);
}

public 
void round_start(Event event, const char[] namebool dontBroadcast)
{
    
delete my_timer;

    
my_timer CreateTimer(15.0my_timer_callback_TIMER_REPEAT);
}

public 
Action my_timer_callback(Handle timer)
{
    
// If some wierd error, repeating timer is working and handle is null - this "safety code" stop timer and don't continue code block.
    // - This kind error can appear if timer callback not reach in the bottom of the code block using Plugin_Stop. Ex. My_Trigger_Callback() create error.
    
if(my_timer == INVALID_HANDLE) return Plugin_Stop;



    
bool IsPlayerConnecting;

    for(
int i 1<= MaxClientsi++)
    {
        if(!
IsClientConnected(i)) continue; // skip not connected client indexs

        
if(!IsClientInGame(i)) IsPlayerConnecting true;
    }


    
// repeating timer
    
if(IsPlayerConnecting)
    {
        
PrintToChatAll("[SM]: Waiting connecting players!");
        return 
Plugin_Continue;
    }


    
// stopping timer
    // - Clear handle first
    
my_timer INVALID_HANDLE;


    
My_Trigger_Callback();


    return 
Plugin_Stop;
}

public 
void My_Trigger_Callback()
{
    
PrintToChatAll("[SM]: Ready!");

__________________
Do not Private Message @me

Last edited by Bacardi; 10-19-2018 at 04:30.
Bacardi is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 10-19-2018 , 10:26   Re: Check all players are fully in-game
Reply With Quote #4

Neuro Toxin, thank you. No, I don't know total number of players in advance that going to connect (but, all of them is connected on last round_end, maybe ±1 new one during map load).

Bacardi, thank you. I was thinking about this version with timer. 15 sec is too much. Maybe I just adjust it using two timers, first delay like 10-15 sec. and next repeatable like each 5 sec + timeout. The goal is not to wait too long and interact as soon as everybody is ingame.

Sounds like this should be fine:
Code:
#pragma semicolon 1
#pragma newdecls required

float g_fConnectionTimeMin = 10.0;
float g_fConnectionTimeMax = 60.0;
float g_fConnectionTime;

public void OnPluginStart()
{
	HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
}

public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast)
{
	g_fConnectionTime = g_fConnectionTimeMin;
	CreateTimer(g_fConnectionTimeMin, Timer_CheckConnection, _, TIMER_FLAG_NO_MAPCHANGE);
}

public Action Timer_CheckConnection(Handle timer)
{
    bool IsPlayerConnecting;
	
    for (int i = 1; i <= MaxClients; i++)
	{
        if (IsClientConnected(i) && !IsClientInGame(i))
		{
			IsPlayerConnecting = true;
			break;
		}
	}
	
    if (IsPlayerConnecting)
    {
		PrintToChatAll("[SM]: Waiting connecting players!");
		
		if (g_fConnectionTime <= g_fConnectionTimeMax)
		{
			g_fConnectionTime += 5.0;
			CreateTimer(5.0, Timer_CheckConnection, _, TIMER_FLAG_NO_MAPCHANGE);
		}
		else {
			OnAllClientsPostAdminCheck(); // timeout
		}
	}
	else {
		OnAllClientsPostAdminCheck();
	}
}

void OnAllClientsPostAdminCheck()
{
	PrintToChatAll("[SM]: Ready!");
}
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]
Dragokas is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-19-2018 , 10:29   Re: Check all players are fully in-game
Reply With Quote #5

ok, sounds nice.
Bacardi is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 10-22-2018 , 15:27   Re: Check all players are fully in-game
Reply With Quote #6

EDIT. Do not use the code below.

Some servers call round_start twice.
So I'll just leave the fix here in case somebody face with the same problem and don't want to call the trigger twice.

Code:
#pragma semicolon 1
#pragma newdecls required

float g_fConnectionTimeMin = 10.0;
float g_fConnectionTimeMax = 60.0;
float g_fConnectionTime;

public void OnPluginStart()
{
	HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
}

public Action Event_RoundStart(Event event, char[] name, bool dontBroadcast)
{
	static float fTime = -0.1;
	if (fTime < 0.0 || GetEngineTime() - fTime > 10.0)
	{
		g_fConnectionTime = g_fConnectionTimeMin;
		CreateTimer(g_fConnectionTimeMin, Timer_CheckConnection, _, TIMER_FLAG_NO_MAPCHANGE);
	}
	fTime = GetEngineTime();
	
	return Plugin_Continue;
}

public Action Timer_CheckConnection(Handle timer)
{
	bool IsPlayerConnecting;
	int i;
	
	for (i = 1; i <= MaxClients; i++)
	{
        if (IsClientConnected(i) && !IsClientInGame(i))
		{
			IsPlayerConnecting = true;
			break;
		}
	}
	
	if (IsPlayerConnecting)
	{
		PrintToChatAll("[SM]: Waiting connecting players: %N", i);
		
		if (g_fConnectionTime <= g_fConnectionTimeMax)
		{
			g_fConnectionTime += 5.0;
			CreateTimer(5.0, Timer_CheckConnection, _, TIMER_FLAG_NO_MAPCHANGE);
		}
		else {
			PrintToChatAll("[SM]: Timeout.");
			OnAllClientsPostAdminCheck(); // timeout
		}
	}
	else {
		OnAllClientsPostAdminCheck();
	}
}

void OnAllClientsPostAdminCheck()
{
	PrintToChatAll("[SM]: Ready!");
}
__________________
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-27-2018 at 08:00. Reason: added warning
Dragokas is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-23-2018 , 07:11   Re: Check all players are fully in-game
Reply With Quote #7

Which HL2 source game ??
Bacardi is offline
Silvers
SourceMod Plugin Approver
Join Date: Aug 2010
Location: SpaceX
Old 10-23-2018 , 07:33   Re: Check all players are fully in-game
Reply With Quote #8

L4D2 and maybe L4D1 have double round_start sometimes, and round_start before all players spawned or player_spawn before round_start. It's why I check for the first time round_start and player_spawn fire after round_end, then creating a 1 second timer and spawning things, otherwise the spawned items sometimes don't show because they were spawned too early. The only way I got it to work 100% in different situations (map change, everyone disconnecting, round restarts etc).
__________________
Silvers is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 10-23-2018 , 09:15   Re: Check all players are fully in-game
Reply With Quote #9

In my case (L4D1) difference between two round_start call was ~ 3-5 seconds.
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]
Dragokas is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 10-23-2018 , 10:14   Re: Check all players are fully in-game
Reply With Quote #10

What if you check round_end event and reason (and perhaps team index who win).
Look very first roun_end result and compare to others.

I just have a idea, if you first check round_end reasons, which one is so called "game begin".
After that, do things in round_start.

*edit
Simple way you could do is create boolean to skip first round_start on every map change...

*edit
you can see events from console using cmd
sm_cvar net_showevents 2

Last edited by Bacardi; 10-23-2018 at 10:50.
Bacardi is offline
Reply



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 03:21.


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