sm-plugins/RestartManager/scripting/RestartManager.sp

312 lines
9.7 KiB
SourcePawn

#include <sourcemod>
#include <files>
#include <mapchooser_extended>
#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 = "1.0.0",
url = ""
};
// TODO: SAFE command for admins to restart!!!
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart()
{
RegAdminCmd("uptime", Command_Uptime, ADMFLAG_GENERIC, "Displays server Uptime");
RegAdminCmd("sm_uptime", Command_Uptime, ADMFLAG_GENERIC, "Displays server Uptime");
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();
char sDefaultMap[64];
g_cvarDefaultMap.GetString(sDefaultMap, sizeof(sDefaultMap));
SetStartMap(sDefaultMap);
RegServerCmd("changelevel", BlockMapSwitch);
CreateTimer(60.0, CheckForRestart, _, TIMER_REPEAT);
}
//----------------------------------------------------------------------------------------------------
// 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 restart: %.2fh", ((g_cvarMaxUptime.FloatValue * 3600.0) - GetEngineTime()) / 3600.0);
return Plugin_Handled;
}
//----------------------------------------------------------------------------------------------------
// 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 <= 1) && 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 < 8)
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;
NotifyAdmins();
return true;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void PrepareRestart(char[] sMap)
{
NotifyAdmins();
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;
}
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:
//----------------------------------------------------------------------------------------------------
public void PrepareRestartNight()
{
NotifyAdmins();
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);
return Plugin_Handled;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void GetUptimeIfControlledRestart()
{
File UptimeFile = OpenFile("uptime.txt", "r");
if(UptimeFile != null)//Server was restarted automatically by this plugin
{
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 or was restarted manually.");
}
//----------------------------------------------------------------------------------------------------
// 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 void NotifyAdmins()
{
for(int i = 1; i <= MaxClients; i++)
{
if(IsValidClient(i) && CheckCommandAccess(i, "", ADMFLAG_KICK))
{
PrintToChat(i, "[SM] WARNING: Server will be restarted on mapswitch!");
PrintToChat(i, "[SM] WARNING: Server will be restarted on mapswitch!");
}
}
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
stock int IsValidClient(int client, bool nobots = true)
{
if (client <= 0 || client > MaxClients || !IsClientConnected(client) || (nobots && IsFakeClient(client)))
return false;
return IsClientInGame(client);
}