C#:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Rust;
#region Changelogs and ToDo
/**********************************************************************
*
* 1.0.0 - Beta Release
* 1.0.1 - Optimised delays
* 1.1.0 - Removed Linq usage
* - Added timer cleanup on unload
* - Auto unload plugin when finished / empty list (Carbon/Oxide)
* 1.1.1 - Fixed Oxide command execution compatibility
* - Replaced server.Command with ConsoleSystem.Run
* - Added config null protection
*
**********************************************************************/
#endregion
namespace Oxide.Plugins
{
[Info("ExecuteAfterStartup" , "Krungh Crow" , "1.1.1")]
[Description("Execute listed commands after a server restart")]
class ExecuteAfterStartup : RustPlugin
{
#region Variables
private Timer executeTimer;
private Timer initCheckTimer;
private Timer startDelayTimer;
private List<string> commandsToExecute = new List<string>();
private int commandIndex;
private enum ExecutionState
{
Initializing,
Executing,
Finished
}
private ExecutionState executionState = ExecutionState.Initializing;
#endregion
#region Configuration
private ConfigData configData;
private class ConfigData
{
[JsonProperty(PropertyName = "Command settings")]
public Settings CommandSettings = new Settings();
}
private class Settings
{
[JsonProperty(PropertyName = "Time After Startup (seconds)")]
public float StartR = 20f;
[JsonProperty(PropertyName = "Time between Command Execution (seconds)")]
public float StartBC = 2f;
[JsonProperty(PropertyName = "Commands to Execute")]
public List<string> CommandList = new List<string>();
}
void Init()
{
if (!LoadConfigVariables())
{
Puts("Config file issue detected. Please delete file, or check syntax and fix.");
return;
}
}
private bool LoadConfigVariables()
{
try
{
configData = Config.ReadObject<ConfigData>();
if (configData == null)
{
Puts("Config file is empty or in an invalid format.");
return false;
}
if (configData.CommandSettings == null)
configData.CommandSettings = new Settings();
if (configData.CommandSettings.CommandList == null)
configData.CommandSettings.CommandList = new List<string>();
}
catch (JsonException ex)
{
Puts($"Error loading configuration: {ex.Message}");
return false;
}
catch (Exception ex)
{
Puts($"Unexpected config error: {ex.Message}");
return false;
}
SaveConfig();
return true;
}
protected override void LoadDefaultConfig()
{
PrintWarning("Fresh install detected. Creating a new config file.");
configData = new ConfigData();
SaveConfig();
}
void SaveConfig() => Config.WriteObject(configData , true);
#endregion
#region Hooks
void OnServerInitialized(bool initial)
{
if (!initial)
{
Puts("Server already initialized. Skipping execution sequence.");
NextTick(UnloadSelf);
return;
}
executionState = ExecutionState.Initializing;
StopAllTimers();
CheckInitialization();
}
void Unload()
{
StopAllTimers();
}
#endregion
#region Core
void CheckInitialization()
{
initCheckTimer = timer.Once(10f , () =>
{
if (executionState != ExecutionState.Initializing)
return;
if (Rust.Application.isLoading)
{
Puts("Server still loading....");
CheckInitialization();
return;
}
StartAfterDelay();
});
}
void StartAfterDelay()
{
if (configData == null || configData.CommandSettings == null)
{
Puts("Configuration was not loaded correctly.");
executionState = ExecutionState.Finished;
NextTick(UnloadSelf);
return;
}
float timeAfterStartup = configData.CommandSettings.StartR;
commandsToExecute = new List<string>(configData.CommandSettings.CommandList ?? new List<string>());
commandIndex = 0;
if (commandsToExecute.Count == 0)
{
Puts("No commands listed to execute.");
executionState = ExecutionState.Finished;
NextTick(UnloadSelf);
return;
}
startDelayTimer = timer.Once(timeAfterStartup , () =>
{
if (executionState != ExecutionState.Initializing)
return;
ExecuteCommandsStateMachine(configData.CommandSettings.StartBC);
});
}
void ExecuteCommandsStateMachine(float timeBetweenCommands)
{
switch (executionState)
{
case ExecutionState.Initializing:
Puts("Starting Command Execution sequence....");
executionState = ExecutionState.Executing;
StopExecuteTimer();
executeTimer = timer.Repeat(timeBetweenCommands , 0 , () =>
{
if (executionState != ExecutionState.Executing)
{
StopExecuteTimer();
return;
}
if (commandIndex >= commandsToExecute.Count)
{
StopExecuteTimer();
executionState = ExecutionState.Finished;
Puts($"Command Execution Finished for {commandsToExecute.Count} command(s)....");
NextTick(UnloadSelf);
return;
}
string command = commandsToExecute[commandIndex];
commandIndex++;
if (string.IsNullOrWhiteSpace(command))
return;
Puts($"Executing command: {command}");
ConsoleSystem.Run(ConsoleSystem.Option.Server , command);
});
break;
case ExecutionState.Executing:
case ExecutionState.Finished:
break;
}
}
void UnloadSelf()
{
Puts($"Unloading {Name} to save server resources");
#if CARBON
ConsoleSystem.Run(ConsoleSystem.Option.Server, $"c.unload {Name}");
#else
ConsoleSystem.Run(ConsoleSystem.Option.Server , $"o.unload {Name}");
#endif
}
void StopExecuteTimer()
{
if (executeTimer != null && !executeTimer.Destroyed)
executeTimer.Destroy();
executeTimer = null;
}
void StopAllTimers()
{
if (executeTimer != null && !executeTimer.Destroyed)
executeTimer.Destroy();
if (initCheckTimer != null && !initCheckTimer.Destroyed)
initCheckTimer.Destroy();
if (startDelayTimer != null && !startDelayTimer.Destroyed)
startDelayTimer.Destroy();
executeTimer = null;
initCheckTimer = null;
startDelayTimer = null;
}
#endregion
}
}