Raised This Month: $ Target: $400
 0% 

[TF2] Quick plugin review before I submit


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
CoolJosh3k
AlliedModders Donor
Join Date: Mar 2010
Old 07-18-2022 , 02:10   [TF2] Quick plugin review before I submit
Reply With Quote #1

Hi there,

I was hoping to get some eyeballs on this before I submit it for review. Hopefully there is nothing wrong with it, but I wrote it back in 2017.

The purpose of this plugin is to stop the jitter issues that a TF2 server can experience if the server has been empty and on the same map for too long.
I'm not entirely sure how to describe it, other than a server getting the jitters. If you've ever connected to a server that has been sitting on the same map for hours you'll probably know what I mean.

It is a basic solution of just restarting the server every hour, provided there is no one actually in it.

Thanks in advance to anyone who can verify it for me, or help me fix issues.

Here is my code:

Code:
#include <sourcemod>

new Handle:hEnable;
new Handle:hUpTime_Min, Handle:hUpTime_Max;
new Handle:hMaxPlayers;
new Handle:hWarn_ShowChat;
new bool:InRestartCountdown;
new iIdleTime;

public const Plugin:myinfo = {
	name = "Server UpTime Restarter",
	author = "CoolJosh3k",
	description = "Restarts a server after a specified uptime. Respects player counts.",
	version = "1.0.1",
}

public OnPluginStart()
{
	AutoExecConfig();
	hEnable = CreateConVar("SUR_Enable", "1", "Use this if you wish to stop plugin functions temporarily.", FCVAR_NOTIFY, true, 0.0, true, 1.0);
	hUpTime_Min = CreateConVar("SUR_UpTime_Min", "3600", "Minimum time in seconds before restart attempt.", FCVAR_NOTIFY, true, 60.0);
	hUpTime_Max = CreateConVar("SUR_UpTime_Max", "86400", "Time in seconds before server restart is forced, regardless of player count.", FCVAR_NOTIFY, true, 60.0);
	hMaxPlayers = CreateConVar("SUR_MinPlayers", "1", "Atleast this many players will cause the restart to be delayed. Spectators are not counted.", FCVAR_NOTIFY, true, 1.0);
	hWarn_ShowChat = CreateConVar("SUR_Warn_ShowChat", "1", "Display restart warning message as a chat message.", FCVAR_NONE, true, 0.0, true, 1.0);
	CreateTimer(1.0, CheckTime, _, TIMER_REPEAT);
}

stock bool:IsValidPlayer(client)
{
	if ((client < 1) || (client > MaxClients))
	{
		return false;
	}
	if (IsClientInGame(client))
	{
		if (IsFakeClient(client))
		{
			return false;
		}
		if (IsClientSourceTV(client) || IsClientReplay(client))
		{
			return false;
		}
		if (GetClientTeam(client) < 2)	//No team or spectator
		{
			return false;
		}
	}
	else	//Client is not in the game
	{
		return false;
	}
	return true;
}

public Action:CheckTime(Handle:timer)
{
	if (GetConVarBool(hEnable) == false)
	{
		return;
	}
	if (InRestartCountdown)	//We are already going to be restarting, but we are busy still letting players know before we actually do.
	{
		return;
	}
	if (GetEngineTime() >= GetConVarInt(hUpTime_Max))	//It has been far too long. A server restart must happen.
	{
		BeginServerRestart();
		return;
	}
	if (GetEngineTime() >= GetConVarInt(hUpTime_Min))
	{
		if (GetGameTime() < 60.0)	//Give time for server to fill. It only just started a new map and might have had enough players.
		{
			iIdleTime++;	//GameTime will not start incrementing without at least 1 player, so we must account for that scenario.
			if (iIdleTime < 60)	//We have been not been idle for long enough. Someone might be coming.
			{
				return;
			}
		}
		else
		{
			iIdleTime = 0;
		}
		new TotalActivePlayers;
		for (new client = 1; client <= MaxClients; client++)
		{
			if (IsValidPlayer(client))
			{
				TotalActivePlayers++;
			}
		}
		if (TotalActivePlayers >= GetConVarInt(hMaxPlayers))
		{
			return;
		}
		else
		{
			BeginServerRestart();
			return;
		}
	}
	return;
}

