Skip to content
RustPluginGenerator

OnSwitchToggle

OnSwitchToggle is called when a player requests to toggle an ElectricSwitch, a FuelGenerator's engine, or an IndustrialConveyor. Returning a non-null value cancels the toggle; returning null lets it proceed.

Signature
object OnSwitchToggle(ElectricSwitch electricSwitch, BasePlayer player)

Parameters

Hook parameters
ParameterTypeDescription
electricSwitchElectricSwitchThe entity whose toggle is being requested. Declare the parameter as the actual type (ElectricSwitch, FuelGenerator, IndustrialConveyor) to receive only that switch kind; use BaseEntity to catch all three.
playerBasePlayerThe player who sent the toggle request. May be null for non-player RPC calls, so null-check it before reading userID, permissions, or position.

Return value

Return null to let the toggle proceed normally. Return any non-null value (typically true) to block the toggle: the game skips reading the requested state, so the switch, engine, or conveyor does not change and OnSwitchToggled is not fired.

How it works

This hook fires inside the RPC handler for three interactive switch objects: ElectricSwitch.RPC_Switch (a button or switch), FuelGenerator.RPC_EngineSwitch (turn generator on/off), and IndustrialConveyor.SvSwitch (conveyor on/off). The handler runs before the entity's state actually changes, so it is the place to accept or refuse the request. When your hook returns non-null, the state change is skipped and OnSwitchToggled is not called either.

Because the call is injected before the new state is read, you cannot read the requested target state from the entity in a reliable way; electricSwitch.IsOn() or fuelGenerator.IsOn() still reflect the current state. If you want to know whether the player is turning it on or off, invert the current value.

Declare the switch parameter as a specific type to react only to that kind. Declaring ElectricSwitch means generator and conveyor calls are skipped entirely because the argument is not an instance of that type. Conveyors fire a slightly different internal method (SvSwitch) but dispatch through the same hook name.

Other signatures

Oxide also calls OnSwitchToggle from other places in the game with these parameter types. Declare the overload you need, or several:

  • object OnSwitchToggle(FuelGenerator fuelGenerator, BasePlayer player)
  • object OnSwitchToggle(IndustrialConveyor industrialConveyor, BasePlayer player)

Example plugin: Lock generators and switches behind a permission

SwitchPermissionGate.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("SwitchPermissionGate", "RustPluginGenerator", "1.0.0")]
    [Description("Requires a permission before players can toggle switches, generators and conveyors.")]
    public class SwitchPermissionGate : RustPlugin
    {
        private const string PermUse = "switchpermissiongate.use";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Bypass for admins")]
            public bool AdminBypass { get; set; } = true;

            [JsonProperty("Blocked message")]
            public string BlockedMessage { get; set; } = "You are not allowed to use that switch.";
        }

        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"] = "{0}"
            }, this);
        }

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

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

        private object OnSwitchToggle(BaseEntity entity, BasePlayer player)
        {
            if (entity == null || player == null) return null;

            if (config.AdminBypass && player.IsAdmin) return null;
            if (permission.UserHasPermission(player.UserIDString, PermUse)) return null;

            player.ChatMessage(Msg("Blocked", player.UserIDString, config.BlockedMessage));
            return true;
        }
    }
}

The plugin registers a single permission and checks it in OnSwitchToggle. If the requesting player lacks the permission and is not an admin, the hook returns true, which stops the state change. Otherwise it returns null so normal behavior continues. The permission list is read from config so admins can rename the permission. Because the parameter is typed as BaseEntity, the same handler covers electric switches, generators, and conveyors. The player parameter is null-checked before reading UserIDString, and the entity type is logged only through a rare warning path, never in the hot path.

Common use cases

  • Permission-locked switches

    Require a permission before players can flip electric switches or start generators. Return true to deny without touching the entity state.

  • Raid-safe generator shutdown

    During a raid window, block engine toggles on generators inside a building you consider protected, or force them off via a timer.

  • Conveyor control by team

    Only allow members of the conveyor's owning team to toggle it by comparing player.currentTeam against the entity owner's team.

Pitfalls

  • Player can be null

    Non-player RPCs may pass a null player. Reading player.userID without a check throws and the toggle silently fails.

  • Reading the requested state is unreliable

    The hook runs before the requested state is applied, so IsOn() still shows the old value. Do not trust it to know whether the player is turning on or off.

  • OnSwitchToggled will not fire when blocked

    Returning a value skips the state change and the follow-up OnSwitchToggled call. Do not rely on that hook to clean up state if you cancelled.

Build a plugin with OnSwitchToggle

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

Prompt: Permission-locked switches using the OnSwitchToggle 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 OnSwitchToggle

Generate