437 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			437 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #include <sourcemod>
 | |
| #include <files>
 | |
| #include <mapchooser_extended>
 | |
| #include <multicolors>
 | |
| 
 | |
| #pragma semicolon 1
 | |
| #pragma newdecls required
 | |
| 
 | |
| float g_fCumulativeUptime;
 | |
| 
 | |
| bool g_bRestart;
 | |
| 
 | |
| ConVar g_cvarDefaultMap;
 | |
| ConVar g_cvarMaxUptime;
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public Plugin myinfo =
 | |
| {
 | |
| 	name        = "RestartManager",
 | |
| 	author      = "Dogan + Neon",
 | |
| 	description = "Display Server Uptime and do controlled Restarts",
 | |
| 	version     = "2.0.1",
 | |
| 	url         = ""
 | |
| };
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void OnPluginStart()
 | |
| {
 | |
| 	RegAdminCmd("uptime", Command_Uptime, ADMFLAG_GENERIC, "Displays server Uptime");
 | |
| 	RegAdminCmd("sm_uptime", Command_Uptime, ADMFLAG_GENERIC, "Displays server Uptime");
 | |
| 	RegAdminCmd("sm_forcerestart", Command_ForceRestart, ADMFLAG_RCON, "Force-restarts the server");
 | |
| 
 | |
| 	g_cvarDefaultMap = CreateConVar("sm_defaultmap", "ze_atix_panic_b3t", "default map of the server");
 | |
| 	g_cvarMaxUptime = CreateConVar("sm_maxuptime", "68", "Uptime in hours after which the server should be restarted", FCVAR_NONE);
 | |
| 	AutoExecConfig(true);
 | |
| 
 | |
| 	GetUptimeIfControlledRestart();
 | |
| 
 | |
| 
 | |
| 	RegServerCmd("changelevel", BlockMapSwitch);
 | |
| 
 | |
| 	CreateTimer(60.0, CheckForRestart, _, TIMER_REPEAT);
 | |
| 	CreateTimer(60.0, ForceRestartMessage, _, TIMER_REPEAT);
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void OnConfigsExecuted()
 | |
| {
 | |
| 	char sDefaultMap[64];
 | |
| 	g_cvarDefaultMap.GetString(sDefaultMap, sizeof(sDefaultMap));
 | |
| 	SetStartMap(sDefaultMap);
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public Action Command_ForceRestart(int client, int args)
 | |
| {
 | |
| 	if(client == 0)
 | |
| 	{
 | |
| 		char sMap[64];
 | |
| 		GetCurrentMap(sMap, sizeof(sMap));
 | |
| 
 | |
| 		PrepareRestart(sMap, client, true);
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	ReplyToCommand(client, "[SM] Confirm the force-restart please!");
 | |
| 	OpenAdminPanel(client);
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public Action Command_Uptime(int client, int args)
 | |
| {
 | |
| 	float fUptime = GetEngineTime();
 | |
| 	char sUptime[64];
 | |
| 	int iUptime = RoundFloat(fUptime);
 | |
| 
 | |
| 	int iDays    	= (iUptime / 86400);
 | |
| 	int iHours   	= (iUptime / 3600) % 24;
 | |
| 	int iMinutes	= (iUptime / 60) % 60;
 | |
| 	int iSeconds	= (iUptime % 60);
 | |
| 
 | |
| 	if (iDays)
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Days %d Hours %d Minutes %d Seconds.", iDays, iHours, iMinutes, iSeconds);
 | |
| 	else if (iHours)
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Hours %d Minutes %d Seconds.", iHours, iMinutes, iSeconds);
 | |
| 	else if (iMinutes)
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Minutes %d Seconds.", iMinutes, iSeconds);
 | |
| 	else
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Seconds.", iSeconds);
 | |
| 
 | |
| 	ReplyToCommand(client, "[SM] Real Server Uptime: %s", sUptime);
 | |
| 
 | |
| 	fUptime = GetEngineTime() + g_fCumulativeUptime;
 | |
| 	iUptime = RoundFloat(fUptime);
 | |
| 
 | |
| 	iDays    = (iUptime / 86400);
 | |
| 	iHours   = (iUptime / 3600) % 24;
 | |
| 	iMinutes = (iUptime / 60) % 60;
 | |
| 	iSeconds = (iUptime % 60);
 | |
| 
 | |
| 	if (iDays)
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Days %d Hours %d Minutes %d Seconds.", iDays, iHours, iMinutes, iSeconds);
 | |
| 	else if (iHours)
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Hours %d Minutes %d Seconds.", iHours, iMinutes, iSeconds);
 | |
| 	else if (iMinutes)
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Minutes %d Seconds.", iMinutes, iSeconds);
 | |
| 	else
 | |
| 		Format(sUptime, sizeof(sUptime), "%d Seconds.", iSeconds);
 | |
| 
 | |
| 	ReplyToCommand(client, "[SM] Cumulative Server Uptime: %s", sUptime);
 | |
| 
 | |
| 	IsItTimeToRestartForced();
 | |
| 	if (g_bRestart)
 | |
| 		ReplyToCommand(client, "[SM] Server is going to restart on next mapswitch.");
 | |
| 	else
 | |
| 		ReplyToCommand(client, "[SM] Time until next force-restart: %.2fh.", ((g_cvarMaxUptime.FloatValue * 3600.0) - GetEngineTime()) / 3600.0);
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void OpenAdminPanel(int client)
 | |
| {
 | |
| 	Menu menu = new Menu(MenuHandler_MainMenu);
 | |
| 
 | |
| 	menu.SetTitle("Are you sure you want to force-restart the server?", client);
 | |
| 
 | |
| 	char sBuffer[32];
 | |
| 
 | |
| 	Format(sBuffer, sizeof(sBuffer), "Yes.");
 | |
| 	menu.AddItem("0", sBuffer);
 | |
| 
 | |
| 	Format(sBuffer, sizeof(sBuffer), "No.");
 | |
| 	menu.AddItem("1", sBuffer);
 | |
| 
 | |
| 	menu.Display(client, MENU_TIME_FOREVER);
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public int MenuHandler_MainMenu(Menu menu, MenuAction action, int client, int selection)
 | |
| {
 | |
| 	char sMap[64];
 | |
| 	GetCurrentMap(sMap, sizeof(sMap));
 | |
| 
 | |
| 	switch(action)
 | |
| 	{
 | |
| 		case(MenuAction_Select):
 | |
| 		{
 | |
| 			switch(selection)
 | |
| 			{
 | |
| 				case(0): PrepareRestart(sMap, client, true);
 | |
| 				case(1): PrintToChat(client, "[SM] You declined the force-restart.");
 | |
| 			}
 | |
| 		}
 | |
| 		case(MenuAction_Cancel):
 | |
| 		{
 | |
| 			PrintToChat(client, "[SM] You declined the force-restart.");
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public Action CheckForRestart(Handle timer)
 | |
| {
 | |
| 	int iPlayers = GetClientCount(false);
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsClientConnected(i) && IsFakeClient(i))
 | |
| 			iPlayers--;
 | |
| 	}
 | |
| 
 | |
| 	if((iPlayers <= 8) && IsItTimeToRestartNight())
 | |
| 	{
 | |
| 		PrepareRestartNight();
 | |
| 		return Plugin_Stop;
 | |
| 	}
 | |
| 
 | |
| 	if(IsItTimeToRestartForced())
 | |
| 		return Plugin_Stop;
 | |
| 
 | |
| 	return Plugin_Continue;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| stock bool IsItTimeToRestartNight()
 | |
| {
 | |
| 	if (GetEngineTime() < (3600 * 12))
 | |
| 		return false;
 | |
| 
 | |
| 	int iTime = GetTime();
 | |
| 	int iHour;
 | |
| 	char sTime[32];
 | |
| 
 | |
| 	FormatTime(sTime, sizeof(sTime), "%H", iTime);
 | |
| 
 | |
| 	iHour = StringToInt(sTime[0]);
 | |
| 
 | |
| 	if (iHour >= 3 && iHour < 6)
 | |
| 		return true;
 | |
| 
 | |
| 	return false;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public bool IsItTimeToRestartForced()
 | |
| {
 | |
| 	if(g_bRestart)
 | |
| 		return true;
 | |
| 
 | |
| 	if(GetEngineTime() < (g_cvarMaxUptime.FloatValue * 3600.0))
 | |
| 		return false;
 | |
| 
 | |
| 	g_bRestart = true;
 | |
| 	return true;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void PrepareRestart(char[] sMap, int client, bool bAdmin)
 | |
| {
 | |
| 	g_fCumulativeUptime += GetEngineTime();
 | |
| 
 | |
| 	char sUptime[64];
 | |
| 	FloatToString(g_fCumulativeUptime, sUptime, sizeof(sUptime));
 | |
| 	File UptimeFile = OpenFile("uptime.txt", "w");
 | |
| 	UptimeFile.WriteLine(sUptime);
 | |
| 	delete UptimeFile;
 | |
| 
 | |
| 	if(sMap[0])
 | |
| 	{
 | |
| 		char sMapFile[68];
 | |
| 		Format(sMapFile, sizeof(sMapFile), "map %s", sMap);
 | |
| 		DeleteFile("cfg/defaultmap.cfg");
 | |
| 		File NextmapFile = OpenFile("cfg/defaultmap.cfg", "w");
 | |
| 		NextmapFile.WriteLine(sMapFile);
 | |
| 		delete NextmapFile;
 | |
| 	}
 | |
| 
 | |
| 	if(bAdmin)
 | |
| 	{
 | |
| 		LogToFile("addons/sourcemod/logs/restarts.log", "%N successfully force-restarted the Server.", client);
 | |
| 		PrintToChat(client, "[SM] You confirmed the force-restart.");
 | |
| 
 | |
| 		CPrintToChatAll("{red}WARNING:{white} Restarting Server in 8 Seconds!");
 | |
| 		CPrintToChatAll("{red}WARNING:{white} Restarting Server in 8 Seconds");
 | |
| 		CPrintToChatAll("{red}WARNING:{white} You may disconnect, reconnect if necessary!");
 | |
| 		PrintCenterTextAll("WARNING: Restarting Server in 8 Seconds.");
 | |
| 
 | |
| 		Panel hNotifyPanel = new Panel(GetMenuStyleHandle(MenuStyle_Radio));
 | |
| 		hNotifyPanel.DrawItem("WARNING: Restarting Server in 8 Seconds.", ITEMDRAW_RAWLINE);
 | |
| 		hNotifyPanel.DrawItem("", ITEMDRAW_SPACER);
 | |
| 		hNotifyPanel.DrawItem("IMPORTANT: You may disconnect, reconnect if necessary!", ITEMDRAW_RAWLINE);
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 			hNotifyPanel.Send(client, MenuHandler_NotifyPanel, 8);
 | |
| 		}
 | |
| 		delete hNotifyPanel;
 | |
| 
 | |
| 		CreateTimer(8.0, AdminForceRestart);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		SimulateMapEnd();
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 			if(IsClientConnected(i) && !IsFakeClient(i))
 | |
| 				ClientCommand(i, "retry");
 | |
| 		}
 | |
| 
 | |
| 		LogToFile("addons/sourcemod/logs/restarts.log", "Successfully force-restarted the Server.");
 | |
| 		RequestFrame(Restart);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| int MenuHandler_NotifyPanel(Menu hMenu, MenuAction iAction, int iParam1, int iParam2)
 | |
| {
 | |
| 	switch (iAction)
 | |
| 	{
 | |
| 		case MenuAction_Select, MenuAction_Cancel:
 | |
| 			delete hMenu;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void PrepareRestartNight()
 | |
| {
 | |
| 	g_fCumulativeUptime += GetEngineTime();
 | |
| 
 | |
| 	char sUptime[64];
 | |
| 	FloatToString(g_fCumulativeUptime, sUptime, sizeof(sUptime));
 | |
| 	File UptimeFile = OpenFile("uptime.txt", "w");
 | |
| 	UptimeFile.WriteLine(sUptime);
 | |
| 	delete UptimeFile;
 | |
| 
 | |
| 	char sMap[64];
 | |
| 	GetCurrentMap(sMap, sizeof(sMap));
 | |
| 	char sMapFile[68];
 | |
| 	Format(sMapFile, sizeof(sMapFile), "map %s", sMap);
 | |
| 	DeleteFile("cfg/defaultmap.cfg");
 | |
| 	File NextmapFile = OpenFile("cfg/defaultmap.cfg", "w");
 | |
| 	NextmapFile.WriteLine(sMapFile);
 | |
| 	delete NextmapFile;
 | |
| 
 | |
| 	SimulateMapEnd();
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsClientConnected(i) && !IsFakeClient(i))
 | |
| 			ClientCommand(i, "retry");
 | |
| 	}
 | |
| 	LogToFile("addons/sourcemod/logs/restarts.log", "Successfully night-restarted the Server.");
 | |
| 	RequestFrame(Restart);
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void Restart()
 | |
| {
 | |
| 	ServerCommand("_restart");
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public Action BlockMapSwitch(int args)
 | |
| {
 | |
| 	if (!g_bRestart)
 | |
| 		return Plugin_Continue;
 | |
| 
 | |
| 	char sMap[64];
 | |
| 	GetCmdArg(1, sMap, sizeof(sMap));
 | |
| 	PrepareRestart(sMap, 0, false);
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void GetUptimeIfControlledRestart()
 | |
| {
 | |
| 	File UptimeFile = OpenFile("uptime.txt", "r");
 | |
| 
 | |
| 	if(UptimeFile != null)//Server was restarted automatically by this plugin or an admin
 | |
| 	{
 | |
| 		char sUptime[64];
 | |
| 		UptimeFile.ReadLine(sUptime, sizeof(sUptime));
 | |
| 		g_fCumulativeUptime = StringToFloat(sUptime);
 | |
| 		delete UptimeFile;
 | |
| 		DeleteFile("uptime.txt");
 | |
| 	}
 | |
| 	else//Server crashed or restarted manually
 | |
| 		LogToFile("addons/sourcemod/logs/restarts.log", "Server crashed.");
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public void SetStartMap(char[] sMap)
 | |
| {
 | |
| 	DeleteFile("cfg/defaultmap.cfg");
 | |
| 	char sMapFile[64];
 | |
| 	Format(sMapFile, sizeof(sMapFile), "map %s", sMap);
 | |
| 	File NextmapFile = OpenFile("cfg/defaultmap.cfg", "w");
 | |
| 	NextmapFile.WriteLine(sMapFile);
 | |
| 	delete NextmapFile;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public Action ForceRestartMessage(Handle timer)
 | |
| {
 | |
| 	if(!g_bRestart)
 | |
| 		return Plugin_Continue;
 | |
| 
 | |
| 	CPrintToChatAll("{red}WARNING:{white} Restarting Server when this Map ends!");
 | |
| 	CPrintToChatAll("{red}WARNING:{white} Restarting Server when this Map ends!");
 | |
| 	CPrintToChatAll("{red}WARNING:{white} You may disconnect, reconnect if necessary!");
 | |
| 
 | |
| 	return Plugin_Continue;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| public Action AdminForceRestart(Handle timer)
 | |
| {
 | |
| 	SimulateMapEnd();
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsClientConnected(i) && !IsFakeClient(i))
 | |
| 			ClientCommand(i, "retry");
 | |
| 	}
 | |
| 
 | |
| 	RequestFrame(Restart);
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| // Purpose:
 | |
| //----------------------------------------------------------------------------------------------------
 | |
| stock int IsValidClient(int client, bool nobots = true)
 | |
| {
 | |
| 	if (client <= 0 || client > MaxClients || !IsClientConnected(client) || (nobots && IsFakeClient(client)))
 | |
| 		return false;
 | |
| 
 | |
| 	return IsClientInGame(client);
 | |
| } |