public OnMapEnd()
{
	if (GetConVarBool(hEnable) == false)
	{
		return;
	}
	if (InRestartCountdown)
	{
		LogMessage("Server restart using \"Server UpTime Restarter\" on map end...");
		ServerCommand("_restart");
	}
}

//=================================//
//- Chain of timers for countdown -//


public BeginServerRestart()
{
	InRestartCountdown = true;
	if (GetConVarBool(hWarn_ShowChat))
	{
		PrintToChatAll("\x03SUR: \x04Server will perform scheduled restart in 60 seconds.");
	}
	CreateTimer(30.0, ServerRestartThirty);
}

public Action:ServerRestartThirty(Handle:timer)
{
	if (GetConVarBool(hEnable))
	{
		if (GetConVarBool(hWarn_ShowChat))
		{
			PrintToChatAll("\x03SUR: \x04Server will perform scheduled restart in 30 seconds.");
		}
		CreateTimer(20.0, ServerRestartTen);
	}
	else
	{
		InRestartCountdown = false;
	}
}

public Action:ServerRestartTen(Handle:timer)
{
	if (GetConVarBool(hEnable))
	{
		if (GetConVarBool(hWarn_ShowChat))
		{
			PrintToChatAll("\x03SUR: \x04Server will perform scheduled restart in TEN seconds.");
		}
		CreateTimer(5.0, ServerRestartFive);
	}
	else
	{
		InRestartCountdown = false;
	}
}

public Action:ServerRestartFive(Handle:timer)
{
	if (GetConVarBool(hEnable))
	{
		if (GetConVarBool(hWarn_ShowChat))
		{
			PrintToChatAll("\x03SUR: \x04Server will perform scheduled restart in FIVE seconds!");
		}
		CreateTimer(4.0, ServerRestartOne);
	}
	else
	{
		InRestartCountdown = false;
	}
}

public Action:ServerRestartOne(Handle:timer)
{
	if (GetConVarBool(hEnable))
	{
		if (GetConVarBool(hWarn_ShowChat))
		{
			PrintToChatAll("\x03SUR: \x04Server will now restart!");
		}
		CreateTimer(1.0, ServerRestartZero);
	}
	else
	{
		InRestartCountdown = false;
	}
}

public Action:ServerRestartZero(Handle:timer)
{
	if (GetConVarBool(hEnable))
	{
		LogMessage("Server restart using \"Server UpTime Restarter\"...");
		ServerCommand("_restart");
	}
	else
	{
		InRestartCountdown = false;
	}
}
CoolJosh3k is offline
Bugsy
AMX Mod X Moderator
Join Date: Feb 2005
Location: NJ, USA
Old 07-18-2022 , 03:04   Re: [TF2] Quick plugin review before I submit
Reply With Quote #2

Moved to SM
__________________
Bugsy is offline
CoolJosh3k
AlliedModders Donor
Join Date: Mar 2010
Old 07-18-2022 , 03:51   Re: [TF2] Quick plugin review before I submit
Reply With Quote #3

Quote:
Originally Posted by Bugsy View Post
Moved to SM
Whoops. Sorry about that.

I did not even notice I was under the AMX section due to how things are laid out.
CoolJosh3k is offline
FlaminSarge
Veteran Member
Join Date: Jul 2010
Old 07-19-2022 , 19:31   Re: [TF2] Quick plugin review before I submit
Reply With Quote #4

This jitter is probably because the server GameTime value gets very high and starts to experience floating point imprecision. This video takes it to an extreme, but it's a similar deal.
I thought that a simple mapchange fixes this, rather than a restart? I didn't think this issue affected EngineTime, either.
__________________
Bread EOTL GunMettle Invasion Jungle Inferno will break everything. Don't even ask.

All plugins: Randomizer/GiveWeapon, ModelManager, etc.
Post in plugin threads with questions.
Steam is for playing games.
You will be fed to javalia otherwise.
Psyduck likes replays.
FlaminSarge is offline
CoolJosh3k
AlliedModders Donor
Join Date: Mar 2010
Old 07-19-2022 , 23:59   Re: [TF2] Quick plugin review before I submit
Reply With Quote #5

