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.
object OnTurretModeToggle(AutoTurret autoTurret, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
autoTurret | AutoTurret | The AutoTurret whose mode is being changed. Use it to read position, authorization list or peacekeeper state, or to react differently per turret. |
player | BasePlayer | The 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
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.attackallbefore the change goes through.Zone-based restrictions
Block attack-all toggles for turrets inside a safe zone or near spawn by checking
autoTurret.transform.positionagainst 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.
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