Skip to content
RustPluginGenerator

OnPhoneNameUpdate

OnPhoneNameUpdate is called when a player submits a new name for a telephone through the PhoneController.UpdatePhoneName method, before the name is written to the entity. Returning a non-null value cancels the rename.

Signature
object OnPhoneNameUpdate(PhoneController phoneController, string newName, BasePlayer currentPlayer)

Parameters

Hook parameters
ParameterTypeDescription
phoneControllerPhoneControllerThe PhoneController entity whose name is being changed. Use it to inspect the phone's owner, position or current name before deciding whether to allow the change.
newNamestringThe requested name after the game has already trimmed it to 30 characters. Check it for blocked words or unwanted characters here.
currentPlayerBasePlayerThe BasePlayer performing the rename. Can be null when the call does not come from a player, so null-check before reading player data.

Return value

Return null to let the original code continue: the phone's name is set, a network update is sent and OnPhoneNameUpdated fires. Return any non-null value to skip all of that, leaving the previous name unchanged and suppressing the follow-up hook.

How it works

The hook fires from PhoneController.UpdatePhoneName, which runs when a player types a new name on a telephone's interface. The game first trims the requested string down to 30 characters, then calls this hook with the PhoneController, the trimmed newName and the currentPlayer doing the rename. If no plugin blocks it, the game assigns PhoneName, sends a network update so nearby clients see the new label, and then fires OnPhoneNameUpdated.

Because currentPlayer is the only player reference, it is the natural place to check permissions, team membership or rate limits. The hook runs before the name is applied, so it is the correct place to reject offensive names: return a non-null value to stop the write. Declare currentPlayer as BasePlayer to keep Oxide dispatching the hook only when the argument actually is a player; if you write it as BaseEntity or object, the hook also fires for calls where the player is null. Keep the handler cheap, since it is invoked once per rename attempt. Note the trimming already happened, so newName is never longer than 30 characters when you receive it.

Example plugin: Enforce a name blacklist and audit renames for phones

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

namespace Oxide.Plugins
{
    [Info("Phone Name Filter", "RustPluginGenerator", "1.0.0")]
    [Description("Filters telephone names against a configurable word list and logs accepted renames")]
    public class PhoneNameFilter : RustPlugin
    {
        private const string PermBypass = "phonenamefilter.bypass";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Blocked words")]
            public List<string> BlockedWords = new List<string> { "admin", "moderator" };

            [JsonProperty("Log accepted renames to console")]
            public bool LogRenames = true;

            [JsonProperty("Rate limit seconds between renames")]
            public float CooldownSeconds = 3f;
        }

        private readonly Dictionary<ulong, float> lastRename = 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>
            {
                ["Blocked"] = "That name contains a restricted word",
                ["Cooldown"] = "Please wait a moment before renaming again",
                ["Accepted"] = "Phone renamed to: {0}"
            }, 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 OnPhoneNameUpdate(PhoneController phoneController, string newName, BasePlayer currentPlayer)
        {
            if (phoneController == null || string.IsNullOrEmpty(newName))
                return null;

            if (currentPlayer == null || !currentPlayer.IsConnected)
                return null;

            if (currentPlayer.UserIDString != null && permission.UserHasPermission(currentPlayer.UserIDString, PermBypass))
                return null;

            float now = Time.realtimeSinceStartup;
            float last;
            if (config.CooldownSeconds > 0f && lastRename.TryGetValue(currentPlayer.userID.Get(), out last) && now - last < config.CooldownSeconds)
            {
                currentPlayer.ChatMessage(Msg("Cooldown", currentPlayer.UserIDString));
                return true;
            }

            string lower = newName.ToLowerInvariant();
            foreach (string word in config.BlockedWords)
            {
                if (string.IsNullOrEmpty(word)) continue;
                if (lower.Contains(word.ToLowerInvariant()))
                {
                    currentPlayer.ChatMessage(Msg("Blocked", currentPlayer.UserIDString));
                    return true;
                }
            }

            lastRename[currentPlayer.userID.Get()] = now;
            currentPlayer.ChatMessage(Msg("Accepted", currentPlayer.UserIDString, newName));

            if (config.LogRenames)
                Puts($"{currentPlayer.displayName} ({currentPlayer.UserIDString}) renamed a phone to: {newName}");

            return null;
        }
    }
}

The plugin keeps a configurable list of blocked words plus an optional permission that bypasses the filter. OnPhoneNameUpdate lowercases the requested newName, scans it for each blocked entry and, if a match is found, sends a chat reply to the renaming player through the language file and returns a non-null value so the game never writes the name. Allowed renames are logged to the server console with the player's display name and the new label. The currentPlayer null-check keeps the hook safe when the rename does not originate from a player, and the permission code phonenamefilter.bypass lets staff set any name.

Common use cases

  • Block offensive phone names

    Scan newName against a configurable word list and return a non-null value to reject it, replying to the player so they know why.

  • Rate limit renames

    Track the last rename time per SteamID in a dictionary and return non-null while the player is still on cooldown.

  • Restrict naming to a permission or team

    Only allow renames for players holding a permission node or belonging to the phone owner's team, returning non-null otherwise.

Pitfalls

  • The name is already trimmed

    The game cuts newName to 30 characters before the hook runs, so length checks beyond that will never trigger. Filter for content, not length.

  • `currentPlayer` can be null

    Reading currentPlayer.UserIDString without a null check throws. Guard it, and declare the parameter as BasePlayer to keep Oxide matching only real player calls.

  • Explaining the rejection

    Returning non-null silently does nothing visible. Send a chat message through the language file so the player knows why their name was rejected.

Build a plugin with OnPhoneNameUpdate

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

Prompt: Block offensive phone names using the OnPhoneNameUpdate 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 OnPhoneNameUpdate

Generate