Skip to content
RustPluginGenerator

OnRfBroadcasterAdd

OnRfBroadcasterAdd is called when an RF broadcaster is registered with the radio frequency manager, before it is added to the broadcaster set for that frequency.

Signature
object OnRfBroadcasterAdd(IRFObject obj, int frequency)

Parameters

Hook parameters
ParameterTypeDescription
objIRFObjectThe IRFObject that is trying to transmit on the given frequency. Cast it to BaseEntity to inspect the prefab, owner or position of the broadcaster.
frequencyintThe already clamped RF frequency (int) the broadcaster would transmit on. This is the value after RFManager limits it to the valid RF range, so it is the number listeners are tuned to.

Return value

Returning null (or nothing) lets the original code continue and the broadcaster is added normally. Returning any non-null value stops RFManager.AddBroadcaster before the broadcaster is inserted into the set for that frequency, so the device never becomes an active broadcaster.

How it works

The hook fires inside RFManager.AddBroadcaster after the frequency has been clamped and before the broadcaster is inserted into the frequency's broadcaster set. Anything that registers an RF transmitter triggers it: players toggling or placing RF broadcasters such as the RF transmitter and similar devices. The obj parameter is the IRFObject being registered; cast it to BaseEntity to get OwnerID, ShortPrefabName or transform.position. The frequency argument is the clamped value the game will actually use. Because the registration path is shared, you cannot narrow this hook by declaring a more specific parameter type and still receive calls; every broadcaster is passed as an IRFObject. Use the hook to inspect or record activity, and return non-null to abort the registration entirely. Keep the body fast, since it runs on every broadcaster registration, and clean up any state you keep for a broadcaster on OnRfBroadcasterRemove.

Example plugin: Limit RF broadcasters per player and frequency

RfBroadcasterLimit.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("RfBroadcasterLimit", "RustPluginGenerator", "1.0.0")]
    [Description("Caps active RF broadcasters per player and frequency and reports blocks in chat")]
    public class RfBroadcasterLimit : RustPlugin
    {
        private const string PermBypass = "rfbroadcasterlimit.bypass";

        private PluginConfig config;
        private readonly Dictionary<string, int> counts = new Dictionary<string, int>();

        private class PluginConfig
        {
            [JsonProperty("Max broadcasters per player per frequency")]
            public int MaxPerFrequency { get; set; } = 2;

            [JsonProperty("Message owner when a broadcaster is blocked")]
            public bool NotifyOwner { get; set; } = true;
        }

        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);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["LimitReached"] = "You already have {0} RF broadcaster(s) on frequency {1}.",
                ["Blocked"] = "This RF broadcaster was not activated: frequency {0} is at its limit for you."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args) =>
            string.Format(lang.GetMessage(key, this, userId), args);

        private void Init()
        {
            permission.RegisterPermission(PermBypass, this);
        }

        private object OnRfBroadcasterAdd(IRFObject obj, int frequency)
        {
            var entity = obj as BaseEntity;
            if (entity == null || entity.OwnerID == 0) return null;

            string userId = entity.OwnerID.ToString();
            if (permission.UserHasPermission(userId, PermBypass)) return null;

            string key = userId + ":" + frequency;
            int current;
            counts.TryGetValue(key, out current);

            if (current >= config.MaxPerFrequency)
            {
                if (config.NotifyOwner)
                {
                    var player = BasePlayer.FindByID(entity.OwnerID);
                    if (player != null && player.IsConnected)
                    {
                        player.ChatMessage(Msg("Blocked", userId, frequency));
                    }
                }
                return false;
            }

            counts[key] = current + 1;
            return null;
        }

        private void OnRfBroadcasterRemove(IRFObject obj, int frequency)
        {
            var entity = obj as BaseEntity;
            if (entity == null || entity.OwnerID == 0) return;

            string key = entity.OwnerID + ":" + frequency;
            int current;
            if (!counts.TryGetValue(key, out current)) return;

            if (current <= 1) counts.Remove(key);
            else counts[key] = current - 1;
        }

        private void Unload()
        {
            counts.Clear();
        }
    }
}

The plugin tracks how many active broadcasters each player owns per frequency in a dictionary keyed by userId:frequency. On OnRfBroadcasterAdd it casts the IRFObject to a BaseEntity, reads OwnerID, and counts existing entries. If the configured limit is already reached it returns a non-null object, which stops registration, and sends the owner a language message explaining the cap. When the broadcaster is removed, OnRfBroadcasterRemove decrements the counter and drops the entry once it reaches zero. The removal hook receives the same IRFObject and frequency, so no special tracking key is needed beyond the owner and frequency pair.

Common use cases

  • Per-player broadcaster caps

    Count active broadcasters owned by a player and block registration once a configurable limit is hit, which curbs RF spam around bases.

  • Frequency restriction lists

    Refuse broadcasters on frequencies reserved for events or admins by returning non-null for those frequencies and messaging the owner.

  • Audit and alerting

    Record who registers broadcasters on a given frequency over time and notify staff when an unexpected device appears.

Pitfalls

  • Frequency is pre-clamped

    The value you receive has already been passed through ClampFrequency, so you never see the raw number the player entered. Compare against the clamped value.

  • Blocking has no automatic feedback

    Returning non-null silently prevents the broadcaster from being registered. The player gets no error unless your plugin sends one, so send a message in the hook.

  • Keep your own counters in sync

    The hook only reports add attempts; use OnRfBroadcasterRemove to decrement counts, otherwise your limits drift upward and eventually block everyone.

Build a plugin with OnRfBroadcasterAdd

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

Prompt: Per-player broadcaster caps using the OnRfBroadcasterAdd 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 OnRfBroadcasterAdd

Generate