OnRfListenerAdd
OnRfListenerAdd is called when an IRFObject is about to be registered as a listener on an RF frequency via RFManager.AddListener. Returning a non-null value cancels the registration.
object OnRfListenerAdd(IRFObject obj, int frequency)Parameters
| Parameter | Type | Description |
|---|---|---|
obj | IRFObject | The IRFObject being registered as a receiver on the frequency. Usually a BaseEntity such as an RF receiver, door controller or other RF-capable entity; cast it to BaseNetworkable or BaseEntity to inspect it. |
frequency | int | The already-clamped RF frequency (0-9999) the listener would be added to. Use it to allow or block specific channels. |
Return value
Return null (or nothing) to let the registration proceed normally. Return any non-null value to abort it: the listener is not added to the frequency set, RFSignalUpdate is skipped and OnRfListenerAdded never fires. The hook itself has no meaningful return value to hand back, so the only use of a return is to block.
How it works
This hook fires inside RFManager.AddListener(int frequency, IRFObject obj), before the object is placed into the listener set for that frequency. The frequency has already been clamped to the valid RF range, so frequency is always the final value. The game calls this whenever something subscribes to an RF channel: RF receivers powering on, doors and other IO entities wired to a broadcaster, and similar entities that call into RFManager when they begin listening.
obj is your handle on the listener. Cast it to BaseNetworkable for net.ID/prefab checks, or to BaseEntity to read OwnerID and position. Declaring the parameter as a more specific type (for example BaseNetworkable) makes Oxide skip the call for arguments that are not instances of that type, so keep it as IRFObject if you want to see every registration.
Returning a value blocks the add: the object never enters the listener set, no RFSignalUpdate is sent, and the follow-up OnRfListenerAdded hook does not fire. This is the right place to enforce per-frequency rules, limit how many listeners a single entity may register, or stop players from subscribing to restricted channels.
Example plugin: Restrict RF frequencies to a permission
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("RfFrequency Guard", "RustPluginGenerator", "1.0.0")]
[Description("Restricts RF listener registrations on configured frequencies to a permission")]
public class RfFrequencyGuard : RustPlugin
{
private const string PermUse = "rffrequencyguard.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Restricted frequencies")]
public List<int> RestrictedFrequencies = new List<int> { 1000, 1001, 1002 };
[JsonProperty("Allow ownerless entities (server owned)")]
public bool AllowOwnerless = 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>
{
["Restricted"] = "RF channel {0} is restricted to authorized players."
}, 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(PermUse, this);
}
private object OnRfListenerAdd(IRFObject obj, int frequency)
{
if (obj == null || config.RestrictedFrequencies == null) return null;
if (!config.RestrictedFrequencies.Contains(frequency)) return null;
BaseEntity entity = obj as BaseEntity;
if (entity == null) return null;
BasePlayer owner = entity.OwnerID == 0 ? null : BasePlayer.FindByID(entity.OwnerID);
if (owner == null)
{
return config.AllowOwnerless ? null : (object)true;
}
if (permission.UserHasPermission(owner.UserIDString, PermUse))
{
return null;
}
owner.ChatMessage(Msg("Restricted", owner.UserIDString, frequency));
return true;
}
}
}The plugin registers a permission rffrequencyguard.use and defines a configurable list of restricted RF channels in PluginConfig. When OnRfListenerAdd fires, it reads frequency and checks the list. Restricted channels are allowed for players with the permission and blocked for everyone else by returning true. The listener's owner is resolved by casting obj to BaseEntity and looking up OwnerID with BasePlayer.FindByID, so server-owned entities without an owner pass through when configured. The example is deliberately minimal: it blocks the add rather than disconnecting the entity, and it never prints to console inside the hook to keep logging quiet.
Common use cases
Reserve a range of frequencies for staff or events
Block listeners on high channels for ordinary players, letting only authed users broadcast and receive there. Keeps event and admin channels clear of random receivers.
Limit RF listener count per entity
Track how many frequencies a single entity registers and deny further ones past a configurable limit. Useful on busy servers where turret and trap logic relies on receivers.
Prevent listeners on specific prefabs
Cast
objtoBaseNetworkable, inspectShortPrefabName, and block registration for prefabs you want to keep off the RF grid, for example on event maps.
Pitfalls
Blocking breaks the entity's logic
Returning non-null skips the listener registration entirely, so the receiver never powers up and anything wired to it stays inactive. Return a value only when you want that behavior, not just to observe the call.
Owner lookups can be zero
Many RF objects are server-created and have
OwnerID0.BasePlayer.FindByIDreturns null in that case, so decide up front whether ownerless listeners should be allowed or blocked, and handle the null path explicitly.The frequency is already clamped
Do not re-clamp
frequencyyourself; the game has already passed it throughClampFrequency. Compare against your configured channels directly.
Build a plugin with OnRfListenerAdd
Describe what should happen and get a compiled plugin that uses this hook.
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 OnRfListenerAdd
Generate