Skip to content
RustPluginGenerator

OnBoomboxStationUpdated

OnBoomboxStationUpdated is called after a player changes the station (radio IP) of a boombox via BoomBox.Server_UpdateRadioIP, right after the new value is stored and broadcast to clients.

Signature
void OnBoomboxStationUpdated(BoomBox boomBox, string text, BasePlayer player)

Parameters

Hook parameters
ParameterTypeDescription
boomBoxBoomBoxThe BoomBox entity whose station was just changed. Use it to read the owner, position or to toggle playback.
textstringThe new radio IP / station string the player submitted. Stored in CurrentRadioIp and sent to nearby clients.
playerBasePlayerThe BasePlayer who set the station through the boombox UI. Can be null in edge cases, so null-check it.

Return value

The hook is called for notification only; whatever you return is ignored and the original method continues. The station stays set to text and the boombox may stop playing if it was on.

How it works

This hook fires inside BoomBox.Server_UpdateRadioIP, immediately after the boombox assigns the player as AssignedRadioBy, stores the submitted string in CurrentRadioIp and sends the OnRadioIPChanged client RPC. The call happens before the code checks IsOn() and stops playback, so at hook time the boombox is still in its previous playing state.

Use boomBox for the entity itself (net.ID.Value, OwnerID, position, IsOn()), text for the raw station string that was accepted, and player for the sender. Because text is already committed to the entity when the hook runs, this is a notification hook, not a validation point; if you need to reject a station, do it with a validation hook instead.

Declaring BasePlayer for the third parameter matches the signature exactly. Declaring a narrower type is not useful here because the argument is always the requesting player, and a mismatch would simply skip your method.

This fires once per station change, not per tick, so light logging or persistence is acceptable. Avoid heavy work like spawning entities or broadcasting to all players inside it.

Example plugin: Log boombox station changes to a data file

BoomboxStationLog.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("Boombox Station Log", "RustPluginGenerator", "1.0.0")]
    [Description("Logs boombox station changes to a data file with bounded entry count.")]
    public class BoomboxStationLog : RustPlugin
    {
        private const string DataFileName = "BoomboxStationLog";

        private PluginConfig config;
        private List<StationEntry> entries;
        private Timer saveTimer;
        private bool dirty;

        private class PluginConfig
        {
            [JsonProperty("Max entries")]
            public int MaxEntries = 500;

            [JsonProperty("Save interval seconds")]
            public float SaveInterval = 30f;

            [JsonProperty("Notify player on change")]
            public bool NotifyPlayer = false;
        }

        private class StationEntry
        {
            [JsonProperty("Time UTC")]
            public string TimeUtc;

            [JsonProperty("Player name")]
            public string PlayerName;

            [JsonProperty("Player id")]
            public string PlayerId;

            [JsonProperty("Boombox id")]
            public ulong BoomboxId;

            [JsonProperty("Station")]
            public string Station;
        }

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        private void Init()
        {
            entries = Interface.Oxide.DataFileSystem.ReadObject<List<StationEntry>>(DataFileName) ?? new List<StationEntry>();
        }

        private void OnServerInitialized()
        {
            if (config.SaveInterval <= 0f) return;
            saveTimer = timer.Every(config.SaveInterval, Flush);
        }

        private void OnBoomboxStationUpdated(BoomBox boomBox, string text, BasePlayer player)
        {
            if (boomBox == null || string.IsNullOrEmpty(text) || player == null) return;

            var baseEntity = boomBox.GetComponentInParent<BaseEntity>();

            entries.Add(new StationEntry
            {
                TimeUtc = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"),
                PlayerName = player.displayName,
                PlayerId = player.UserIDString,
                BoomboxId = baseEntity != null && baseEntity.net != null ? baseEntity.net.ID.Value : 0UL,
                Station = text
            });

            while (entries.Count > Math.Max(1, config.MaxEntries))
            {
                entries.RemoveAt(0);
            }

            dirty = true;

            if (config.NotifyPlayer)
            {
                player.ChatMessage($"Boombox set to: {text}");
            }
        }

        private void Flush()
        {
            if (!dirty) return;
            dirty = false;
            Interface.Oxide.DataFileSystem.WriteObject(DataFileName, entries);
        }

        private void Unload()
        {
            if (saveTimer != null)
            {
                saveTimer.Destroy();
                saveTimer = null;
            }
            Flush();
        }
    }
}

The plugin records accepted boombox station changes into oxide/data/BoomboxStationLog so admins can review which players set which stations. OnBoomboxStationUpdated returns early when the boombox, text or player is null or empty, then appends an entry holding the player's name, user ID string, the boombox network ID, the station string and a UTC timestamp formatted yyyy-MM-dd HH:mm:ss. Entries are trimmed from the front once the count exceeds Max entries (with a minimum cap of 1). A dirty flag makes the save timer skip writes when nothing changed; Unload flushes any pending entry. Config also controls whether the player receives a chat message Boombox set to: {text}.

Common use cases

  • Audit station changes

    Keep a rolling log of which players set which radio IPs on which boomboxes, useful when investigating spam or abuse.

  • Notify staff of custom stations

    Send a message to admins when a player sets a station that is not on an allowlist, so they can review it manually.

  • Track boombox usage per player

    Increment a per-player counter in a data file to see how often each player changes stations.

Pitfalls

  • Not a validation hook

    The station string is already written to the boombox and sent to clients before this hook runs, so returning or rejecting here does not revert it.

  • Playback is stopped afterwards

    After the hook, the game calls ServerTogglePlay(false) when the boombox is on, so reading IsOn() inside the hook reflects the pre-change state.

  • Frequent data writes

    Players can change stations repeatedly; bound your log size and avoid rewriting the data file on every single call.

Build a plugin with OnBoomboxStationUpdated

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Audit station changes using the OnBoomboxStationUpdated hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnBoomboxStationUpdated

Generate