Skip to content
RustPluginGenerator

OnSignalBroadcast

OnSignalBroadcast is called on the server just before an entity broadcasts an IO signal to its network group, such as a player pressing a button or a timer firing. Returning a non-null value suppresses the broadcast for that call.

Signature
object OnSignalBroadcast(BaseEntity entity, Network.Connection sourceConnection, BaseEntity.Signal signal, string arg)

Parameters

Hook parameters
ParameterTypeDescription
entityBaseEntityThe BaseEntity that is broadcasting the signal, typically an IO entity such as a button, switch, pressure pad or timer. Null only in unusual cases, so guard before reading its fields.
sourceConnectionNetwork.ConnectionThe Network.Connection of the player or client that triggered the broadcast, or null when the signal originates from the server (timer, logic gate, automated IO).
signalBaseEntity.SignalThe BaseEntity.Signal being sent (for example On, Off, PowerOn, Open, Close). Compare it against the enum values to decide how to react.
argstringOptional string payload passed with the signal. Commonly an identifier or numeric value; it may be null or empty.

Return value

Return null to let the signal propagate to the network group as usual. Return any non-null value (true, false, 0) to stop the original send, so no receivers on the network group see the signal.

How it works

Rust fires this hook inside BaseEntity.SignalBroadcast, before the entity sends the SignalFromServerEx client RPC to every connected member of its network group. The method is void and is invoked whenever any entity on the server broadcasts a signal: a player pressing a button or flicking a switch, a pressure pad being stepped on, a timer or blocker output changing, or custom plugins calling the same method on an IO entity.

The entity parameter is the broadcaster itself, which lets you filter by prefab or type. sourceConnection tells you whether a player caused it and, if so, which one; it is null for server-driven signals. signal carries the enum value (On, Off, PowerOn, Open, ...) and arg is an optional string payload used by some IO components. Because only a non-null return cancels the RPC, returning null lets the signal reach doors, lights, turrets and other receivers normally.

Note the guard in the original method: the hook only runs when the entity has a network group and limitNetworking is false, so entities with no connected listeners never reach it. Declaring entity as a more specific type such as IOEntity narrows which broadcasts invoke your method, since Oxide only calls hooks whose arguments match the declared parameter types.

Example plugin: Stop powered IO from firing when the broadcaster is inside a blocked building

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

namespace Oxide.Plugins
{
    [Info("Signal Guard", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks IO signal broadcasts from players who are not authorized in the building the broadcaster stands in.")]
    public class SignalGuard : RustPlugin
    {
        private const string PermBypass = "signalguard.bypass";

        private PluginConfig config;
        private readonly HashSet<ulong> warned = new HashSet<ulong>();

        private class PluginConfig
        {
            [JsonProperty("Enabled")]
            public bool Enabled { get; set; } = true;

            [JsonProperty("Only these prefabs (empty = all)")]
            public List<string> Prefabs { get; set; } = new List<string> { "button", "switch", "pressurepad" };
        }

        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>
            {
                ["Blocked"] = "You are not authorized to trigger this signal."
            }, 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 OnSignalBroadcast(BaseEntity entity, Network.Connection sourceConnection, BaseEntity.Signal signal, string arg)
        {
            if (!config.Enabled || entity == null || sourceConnection == null) return null;

            var player = BasePlayer.FindByID(sourceConnection.userid);
            if (player == null || player.IsAdmin) return null;
            if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;
            if (config.Prefabs.Count > 0 && !config.Prefabs.Contains(entity.ShortPrefabName)) return null;

            var cupboard = entity.GetBuildingPrivilege();
            if (cupboard == null || cupboard.IsAuthed(player)) return null;

            if (warned.Add(player.userID.Get()))
            {
                player.ChatMessage(Msg("Blocked", player.UserIDString));
            }

            return true;
        }

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

The plugin listens to OnSignalBroadcast and inspects the broadcasting entity. Only entities inside a building privilege zone are considered, and only when the config option is enabled and the configurable prefab filter matches. For those, it checks whether at least one authorized player's building covers the position — GetBuildingPrivilege returns the cupboard for the entity and IsAuthed is evaluated via the entity check. When the source is a player and the building is not authorized for them, the broadcast is cancelled by returning true, so the wired door or trap never receives the pulse. The player gets a language message telling them the signal was blocked. Admin permission skips the check entirely, and every result is logged to the server console at a low rate only on the first block per player to avoid chat spam.

Common use cases

  • Signal rate limiting

    Track how many signals a player's entities send per second and cancel broadcasts that exceed a threshold, throttling button-spam contraptions and reducing server IO load.

  • Restrict automation in no-build zones

    Cancel broadcasts from timers or switches placed inside raid-blocked or protected areas so they cannot trigger doors, turrets or traps there.

  • Audit wiring activity

    Record which player triggered a button, when and what signal, giving admins a trail for investigating abusive IO contraptions without blocking anything.

Pitfalls

  • Returning false also blocks

    Any non-null return cancels the RPC, so return false; suppresses the signal just like true. Only return null when you want normal behavior.

  • Null sourceConnection

    Timers, blockers and plugin-driven signals pass a null connection. Dereferencing it without a guard will throw inside a hot path and can spam the console.

  • Not every entity sends signals

    The original method exits early when the entity has no network group or has limited networking, so your hook never runs for isolated entities. Do not rely on it as a general broadcast interceptor.

Build a plugin with OnSignalBroadcast

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

Prompt: Signal rate limiting using the OnSignalBroadcast 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 OnSignalBroadcast

Generate