using Newtonsoft.Json; using System; using System.Collections.Generic; using UnityEngine; namespace Oxide.Plugins { [Info("SimpleEvents", "Ridamees", "0.0.2")] [Description("Set Minimum required players and custom commands for rust events.")] class SimpleEvents : RustPlugin { private ConfigFile config; private Dictionary timedCommandTimers = new Dictionary(); class ConfigFile { [JsonProperty(PropertyName = "Custom Commands Execution Mode | 1 = Sequentially, 2 = Simultaneously, 3 = Disabled")] public int ExecuteTimedCommandsMode = 1; [JsonProperty(PropertyName = "Custom Commands")] public List timedCommands = new List{}; [JsonProperty(PropertyName = "Patrol Helicopter")] public EventConfig patrolHeli = new EventConfig { MinPop = 0, Commands = new List { "", }, Prefab = "assets/prefabs/npc/patrol helicopter/patrolhelicopter.prefab" }; [JsonProperty(PropertyName = "CH47 Helicopter")] public EventConfig chinook = new EventConfig { MinPop = 0, Commands = new List { "", }, Prefab = "assets/prefabs/npc/ch47/ch47scientists.entity.prefab" }; [JsonProperty(PropertyName = "Cargo Ship")] public CargoShipConfig cargoShip = new CargoShipConfig { MinPop = 0, LootRoundsMinPop = new List(), Commands = new List { "", }, Prefab = "assets/content/vehicles/boats/cargoship/cargoshiptest.prefab" }; [JsonProperty(PropertyName = "Cargo Plane")] public EventConfig cargoPlane = new EventConfig { MinPop = 0, Commands = new List { "", }, Prefab = "assets/prefabs/npc/cargo plane/cargo_plane.prefab" }; [JsonProperty(PropertyName = "Easter Egg Hunt")] public EventConfig easterEggHunt = new EventConfig { MinPop = 0, Commands = new List { "", }, Prefab = "assets/prefabs/misc/easter/egghunt.prefab" }; [JsonProperty(PropertyName = "Santa's Sleigh")] public EventConfig santasSleigh = new EventConfig { MinPop = 0, Commands = new List { "", }, Prefab = "assets/prefabs/misc/xmas/sleigh/santasleigh.prefab" }; [JsonProperty(PropertyName = "Halloween Hunt")] public EventConfig halloweenHunt = new EventConfig { MinPop = 0, Commands = new List { "", }, Prefab = "assets/prefabs/misc/halloween/halloweenhunt.prefab" }; [JsonProperty(PropertyName = "Bradley APC")] public EventConfig bradley = new EventConfig { MinPop = 0 }; public class EventConfig { [JsonProperty(PropertyName = "Commands")] public List Commands { get; set; } [JsonProperty(PropertyName = "Min Players")] public int MinPop { get; set; } [JsonProperty(PropertyName = "Prefab")] public string Prefab { get; set; } } public class CargoShipConfig : EventConfig { [JsonProperty(PropertyName = "Noninitial LootRound Min Players")] public List LootRoundsMinPop { get; set; } public CargoShipConfig() : base() { } } public class TimedCommandConfig { [JsonProperty(PropertyName = "Commands")] public List Commands { get; set; } [JsonProperty(PropertyName = "Min Interval (s)")] public int MinInterval { get; set; } [JsonProperty(PropertyName = "Max Interval (s)")] public int MaxInterval { get; set; } [JsonProperty(PropertyName = "Min Players")] public int MinPlayers { get; set; } } public static List GetDefaultTimedCommands() { return new List { new TimedCommandConfig { Commands = new List { "", "" }, MinInterval = 60, MaxInterval = 120, MinPlayers = 0 }, new TimedCommandConfig { Commands = new List { "", "" }, MinInterval = 180, MaxInterval = 300, MinPlayers = 0 } }; } public static ConfigFile getDefaultConfigFile() { return new ConfigFile(); } } protected override void LoadConfig() { base.LoadConfig(); config = Config.ReadObject(); } protected override void LoadDefaultConfig() => config = ConfigFile.getDefaultConfigFile(); protected override void SaveConfig() => Config.WriteObject(config); private bool isConfiguredEvent(string prefabPath, ConfigFile.EventConfig config) { return prefabPath.Equals(config?.Prefab); } void Init() { LoadConfig(); initializedTimedCommands.Clear(); foreach (var timer in timedCommandTimers.Values) { timer.Destroy(); } timedCommandTimers.Clear(); if (config.timedCommands.Count == 0) { config.timedCommands = ConfigFile.GetDefaultTimedCommands(); SaveConfig(); } switch (config.ExecuteTimedCommandsMode) { case 1: StartTimedCommandsSequentially(); break; case 2: StartTimedCommandsSimultaneously(); break; case 3: // Custom Timed Commands Disabled break; default: PrintWarning("Invalid TimedCommands execution mode. Mode should be 1 (Sequentially), 2 (Simultaneously), or 3 (Disabled)."); break; } } void OnEntitySpawned(BaseNetworkable networkable) { int numberOfActivePlayers = BasePlayer.activePlayerList.Count; if (networkable is BradleyAPC) { if (numberOfActivePlayers < config.bradley.MinPop) { Puts("Killing Bradley because pop ({0}) is less than configured minimum of {1}", numberOfActivePlayers, config.bradley.MinPop); networkable.Kill(BaseNetworkable.DestroyMode.None); } } } object OnEventTrigger(TriggeredEventPrefab prefab) { string prefabPath = prefab?.targetPrefab?.resourcePath; if (prefabPath == null) { return null; } int numberOfActivePlayers = BasePlayer.activePlayerList.Count; List executedCommands = new List(); if (prefabPath == config.cargoPlane.Prefab) { executedCommands = config.cargoPlane.Commands; } else if (prefabPath == config.santasSleigh.Prefab) { executedCommands = config.santasSleigh.Commands; } else if (prefabPath == config.patrolHeli.Prefab) { executedCommands = config.patrolHeli.Commands; } else if (prefabPath == config.chinook.Prefab) { executedCommands = config.chinook.Commands; } else if (prefabPath == config.cargoShip.Prefab) { executedCommands = config.cargoShip.Commands; } else if (prefabPath == config.easterEggHunt.Prefab) { executedCommands = config.easterEggHunt.Commands; } else if (prefabPath == config.halloweenHunt.Prefab) { executedCommands = config.halloweenHunt.Commands; } foreach (string command in executedCommands) { if (isConfiguredEvent(prefabPath, config.cargoPlane) && numberOfActivePlayers >= config.cargoPlane.MinPop) { ExecuteConsoleCommand(command); } else if (isConfiguredEvent(prefabPath, config.santasSleigh) && numberOfActivePlayers >= config.santasSleigh.MinPop) { ExecuteConsoleCommand(command); } else if (isConfiguredEvent(prefabPath, config.patrolHeli) && numberOfActivePlayers >= config.patrolHeli.MinPop) { ExecuteConsoleCommand(command); } else if (isConfiguredEvent(prefabPath, config.chinook) && numberOfActivePlayers >= config.chinook.MinPop) { ExecuteConsoleCommand(command); } else if (isConfiguredEvent(prefabPath, config.cargoShip) && numberOfActivePlayers >= config.cargoShip.MinPop) { ExecuteConsoleCommand(command); } else if (isConfiguredEvent(prefabPath, config.easterEggHunt) && numberOfActivePlayers >= config.easterEggHunt.MinPop) { ExecuteConsoleCommand(command); } else if (isConfiguredEvent(prefabPath, config.halloweenHunt) && numberOfActivePlayers >= config.halloweenHunt.MinPop) { ExecuteConsoleCommand(command); } } if (eventConfigCancelsEvent(prefabPath, config.cargoPlane, "cargo plane", numberOfActivePlayers) || eventConfigCancelsEvent(prefabPath, config.santasSleigh, "santa's sleigh", numberOfActivePlayers) || eventConfigCancelsEvent(prefabPath, config.patrolHeli, "patrol helicopter", numberOfActivePlayers) || eventConfigCancelsEvent(prefabPath, config.chinook, "CH47 helicopter", numberOfActivePlayers) || eventConfigCancelsEvent(prefabPath, config.cargoShip, "cargo ship", numberOfActivePlayers) || eventConfigCancelsEvent(prefabPath, config.easterEggHunt, "easter egg hunt", numberOfActivePlayers) || eventConfigCancelsEvent(prefabPath, config.halloweenHunt, "halloween hunt", numberOfActivePlayers)) { return false; } return null; } private bool eventConfigCancelsEvent(string prefabPath, ConfigFile.EventConfig config, string configName, int numberOfActivePlayers) { if (!isConfiguredEvent(prefabPath, config)) { return false; } if (numberOfActivePlayers < config.MinPop) { Puts("Cancelling " + configName + " event because active population ({0}) is less than configured minimum of {1}", numberOfActivePlayers, config.MinPop); return true; } return false; } private HashSet initializedTimedCommands = new HashSet(); private void ExecuteConsoleCommand(string command) { if (!string.IsNullOrEmpty(command)) { string[] commands = command.Split('|'); foreach (string cmd in commands) { ConsoleSystem.Run(ConsoleSystem.Option.Server, cmd.Trim()); } } } void StartTimedCommandsSequentially() { RunNextTimedCommandSequentially(0); } void RunNextTimedCommandSequentially(int index) { if (config.timedCommands.Count == 0) { return; } index = index % config.timedCommands.Count; var timedCommand = config.timedCommands[index]; int numberOfActivePlayers = BasePlayer.activePlayerList.Count; if (numberOfActivePlayers >= timedCommand.MinPlayers) { float interval = UnityEngine.Random.Range(timedCommand.MinInterval, timedCommand.MaxInterval); List commands = timedCommand.Commands; string key = commands[0]; if (!initializedTimedCommands.Contains(key)) { timedCommandTimers[key] = timer.Once(interval, () => { foreach (string command in commands) { ExecuteConsoleCommand(command); } initializedTimedCommands.Remove(key); RunNextTimedCommandSequentially(index + 1); }); initializedTimedCommands.Add(key); } } else { timedCommandTimers[timedCommand.Commands[0]] = timer.Once(timedCommand.MinInterval, () => RunNextTimedCommandSequentially(index + 1)); } } void StartTimedCommandsSimultaneously() { foreach (var timedCommand in config.timedCommands) { RunTimedCommandSimultaneously(timedCommand); } } void RunTimedCommandSimultaneously(ConfigFile.TimedCommandConfig timedCommand) { int numberOfActivePlayers = BasePlayer.activePlayerList.Count; if (numberOfActivePlayers >= timedCommand.MinPlayers) { float interval = UnityEngine.Random.Range(timedCommand.MinInterval, timedCommand.MaxInterval); List commands = timedCommand.Commands; string key = commands[0]; if (!initializedTimedCommands.Contains(key)) { timedCommandTimers[key] = timer.Once(interval, () => { foreach (string command in commands) { ExecuteConsoleCommand(command); } initializedTimedCommands.Remove(key); RunTimedCommandSimultaneously(timedCommand); }); initializedTimedCommands.Add(key); } } else { timedCommandTimers[timedCommand.Commands[0]] = timer.Once(timedCommand.MinInterval, () => RunTimedCommandSimultaneously(timedCommand)); } } void Unload() { foreach (var timer in timedCommandTimers.Values) { timer.Destroy(); } } } }