Skip to content
RustPluginGenerator

OnSamSiteModeToggle

OnSamSiteModeToggle is called when a player toggles a SamSite between defender mode and vehicle mode. Returning a non-null value cancels the switch.

Signature
object OnSamSiteModeToggle(SamSite samSite, BasePlayer player, bool flag)

Parameters

Hook parameters
ParameterTypeDescription
samSiteSamSiteThe SamSite entity whose defender mode is being switched. Use it to inspect position, owner, health or any attached data.
playerBasePlayerThe BasePlayer who sent the toggle request. The game already rejects null players and players without build permission before the hook is reached.
flagboolThe requested mode: true means defender mode on (targets players), false means it is being turned off (targets vehicles only).

Return value

Returning null lets the toggle proceed and the site updates its manually-set-mode flag and network state. Returning any non-null object stops the original method, so the flag is never applied and the site stays in its current mode.

How it works

The hook fires inside SamSite.ToggleDefenderMode, which runs when a player uses the SAM site's mode toggle input (the RPC the client sends when pressing the toggle). Before the hook is reached the game has already discarded the request if the player is null or fails CanBuild(), and it reads the requested boolean from the network message. The hook is also called when the requested value already matches the current mode; in that case the game would return early anyway. Use samSite to inspect the site and player to identify who is toggling. flag is the new mode the player wants, so true corresponds to defender mode and false to vehicle-only mode. Declaring a more specific parameter type does not narrow the call here because the runtime arguments are always a SamSite and a BasePlayer; the boolean stays a boolean. The typical use is to gate or notify on the switch: block it in restricted zones, keep certain sites locked to one mode, or log who changed what.

Example plugin: Lock SAM sites to vehicle mode in a no-fly zone

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

namespace Oxide.Plugins
{
    [Info("Sam Site Mode Lock", "RustPluginGenerator", "1.0.0")]
    [Description("Restricts SAM site mode toggles inside configured zones and reports blocked attempts.")]
    public class SamSiteModeLock : RustPlugin
    {
        private const string PermBypass = "samsitemodelock.bypass";

        private PluginConfig config;
        private readonly Dictionary<ulong, int> blockedCounts = new Dictionary<ulong, int>();

        private class PluginConfig
        {
            [JsonProperty("Restricted zones")]
            public List<Zone> Zones = new List<Zone>
            {
                new Zone { X = 0f, Y = 0f, Z = 0f, Radius = 50f, ForceVehicleMode = true, Message = "SAM sites in this area cannot use defender mode." }
            };
        }

        private class Zone
        {
            [JsonProperty("X")]
            public float X;
            [JsonProperty("Y")]
            public float Y;
            [JsonProperty("Z")]
            public float Z;
            [JsonProperty("Radius")]
            public float Radius;
            [JsonProperty("Force vehicle mode")]
            public bool ForceVehicleMode;
            [JsonProperty("Blocked message")]
            public string Message;
        }

        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 cannot change the SAM site mode here: {0}",
                ["Info"] = "Restricted zones: {0}",
                ["Report"] = "Player {0} had {1} blocked SAM site mode changes."
            }, 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 OnSamSiteModeToggle(SamSite samSite, BasePlayer player, bool flag)
        {
            if (samSite == null || player == null) return null;
            if (!flag) return null;
            if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;

            Vector3 pos = samSite.transform.position;
            string reason = null;
            foreach (Zone zone in config.Zones)
            {
                if (!zone.ForceVehicleMode) continue;
                Vector3 center = new Vector3(zone.X, zone.Y, zone.Z);
                if (Vector3.Distance(pos, center) <= zone.Radius)
                {
                    reason = zone.Message;
                    break;
                }
            }

            if (reason == null) return null;

            int count;
            blockedCounts.TryGetValue(player.userID.Get(), out count);
            blockedCounts[player.userID.Get()] = count + 1;

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

        [ConsoleCommand("samlock.info")]
        private void CmdInfo(ConsoleSystem.Arg arg)
        {
            if (arg == null || !arg.IsAdmin) return;

            List<string> lines = new List<string>();
            foreach (Zone zone in config.Zones)
            {
                lines.Add(string.Format("({0:F0},{1:F0},{2:F0}) r={3:F0} vehicle={4}", zone.X, zone.Y, zone.Z, zone.Radius, zone.ForceVehicleMode));
            }
            arg.ReplyWith(Msg("Info", null, lines.Count > 0 ? string.Join("; ", lines) : "none"));
        }

        [ConsoleCommand("samlock.report")]
        private void CmdReport(ConsoleSystem.Arg arg)
        {
            if (arg == null || !arg.IsAdmin) return;

            foreach (KeyValuePair<ulong, int> entry in blockedCounts)
            {
                arg.ReplyWith(Msg("Report", null, entry.Key, entry.Value));
            }
        }

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

The plugin carries a configurable list of restricted coordinates with a radius and a flag for whether the site should be forced to vehicle mode. In OnSamSiteModeToggle it checks if the site's position falls inside any restricted sphere; if so and the flag would enable defender mode, the hook returns a non-null value to block the change and sends the player a localized message. It also keeps a count of blocked attempts per player for a console report. The permission samsitemodelock.bypass lets admins switch freely, and the samlock.info console command prints the configured zones so admins can verify coordinates.

Common use cases

  • Restrict SAM sites in safe zones

    Block toggling to defender mode for any site inside a defined safe sphere so it cannot be used to hunt players leaving spawn.

  • Audit mode changes

    Record each toggle with player, site position and new mode for admin review without blocking the action.

  • Whitelist admins

    Return non-null for unauthorized users while letting a permission group toggle freely.

Pitfalls

  • Returning non-null blocks silently

    If you block the toggle without a message, the player's client shows nothing. Send a chat or console reply before returning to make the rejection clear.

  • Hook fires even when nothing changes

    The injection site runs before the equality check, so the hook is called when the requested mode matches the current one. Verify samSite.IsInDefenderMode() if you only want to react to actual changes.

  • Permission is checked before you see the player

    The game has already confirmed the player can build in the area, so player is a connected, non-null player, but you still need your own permission checks if you want to restrict beyond that.

Build a plugin with OnSamSiteModeToggle

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

Prompt: Restrict SAM sites in safe zones using the OnSamSiteModeToggle 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 OnSamSiteModeToggle

Generate