From ed6530e8db0c95cce7eed816c6435f72b6c30276 Mon Sep 17 00:00:00 2001 From: saulteafarmer Date: Sun, 16 Mar 2025 15:13:31 +0000 Subject: [PATCH] Initial Upload --- AutoRadioManager.cs | 407 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 30 +++- 2 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 AutoRadioManager.cs diff --git a/AutoRadioManager.cs b/AutoRadioManager.cs new file mode 100644 index 0000000..094d258 --- /dev/null +++ b/AutoRadioManager.cs @@ -0,0 +1,407 @@ +using Newtonsoft.Json; +using System.Collections.Generic; +using UnityEngine; +using System; + +namespace Oxide.Plugins +{ + [Info("Auto Radio Manager", "RustySats", "1.0.0")] + [Description("Automatically manages boomboxes in your Rust server with various configuration options")] + public class AutoRadioManager : RustPlugin + { + #region Configuration + private Configuration config; + + public class Configuration + { + [JsonProperty("Radio Stream URL")] + public string RadioStreamUrl = "https://radio.goodmorningbitcoin.com/listen/goodmorningbitcoin/radio.mp3"; + + [JsonProperty("Additional Radio Stations (name,url format)", ObjectCreationHandling = ObjectCreationHandling.Replace)] + public Dictionary AdditionalRadioStations = new Dictionary + { + { "Good Morning Bitcoin", "https://radio.goodmorningbitcoin.com/listen/goodmorningbitcoin/radio.mp3" } + }; + + [JsonProperty("Enable for deployed boomboxes")] + public bool EnableForDeployed = false; + + [JsonProperty("Enable for handheld boomboxes")] + public bool EnableForHandheld = true; + + [JsonProperty("Enable for static/monument boomboxes")] + public bool EnableForStatic = true; + + [JsonProperty("Auto-restart interval (minutes)")] + public int AutoRestartInterval = 60; + + [JsonProperty("Enable auto-restart")] + public bool EnableAutoRestart = true; + + [JsonProperty("Turn on radios after server restart")] + public bool TurnOnAfterServerRestart = true; + } + + protected override void LoadDefaultConfig() => config = new Configuration(); + + protected override void LoadConfig() + { + base.LoadConfig(); + try + { + config = Config.ReadObject(); + if (config == null) + { + throw new JsonException(); + } + + SaveConfig(); + } + catch + { + PrintWarning($"Configuration file {Name}.json is invalid; using defaults"); + LoadDefaultConfig(); + } + } + + protected override void SaveConfig() + { + Config.WriteObject(config, true); + Puts($"Configuration saved to {Name}.json"); + } + #endregion + + #region Fields + private Timer autoRestartTimer; + private string originalServerUrlList; + #endregion + + #region Oxide Hooks + private void Init() + { + // Initialize any necessary resources + Puts("Auto Radio Manager initialized"); + + // Store the original server URL list for restoration on unload + originalServerUrlList = BoomBox.ServerUrlList; + } + + private void OnServerInitialized() + { + // Update the server URL list with additional radio stations + UpdateServerUrlList(); + + // Start the auto-restart timer if enabled + if (config.EnableAutoRestart) + { + StartAutoRestartTimer(); + } + + // Turn on all radios after server restart if enabled + if (config.TurnOnAfterServerRestart) + { + // Use a slight delay to ensure all entities are fully loaded + timer.Once(5f, () => TurnOnAllRadios()); + } + } + + private void OnEntitySpawned(DeployableBoomBox boombox) + { + if (!config.EnableForDeployed || boombox == null) + return; + + // Use a slight delay to ensure the entity is fully initialized + timer.Once(0.5f, () => { + if (boombox != null && boombox.BoxController != null) + SetBoomboxRadioIP(boombox.BoxController); + }); + } + + private void OnEntitySpawned(HeldBoomBox boombox) + { + if (!config.EnableForHandheld || boombox == null) + return; + + // Use a slight delay to ensure the entity is fully initialized + timer.Once(0.5f, () => { + if (boombox != null && boombox.BoxController != null) + SetBoomboxRadioIP(boombox.BoxController); + }); + } + + private void OnEntitySpawned(BoomBox boombox) + { + if (!config.EnableForStatic || boombox == null) + return; + + // Use a slight delay to ensure the entity is fully initialized + timer.Once(0.5f, () => { + if (boombox != null && IsStaticBoombox(boombox)) + SetBoomboxRadioIP(boombox); + }); + } + + void Unload() + { + // Clean up the timer when the plugin is unloaded + if (autoRestartTimer != null) + { + autoRestartTimer.Destroy(); + autoRestartTimer = null; + } + + // Restore the original server URL list + BoomBox.ServerUrlList = originalServerUrlList; + if (BoomBox.ServerValidStations != null && !string.IsNullOrEmpty(originalServerUrlList)) + { + BoomBox.ServerValidStations.Clear(); + Server.Command($"BoomBox.ServerUrlList \"{originalServerUrlList}\""); + } + + Puts("Auto Radio Manager unloaded"); + } + #endregion + + #region Methods + private void UpdateServerUrlList() + { + if (config.AdditionalRadioStations == null || config.AdditionalRadioStations.Count == 0) + { + Puts("No additional radio stations configured"); + return; + } + + List stationEntries = new List(); + + // Process additional radio stations from config + foreach (var station in config.AdditionalRadioStations) + { + string entry = $"{station.Key},{station.Value}"; + stationEntries.Add(entry); + } + + if (stationEntries.Count > 0) + { + // Clear existing stations if needed + if (BoomBox.ServerValidStations != null) + { + BoomBox.ServerValidStations.Clear(); + } + + // Build the comma-separated list for the server + string urlList = string.Join(",", stationEntries); + + // Apply the list through server command + Server.Command($"BoomBox.ServerUrlList \"{urlList}\""); + + Puts($"Added {stationEntries.Count} additional radio stations to server list"); + } + } + private bool IsStaticBoombox(BoomBox boombox) + { + // This determines if a boombox is a static/monument boombox + + try + { + // Find all deployable and held boomboxes + var deployables = UnityEngine.Object.FindObjectsOfType(); + var handhelds = UnityEngine.Object.FindObjectsOfType(); + + // Check if this boombox is a controller for any of them + foreach (var deployable in deployables) + { + if (deployable.BoxController == boombox) + return false; // It's a deployed boombox + } + + foreach (var handheld in handhelds) + { + if (handheld.BoxController == boombox) + return false; // It's a handheld boombox + } + + // Check if it has an owner + if (boombox.baseEntity != null && boombox.baseEntity.OwnerID != 0) + return false; // It has an owner, so likely not a static/monument boombox + + return true; // If it's not part of a deployable or handheld and has no owner, assume it's static + } + catch (Exception ex) + { + PrintError($"Error in IsStaticBoombox: {ex.Message}"); + return false; // Default to not treating it as static in case of error + } + } + + private void SetBoomboxRadioIP(BoomBox box) + { + if (box == null) return; + + try + { + // Set the radio IP to the configured stream URL + box.CurrentRadioIp = config.RadioStreamUrl; + + // Notify clients of the change + box.baseEntity.ClientRPC(null, "OnRadioIPChanged", box.CurrentRadioIp); + + // Turn on the radio + box.SetFlag(BaseEntity.Flags.On, true); + box.baseEntity.SendNetworkUpdate(); + } + catch (Exception ex) + { + PrintError($"Error setting boombox radio IP: {ex.Message}"); + } + } + + private void StartAutoRestartTimer() + { + // Destroy any existing timer + if (autoRestartTimer != null) + { + autoRestartTimer.Destroy(); + autoRestartTimer = null; + } + + // Validate interval (minimum 1 minute) + int interval = Math.Max(1, config.AutoRestartInterval); + + // Create a new timer with the configured interval + autoRestartTimer = timer.Every(interval * 60f, RestartAllRadios); + Puts($"Auto-restart timer started with interval of {interval} minutes"); + } + + private void TurnOnAllRadios() + { + Puts("Turning on all radios..."); + + int deployedCount = 0; + int handheldCount = 0; + int staticCount = 0; + + try + { + // Find all deployed boomboxes + if (config.EnableForDeployed) + { + var deployables = UnityEngine.Object.FindObjectsOfType(); + foreach (var deployable in deployables) + { + if (deployable != null && deployable.BoxController != null) + { + SetBoomboxRadioIP(deployable.BoxController); + deployedCount++; + } + } + } + + // Find all handheld boomboxes + if (config.EnableForHandheld) + { + var handhelds = UnityEngine.Object.FindObjectsOfType(); + foreach (var handheld in handhelds) + { + if (handheld != null && handheld.BoxController != null) + { + SetBoomboxRadioIP(handheld.BoxController); + handheldCount++; + } + } + } + + // Find all static boomboxes + if (config.EnableForStatic) + { + var allBoomboxes = UnityEngine.Object.FindObjectsOfType(); + foreach (var boombox in allBoomboxes) + { + if (boombox != null && IsStaticBoombox(boombox)) + { + SetBoomboxRadioIP(boombox); + staticCount++; + } + } + } + + Puts($"Turned on {deployedCount} deployed, {handheldCount} handheld, and {staticCount} static boomboxes"); + } + catch (Exception ex) + { + PrintError($"Error in TurnOnAllRadios: {ex.Message}"); + } + } + + private void RestartAllRadios() + { + Puts("Auto-restarting all radios..."); + + int deployedCount = 0; + int handheldCount = 0; + int staticCount = 0; + + try + { + // First turn off all radios + + // Deployed boomboxes + if (config.EnableForDeployed) + { + var deployables = UnityEngine.Object.FindObjectsOfType(); + foreach (var deployable in deployables) + { + if (deployable != null && deployable.BoxController != null) + { + deployable.BoxController.SetFlag(BaseEntity.Flags.On, false); + deployable.BoxController.baseEntity.SendNetworkUpdate(); + deployedCount++; + } + } + } + + // Handheld boomboxes + if (config.EnableForHandheld) + { + var handhelds = UnityEngine.Object.FindObjectsOfType(); + foreach (var handheld in handhelds) + { + if (handheld != null && handheld.BoxController != null) + { + handheld.BoxController.SetFlag(BaseEntity.Flags.On, false); + handheld.BoxController.baseEntity.SendNetworkUpdate(); + handheldCount++; + } + } + } + + // Static boomboxes + if (config.EnableForStatic) + { + var allBoomboxes = UnityEngine.Object.FindObjectsOfType(); + foreach (var boombox in allBoomboxes) + { + if (boombox != null && IsStaticBoombox(boombox)) + { + boombox.SetFlag(BaseEntity.Flags.On, false); + boombox.baseEntity.SendNetworkUpdate(); + staticCount++; + } + } + } + + Puts($"Turned off {deployedCount} deployed, {handheldCount} handheld, and {staticCount} static boomboxes"); + + // Wait a short delay to ensure they're all off + timer.Once(2f, () => { + Puts("Turning radios back on..."); + TurnOnAllRadios(); + }); + } + catch (Exception ex) + { + PrintError($"Error in RestartAllRadios: {ex.Message}"); + } + } + #endregion + } +} \ No newline at end of file diff --git a/README.md b/README.md index 772d37d..376313f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,29 @@ -# AutoRadioManager +# Auto Radio Manager -Automatically manages boomboxes in your Rust server with various configuration options \ No newline at end of file +A Rust plugin that automatically manages boomboxes in your server by setting default radio stream URLs, turning on radios when deployed/spawned, restarting radios periodically, and turning on all radios after server restarts. + +## Features + +- Sets a default radio stream URL for all boomboxes +- Automatically turns on radios when deployed/spawned +- Restarts radios periodically to prevent connection issues +- Turns on all radios after server restarts +- Separate control for deployed, handheld and static (monument) boomboxes +- Support for adding multiple radio stations to the server + +## Configuration + +```json +{ + "Radio Stream URL": "https://radio.goodmorningbitcoin.com/listen/goodmorningbitcoin/radio.mp3", + "Additional Radio Stations (name,url format)": { + "Good Morning Bitcoin": "https://radio.goodmorningbitcoin.com/listen/goodmorningbitcoin/radio.mp3" + }, + "Enable for deployed boomboxes": false, + "Enable for handheld boomboxes": true, + "Enable for static/monument boomboxes": true, + "Auto-restart interval (minutes)": 60, + "Enable auto-restart": true, + "Turn on radios after server restart": true +} +``` \ No newline at end of file