Skip to content
RustPluginGenerator

OnTurretModeToggle

OnTurretModeToggle is called when an authorized player toggles an AutoTurret between peacekeeper mode and attack-all mode from the turret control screen. Returning a non-null value cancels the change.

Signature
object OnTurretModeToggle(AutoTurret autoTurret, BasePlayer player)

Parameters

Hook parameters
ParameterTypeDescription
autoTurretAutoTurretThe AutoTurret whose mode is being changed. Use it to read position, authorization list or peacekeeper state, or to react differently per turret.
playerBasePlayerThe BasePlayer who triggered the mode change through the turret control UI. Already passed the turret's IsAuthed check, so this is an authorized user.

Return value

Return null to allow the game to change the turret mode as the player requested. Return any non-null value to block the change; the original SetPeacekeepermode call is skipped and the turret keeps its current mode.

How it works

The hook fires inside AutoTurret.SERVER_Peacekeeper and AutoTurret.SERVER_AttackAll, the RPC handlers used by the turret control UI. Both run only after IsAuthed(rpc.player) succeeds, so player is always a player the turret trusts. SERVER_Peacekeeper normally calls SetPeacekeepermode(true) (targets only players who are not authorized); SERVER_AttackAll calls SetPeacekeepermode(false) (shoot everything valid). The hook call itself happens before either setter, so at hook time the turret still has its previous mode. To tell which direction the player requested, compare the current peacekeeper state or inspect the RPC via other means; the signature does not tell you directly. Returning null lets the original setter run. Returning any non-null value skips it and leaves the turret in its existing mode. There is no per-turret narrowing available through parameter types here because both parameters are already concrete (AutoTurret and BasePlayer). Use this hook for server rules such as forbidding attack-all on turrets inside a specific zone, logging mode changes for staff audits, or notifying the owner when someone else flips their turret.

Example plugin: Restrict attack-all mode with permission and announce changes

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

namespace Oxide.Plugins
{
    [Info("Turret Mode Guard", "RustPluginGenerator", "1.0.0")]
    [Description("Requires a permission to switch an AutoTurret to attack-all mode and announces mode changes.")]
    public class TurretModeGuard : RustPlugin
    {
        private const string PermAttackAll = "turretmodeguard.attackall";

        private PluginConfig config;

        public class PluginConfig
        {
            [JsonProperty("Announce mode changes to authorized players")]
            public bool AnnounceChanges { get; set; } = true;

            [JsonProperty("Notify the owner when another player changes mode")]
            public bool NotifyOwner { get; set; } = 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>
            {
                ["Denied"] = "You are not allowed to switch this turret to attack-all mode.",
                ["Changed"] = "{0} set the turret to {1} mode.",
                ["OwnerNotify"] = "{0} changed your turret at {1} to {2} mode.",
                ["Peacekeeper"] = "peacekeeper",
                ["AttackAll"] = "attack-all"
            }, 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(PermAttackAll, this);
        }

        private object OnTurretModeToggle(AutoTurret autoTurret, BasePlayer player)
        {
            if (autoTurret == null || player == null || autoTurret.IsDestroyed) return null;

            bool goingAttackAll = autoTurret.PeacekeeperMode();

            if (goingAttackAll && !permission.UserHasPermission(player.UserIDString, PermAttackAll))
            {
                player.ChatMessage(Msg("Denied", player.UserIDString));
                return true;
            }

            if (config.AnnounceChanges)
            {
                string mode = goingAttackAll ? Msg("AttackAll") : Msg("Peacekeeper");
                var auth = autoTurret.authorizedPlayers;
                if (auth != null)
                {
                    foreach (var entry in auth)
                    {
                        // entry is already the ulong user id
                        var target = BasePlayer.FindByID(entry);
                        if (target != null)
                            target.ChatMessage(Msg("Changed", target.UserIDString, player.displayName, mode));
                    }
                }
            }

            if (config.NotifyOwner && autoTurret.OwnerID != 0 && autoTurret.OwnerID != player.userID.Get())
            {
                var owner = BasePlayer.FindByID(autoTurret.OwnerID);
                if (owner != null && owner.IsConnected)
                {
                    string mode = goingAttackAll ? Msg("AttackAll") : Msg("Peacekeeper");
                    var pos = autoTurret.transform.position;
                    owner.ChatMessage(Msg("OwnerNotify", owner.UserIDString, player.displayName,
                        $"({pos.x:F0}, {pos.z:F0})", mode));
                }
            }

            return null;
        }
    }
}

The plugin registers the permission turretmodeguard.attackall, which controls who may put a turret into attack-all mode. In OnTurretModeToggle it reads the turret's peacekeeper flag before the toggle applies: if the turret is currently in peacekeeper mode, the incoming request is an attack-all switch, so a player without the permission is denied and a chat message is sent; otherwise the request is a peacekeeper switch and is always allowed. When AnnounceChanges is enabled, the new mode is sent to each currently online authorized player on the turret. When NotifyOwner is enabled and the owner is a different, connected player, the owner receives a chat message with the changer's name, the turret position and the new mode. All player-facing strings come from the language file, and the hook returns early if the turret or player is missing or the turret is destroyed.

Common use cases

  • Permission-gated attack-all

    Prevent lower-ranked players from flipping turrets to attack-all and require a permission such as turretmodeguard.attackall before the change goes through.

  • Zone-based restrictions

    Block attack-all toggles for turrets inside a safe zone or near spawn by checking autoTurret.transform.position against your zone data and returning a non-null value.

  • Audit trail and owner alerts

    Log every mode change with the acting player's name and ID, and message the turret owner (look up via autoTurret.OwnerID) when someone else toggles their turret.

Pitfalls

  • Direction is not in the signature

    The hook fires for both peacekeeper and attack-all transitions with the same arguments. Read the turret's current peacekeeper state to determine which request is in flight before deciding to block.

  • Do not log with Puts in the hook body for high-traffic servers

    Every authorized toggle triggers this hook; keep the hot path cheap and queue log lines only if the operation is meaningful, or write them through data files on a timer.

  • Return value is the only way to cancel

    There is no separate CanSet hook; you must return a non-null object (for example true) to keep the turret in its current mode. Returning false also blocks the change because the patcher only checks for null.

Build a plugin with OnTurretModeToggle

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

Prompt: Permission-gated attack-all using the OnTurretModeToggle 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 OnTurretModeToggle

Generate