Skip to content
RustPluginGenerator

OnServerCommand

OnServerCommand is called by Oxide's command dispatcher before a console command is executed, giving plugins a chance to block it. Returning a non-null value stops the command from running.

Signature
object OnServerCommand(ConsoleSystem.Arg arg)

Parameters

Hook parameters
ParameterTypeDescription
argConsoleSystem.ArgThe ConsoleSystem.Arg describing the queued console command: arg.cmd.FullName is the command string (e.g. 'global.kill'), arg.Connection identifies the calling client (null for server console/RCON), arg.Player() resolves the connected player, and arg.Args holds the raw string arguments.

Return value

Return null (or nothing) to let the command run normally. Return any non-null object to block the command entirely; Oxide then reports the command as handled and the original command never executes. A returned value does not become the command's output, it only acts as a stop signal.

How it works

This hook is not a patched game method; Oxide calls it from its own IOnServerCommand gate before a player or server console command reaches the game. It runs for player-issued commands (arg.Connection is set) and for commands executed server-side or over RCON (arg.Connection is null). Three chat commands, chat.say, chat.teamsay and chat.localsay, are filtered out before the hook and never reach it, so use OnPlayerChat for chat. arg.cmd.FullName gives the command path, arg.Args the argument array, and arg.Player() the issuing player or null. The hook also has a second, covalence-style form OnServerCommand(string command, string[] args); Oxide calls both and prefers the Arg result when both return something. Declaring the parameter as ConsoleSystem.Arg keeps you on this overload. It fires for every command a client sends, which can be many per second, so keep the body cheap and avoid logging.

Example plugin: Block .kill and other commands for non-admins

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

namespace Oxide.Plugins
{
    [Info("Command Blocker", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks configured console commands unless the player has a bypass permission")]
    public class CommandBlocker : RustPlugin
    {
        private const string PermBypass = "commandblocker.bypass";

        private PluginConfig config;
        private HashSet<string> blocked;

        private class PluginConfig
        {
            [JsonProperty("Blocked commands")]
            public List<string> BlockedCommands = new List<string>
            {
                "kill",
                "respawn",
                "global.kill",
                "global.respawn"
            };
        }

        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"] = "The command '{0}' is not allowed on this server."
            }, 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 void OnServerInitialized()
        {
            blocked = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            foreach (string command in config.BlockedCommands)
            {
                if (!string.IsNullOrEmpty(command))
                    blocked.Add(command.Trim());
            }
        }

        private object OnServerCommand(ConsoleSystem.Arg arg)
        {
            if (arg == null || arg.cmd == null || blocked == null || blocked.Count == 0)
                return null;

            string command = arg.cmd.FullName;
            if (string.IsNullOrEmpty(command) || !blocked.Contains(command))
                return null;

            BasePlayer player = arg.Player();
            if (player == null)
                return null;

            if (permission.UserHasPermission(player.UserIDString, PermBypass))
                return null;

            player.ChatMessage(Msg("Blocked", player.UserIDString, command));
            return false;
        }
    }
}

The plugin stores a list of blocked console commands in its config and registers a permission that grants exemptions. In OnServerCommand it reads arg.cmd.FullName, ignores anything not on the list, and resolves the calling player through arg.Player(). Server console and RCON calls have no player and pass through untouched. If a player issues a blocked command without commandblocker.bypass, the plugin sends a localized chat reply and returns false to stop the command. Because the hook can fire rapidly, nothing is logged per call; the only output is the reply to the blocked player.

Common use cases

  • Block client console commands

    Prevent players from running commands like kill, respawn or global.inventory outside their intended context by returning a truthy value from the hook.

  • Audit or gate admin tooling

    Only allow a whitelist of commands to players in an admin group, blocking everything else and replying with a permission message.

  • Rate-limit spammy commands

    Track per-player command timestamps and block a command when it arrives too frequently, reducing input flooding on the server.

Pitfalls

  • Chat commands are excluded

    chat.say, chat.teamsay and chat.localsay are filtered out before this hook is called, so blocking them here silently fails. Use OnPlayerChat or OnUserChat instead.

  • Runs at high frequency

    Any client can send commands repeatedly, so the hook body should be a fast string comparison against a small set. Avoid allocations, data file reads or logging inside it.

  • Two overloads are invoked

    Oxide also calls OnServerCommand(string, string[]). If you implement both, keep their return values consistent; the Arg result takes priority when it is non-null.

Plugin recipes that use OnServerCommand

Build a plugin with OnServerCommand

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

Prompt: Block client console commands using the OnServerCommand 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 OnServerCommand

Generate