Quote:
Originally Posted by FlaminSarge View Post
This jitter is probably because the server GameTime value gets very high and starts to experience floating point imprecision. This video takes it to an extreme, but it's a similar deal.
I thought that a simple mapchange fixes this, rather than a restart? I didn't think this issue affected EngineTime, either.
A floating point error makes perfect sense.
Of course back in 2017, when I wrote this, I probably didn't even know what a floating point was!

Simply changing the map is probably a better solution, but I figure a restart is going to possibly catch other issues that might also exist on a server. The one downside I can think of for a restart, is that it creates a whole new log file.

Once the basic functionality is public as an actual plugin, I'd be very welcoming if anyone wanted to update it an add the ability to initiate a map change instead. Of course this does open questions about which map and how to decide.

I would assume then that there are no obvious issues. I am inclined to submit this as an actual public-ready plugin then soon.
CoolJosh3k is offline
FlaminSarge
Veteran Member
Join Date: Jul 2010
Old 08-03-2022 , 17:11   Re: [TF2] Quick plugin review before I submit
Reply With Quote #6

Quote:
Originally Posted by CoolJosh3k View Post
Of course this does open questions about which map and how to decide.
...The current map, maybe?

It may be worth having this plugin check GameTime/EngineTime is a very high actual value (one that would have floating point imprecision) before doing any changes. That could probably be accomplished by having the default value of each of the time cvars just be ridiculously high (ideally just before server starts getting really bad FP imprecision).

Potential concern would be whether float to int comparison (GetEngineTime() >= (cvar int value)) has trouble when either side of the comparison may be a ridiculously high value.
__________________
Bread EOTL GunMettle Invasion Jungle Inferno will break everything. Don't even ask.

All plugins: Randomizer/GiveWeapon, ModelManager, etc.
Post in plugin threads with questions.
Steam is for playing games.
You will be fed to javalia otherwise.
Psyduck likes replays.

Last edited by FlaminSarge; 08-03-2022 at 17:15.
FlaminSarge is offline
CoolJosh3k
AlliedModders Donor
Join Date: Mar 2010
Old 08-04-2022 , 23:43   Re: [TF2] Quick plugin review before I submit
Reply With Quote #7

Quote:
Originally Posted by FlaminSarge View Post
...The current map, maybe?

It may be worth having this plugin check GameTime/EngineTime is a very high actual value (one that would have floating point imprecision) before doing any changes. That could probably be accomplished by having the default value of each of the time cvars just be ridiculously high (ideally just before server starts getting really bad FP imprecision).

Potential concern would be whether float to int comparison (GetEngineTime() >= (cvar int value)) has trouble when either side of the comparison may be a ridiculously high value.
While I do assume it is floating error related (as well as others like yourself), I can't know for sure.

I expect if only ever treated as a float, then it is possible to detect when an error would have occurred. I think though that having it be some regular, predictable outcome that a server operator can configure is quite useful.

I have since released this plugin in a more official capacity, as per this thread: https://forums.alliedmods.net/showthread.php?t=338903

There are certainly a few things that could be added to make this plugin more flexible, but the base functionality and solution is all there.

It is my hope that by sharing this really old solution of mine, that others in the community might get some use out of it.
CoolJosh3k is offline
Marttt
Veteran Member
Join Date: Jan 2019
Location: Brazil
Old 08-05-2022 , 11:37   Re: [TF2] Quick plugin review before I submit
Reply With Quote #8

use new syntax: https://wiki.alliedmods.net/SourcePa...itional_Syntax
__________________
Marttt is offline
CoolJosh3k
AlliedModders Donor
Join Date: Mar 2010
Old 08-06-2022 , 23:42   Re: [TF2] Quick plugin review before I submit
Reply With Quote #9

Quote:
Originally Posted by Marttt View Post
If I write a plugin again, I will certainly do so. This one was originally written quite a few years ago.
CoolJosh3k 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 15:46.


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