228 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #pragma semicolon 1
 | |
| #include <sourcemod>
 | |
| 
 | |
| 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_bRestartRecording = false;
 | |
| bool g_bIsRecording = false;
 | |
| bool g_bIsManual = false;
 | |
| 
 | |
| int g_iRestartRecording;
 | |
| 
 | |
| // 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");
 | |
| 
 | |
| 	HookEvent("round_start", OnRoundStart);
 | |
| 
 | |
| 	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 OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast)
 | |
| {
 | |
| 	if(g_bRestartRecording && g_iRestartRecording <= GetTime())
 | |
| 	{
 | |
| 		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;
 | |
| 
 | |
| 		g_bRestartRecording = false;
 | |
| 		g_iRestartRecording = -1;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 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);
 | |
| 
 | |
| 		g_bRestartRecording = true;
 | |
| 		g_iRestartRecording = GetTime() + 1800;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void StopRecord()
 | |
| {
 | |
| 	if(GetConVarBool(g_hTvEnabled))
 | |
| 	{
 | |
| 		ServerCommand("tv_stoprecord");
 | |
| 		g_bIsRecording = false;
 | |
| 
 | |
| 		g_bRestartRecording = false;
 | |
| 		g_iRestartRecording = -1;
 | |
| 	}
 | |
| }
 |