From f44f9eeaab4ee31981d89f11b301f6d867d37dc6 Mon Sep 17 00:00:00 2001 From: BotoX Date: Sun, 26 Feb 2017 00:26:38 +0100 Subject: [PATCH] Add AutoRecorder --- AutoRecorder/scripting/AutoRecorder.sp | 204 +++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 AutoRecorder/scripting/AutoRecorder.sp diff --git a/AutoRecorder/scripting/AutoRecorder.sp b/AutoRecorder/scripting/AutoRecorder.sp new file mode 100644 index 00000000..b2f2f284 --- /dev/null +++ b/AutoRecorder/scripting/AutoRecorder.sp @@ -0,0 +1,204 @@ +#pragma semicolon 1 +#include + +ConVar g_hTvEnabled; +ConVar g_hAutoRecord; +ConVar g_hMinPlayersStart; +ConVar g_hIgnoreBots; +ConVar g_hTimeStart; +ConVar g_hTimeStop; +ConVar g_hFinishMap; +ConVar g_hDemoPath; + +bool g_bIsRecording = false; +bool g_bIsManual = false; + +// Default: o=rx,g=rx,u=rwx | 755 +#define DIRECTORY_PERMISSIONS (FPERM_O_READ|FPERM_O_EXEC | FPERM_G_READ|FPERM_G_EXEC | FPERM_U_READ|FPERM_U_WRITE|FPERM_U_EXEC) + +public Plugin myinfo = +{ + name = "Auto Recorder", + author = "Stevo.TVR", + description = "Automates SourceTV recording based on player count and time of day.", + version = "1.2.0", + url = "http://www.theville.org" +} + +public void OnPluginStart() +{ + g_hAutoRecord = CreateConVar("sm_autorecord_enable", "1", "Enable automatic recording", _, true, 0.0, true, 1.0); + g_hMinPlayersStart = CreateConVar("sm_autorecord_minplayers", "4", "Minimum players on server to start recording", _, true, 0.0); + g_hIgnoreBots = CreateConVar("sm_autorecord_ignorebots", "1", "Ignore bots in the player count", _, true, 0.0, true, 1.0); + g_hTimeStart = CreateConVar("sm_autorecord_timestart", "-1", "Hour in the day to start recording (0-23, -1 disables)"); + g_hTimeStop = CreateConVar("sm_autorecord_timestop", "-1", "Hour in the day to stop recording (0-23, -1 disables)"); + g_hFinishMap = CreateConVar("sm_autorecord_finishmap", "1", "If 1, continue recording until the map ends", _, true, 0.0, true, 1.0); + g_hDemoPath = CreateConVar("sm_autorecord_path", "demos/", "Path to store recorded demos"); + + AutoExecConfig(true, "autorecorder"); + + RegAdminCmd("sm_record", Command_Record, ADMFLAG_KICK, "Starts a SourceTV demo"); + RegAdminCmd("sm_stoprecord", Command_StopRecord, ADMFLAG_KICK, "Stops the current SourceTV demo"); + + g_hTvEnabled = FindConVar("tv_enable"); + + static char sPath[PLATFORM_MAX_PATH]; + GetConVarString(g_hDemoPath, sPath, sizeof(sPath)); + + if(!DirExists(sPath)) + CreateDirectory(sPath, DIRECTORY_PERMISSIONS); + + HookConVarChange(g_hMinPlayersStart, OnConVarChanged); + HookConVarChange(g_hIgnoreBots, OnConVarChanged); + HookConVarChange(g_hTimeStart, OnConVarChanged); + HookConVarChange(g_hTimeStop, OnConVarChanged); + HookConVarChange(g_hDemoPath, OnConVarChanged); + + CreateTimer(300.0, Timer_CheckStatus, _, TIMER_REPEAT); + + StopRecord(); + CheckStatus(); +} + +public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue) +{ + if(convar == g_hDemoPath) + { + if(!DirExists(newValue)) + CreateDirectory(newValue, DIRECTORY_PERMISSIONS); + } + else + CheckStatus(); +} + +public void OnMapEnd() +{ + if(g_bIsRecording) + { + StopRecord(); + g_bIsManual = false; + } +} + +public void OnClientPutInServer(int client) +{ + CheckStatus(); +} + +public void OnClientDisconnect_Post(int client) +{ + CheckStatus(); +} + +public Action Timer_CheckStatus(Handle hTimer) +{ + CheckStatus(); +} + +public Action Command_Record(int client, int args) +{ + if(g_bIsRecording) + { + ReplyToCommand(client, "[SM] SourceTV is already recording!"); + return Plugin_Handled; + } + + StartRecord(); + g_bIsManual = true; + + ReplyToCommand(client, "[SM] SourceTV is now recording..."); + + return Plugin_Handled; +} + +public Action Command_StopRecord(int client, int args) +{ + if(!g_bIsRecording) + { + ReplyToCommand(client, "[SM] SourceTV is not recording!"); + return Plugin_Handled; + } + + StopRecord(); + + if(g_bIsManual) + { + g_bIsManual = false; + CheckStatus(); + } + + ReplyToCommand(client, "[SM] Stopped recording."); + + return Plugin_Handled; +} + +void CheckStatus() +{ + if(GetConVarBool(g_hAutoRecord) && !g_bIsManual) + { + int iMinClients = GetConVarInt(g_hMinPlayersStart); + + int iTimeStart = GetConVarInt(g_hTimeStart); + int iTimeStop = GetConVarInt(g_hTimeStop); + bool bReverseTimes = (iTimeStart > iTimeStop); + + static char sCurrentTime[4]; + FormatTime(sCurrentTime, sizeof(sCurrentTime), "%H", GetTime()); + int iCurrentTime = StringToInt(sCurrentTime); + + if(GetPlayerCount() >= iMinClients+1 && (iTimeStart < 0 || (iCurrentTime >= iTimeStart && (bReverseTimes || iCurrentTime < iTimeStop)))) + { + StartRecord(); + } + else if(g_bIsRecording && !GetConVarBool(g_hFinishMap) && (iTimeStop < 0 || iCurrentTime >= iTimeStop)) + { + StopRecord(); + } + } +} + +int GetPlayerCount() +{ + if(!GetConVarBool(g_hIgnoreBots)) + return GetClientCount(false) - 1; + + int iNumPlayers = 0; + for(int i = 1; i <= MaxClients; i++) + { + if(IsClientConnected(i) && !IsFakeClient(i)) + iNumPlayers++; + } + + return iNumPlayers; +} + +void StartRecord() +{ + if(GetConVarBool(g_hTvEnabled) && !g_bIsRecording) + { + static char sPath[PLATFORM_MAX_PATH]; + static char sMap[PLATFORM_MAX_PATH]; + static char sTime[16]; + + GetConVarString(g_hDemoPath, sPath, sizeof(sPath)); + FormatTime(sTime, sizeof(sTime), "%Y%m%d-%H%M%S", GetTime()); + GetCurrentMap(sMap, sizeof(sMap)); + + // replace slashes in map path name with dashes, to prevent fail on workshop maps + ReplaceString(sMap, sizeof(sMap), "/", "-", false); + + ServerCommand("tv_record \"%s/auto-%s-%s\"", sPath, sTime, sMap); + g_bIsRecording = true; + + LogMessage("Recording to auto-%s-%s.dem", sTime, sMap); + } +} + +void StopRecord() +{ + if(GetConVarBool(g_hTvEnabled)) + { + ServerCommand("tv_stoprecord"); + g_bIsRecording = false; + } +}