OnSwitchToggled
OnSwitchToggled is called after a player toggles an electrical switch, a fuel generator engine switch or an industrial conveyor, once the new state has already been applied to the entity.
void OnSwitchToggled(ElectricSwitch electricSwitch, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
electricSwitch | ElectricSwitch | The entity whose switch just changed state. Depending on the signature you declare this is an ElectricSwitch, FuelGenerator or IndustrialConveyor. Cast or check the concrete type before reading entity-specific members. |
player | BasePlayer | The BasePlayer who sent the interaction RPC. It is the RPC sender, so it can be null or a player who is not the entity owner; always null-check it. |
Return value
The return value is ignored; the hook fires after the switch state was already changed and cannot cancel it. To block the interaction, use OnSwitchToggle, which stops the change when it returns a non-null value.
How it works
Oxide fires this hook right after the game applies a switch interaction, in three separate code paths: ElectricSwitch.RPC_Switch (the wall/floor lever players press), FuelGenerator.RPC_EngineSwitch (the generator's on/off toggle) and IndustrialConveyor.SvSwitch (the conveyor's enable/disable switch). The new state is already set when the hook runs, so read it with IsOn() on ElectricSwitch or IndustrialConveyor, or the generator state on FuelGenerator, rather than guessing from the RPC.
The hook only fires for the RPC path, i.e. a player interaction. A switch flipped by anything else in code does not produce this call. Both the parent OnSwitchToggle hook and this one are inside the same null-return guard, so suppressing OnSwitchToggle also prevents OnSwitchToggled.
Because the parameter type varies per injection site, declare the hook with the type you care about. A method taking ElectricSwitch is skipped for generator and conveyor toggles, and a method taking FuelGenerator is skipped for everything else. To handle all three, write three private methods with the same name and different parameter types; Oxide dispatches each call to the matching one.
Other signatures
Oxide also calls OnSwitchToggled from other places in the game with these parameter types. Declare the overload you need, or several:
void OnSwitchToggled(FuelGenerator fuelGenerator, BasePlayer player)void OnSwitchToggled(IndustrialConveyor industrialConveyor, BasePlayer player)
Example plugin: Broadcast generator and switch toggles to admins with cooldown
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Switch Toggle Audit", "RustPluginGenerator", "1.0.0")]
[Description("Reports electric switch, generator and conveyor toggles to online admins.")]
public class SwitchToggleAudit : RustPlugin
{
private const string PermSee = "switchtoggleaudit.see";
private class PluginConfig
{
[JsonProperty("Broadcast to admins")]
public bool BroadcastToAdmins { get; set; } = true;
[JsonProperty("Cooldown seconds per player")]
public float CooldownSeconds { get; set; } = 5f;
}
private PluginConfig config;
private readonly Dictionary<ulong, float> lastReport = new Dictionary<ulong, float>();
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>
{
["Report"] = "{0} toggled a {1} at {2} (now {3})",
["StateOn"] = "on",
["StateOff"] = "off"
}, 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(PermSee, this);
}
private void OnSwitchToggled(ElectricSwitch electricSwitch, BasePlayer player) =>
Report(electricSwitch, "electric switch", electricSwitch.IsOn(), player);
private void OnSwitchToggled(FuelGenerator fuelGenerator, BasePlayer player) =>
Report(fuelGenerator, "fuel generator", fuelGenerator.IsOn(), player);
private void OnSwitchToggled(IndustrialConveyor industrialConveyor, BasePlayer player) =>
Report(industrialConveyor, "industrial conveyor", industrialConveyor.IsOn(), player);
private void Report(BaseEntity entity, string label, bool isOn, BasePlayer player)
{
if (entity == null || player == null || player.IsNpc) return;
if (!config.BroadcastToAdmins) return;
ulong id = player.userID.Get();
float now = Time.realtimeSinceStartup;
float last;
if (lastReport.TryGetValue(id, out last) && now - last < config.CooldownSeconds) return;
lastReport[id] = now;
string position = entity.transform != null
? string.Format("{0:F0}, {1:F0}", entity.transform.position.x, entity.transform.position.z)
: "unknown";
string state = isOn ? Msg("StateOn") : Msg("StateOff");
string line = Msg("Report", null, player.displayName, label, position, state);
foreach (BasePlayer admin in BasePlayer.activePlayerList)
{
if (admin == null || !admin.IsConnected) continue;
if (!admin.IsAdmin && !permission.UserHasPermission(admin.UserIDString, PermSee)) continue;
admin.ChatMessage(line);
}
}
private void Unload()
{
lastReport.Clear();
}
}
}The plugin keeps a small audit feed for staff. It declares three overloads of OnSwitchToggled: one for ElectricSwitch, one for FuelGenerator and one for IndustrialConveyor, all routed into a shared Report method. Each report resolves the entity position, reads the new state with IsOn() where the type supports it and formats a message through the language file. Admins who are connected receive the line in chat, but only if Broadcast to admins is enabled in the config. A per-player cooldown timer set of five seconds prevents a player spamming a lever from flooding admin chat; the cooldown table is cleared on unload so the plugin leaves no dangling timers.
Common use cases
Staff visibility on generator abuse
Feed generator and conveyor toggles into an admin chat channel so moderators see who keeps disabling power to a base or a raid compound.
Base power monitoring
Log the position and new state of every switch a player flips, so you can correlate power outages with player activity.
Reward proximity interactions
When a player toggles a switch inside a custom event arena, grant a point or trigger the next stage of a scripted sequence.
Pitfalls
One name, three parameter types
A single
OnSwitchToggled(ElectricSwitch, BasePlayer)method never sees generator or conveyor toggles. Declare separate overloads if you need coverage of all three.Cannot be cancelled here
The state is already applied when this fires. To stop a player from flipping a switch, handle
OnSwitchToggleand return a non-null value there.The player can be null or unrelated
The second argument is the RPC sender. Check it before use and do not assume it is the entity owner or that it is connected, especially when entities are toggled by team members or cheats.
Build a plugin with OnSwitchToggled
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 OnSwitchToggled
Generate