Skip to content
RustPluginGenerator

OnPhoneDialFailed

OnPhoneDialFailed is called when a PhoneController's dial attempt fails and the game is about to report the failure to the caller.

Signature
void OnPhoneDialFailed(PhoneController phoneController, Telephone.DialFailReason reason, BasePlayer currentPlayer)

Parameters

Hook parameters
ParameterTypeDescription
phoneControllerPhoneControllerThe PhoneController entity that failed to place the call. Use it to read the dialed number and the entity's position or owner.
reasonTelephone.DialFailReasonThe Telephone.DialFailReason the game passed in, such as no answer, busy, or invalid number. Treat unexpected values defensively when switching on it.
currentPlayerBasePlayerThe BasePlayer who attempted the call. May be null in edge cases, so check it before sending chat or UI.

Return value

The return value is ignored. This hook cannot stop the game from processing or reporting the failed dial; it is purely observational.

How it works

This hook fires from PhoneController.OnDialFailed, right after the controller cancels its pending dial-timeout invoke and before anything else happens. It runs on both successful-looking ends of a call attempt where the game decided the dial did not connect: unreachable numbers, a receiver that did not answer, or a rejected connection. The reason value tells you which case it was, phoneController gives you the entity (owner ID, position, dialed number) and currentPlayer is the player who pressed dial.

Because the parameter types are already specific (PhoneController, BasePlayer), there is nothing to narrow. Just null-check currentPlayer and phoneController before using them. The hook is not hot: it only fires on failed calls, so short chat replies, effect plays or logging are acceptable here. Do not assume the player is still connected, and do not rely on reason having any value beyond the documented enum members. Cancelling the original flow is not possible: the return value is ignored.

Example plugin: Tell players why a phone call failed and rate-limit spam

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

namespace Oxide.Plugins
{
    [Info("Phone Dial Failure Notice", "RustPluginGenerator", "1.0.0")]
    [Description("Sends a localized chat message when a player's phone call fails to dial")]
    public class PhoneDialFailureNotice : RustPlugin
    {
        private PluginConfig config;
        private readonly Dictionary<ulong, float> lastNotice = new Dictionary<ulong, float>();

        private class PluginConfig
        {
            [JsonProperty("Cooldown seconds between notices")]
            public float CooldownSeconds = 8f;
        }

        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>
            {
                ["Busy"] = "That line is busy right now.",
                ["NoAnswer"] = "Nobody picked up the phone.",
                ["NoCarrier"] = "The call could not be connected.",
                ["Generic"] = "Your call failed to dial ({0}).",
                ["Cooldown"] = "Please wait before trying again."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args) =>
            string.Format(lang.GetMessage(key, this, userId), args);

        private void OnPhoneDialFailed(PhoneController phoneController, Telephone.DialFailReason reason, BasePlayer currentPlayer)
        {
            if (currentPlayer == null || !currentPlayer.IsConnected)
                return;

            float now = Time.realtimeSinceStartup;
            float last;
            if (lastNotice.TryGetValue(currentPlayer.userID, out last) && now - last < config.CooldownSeconds)
                return;
            lastNotice[currentPlayer.userID] = now;

            string key;
            switch (reason.ToString())
            {
                case "Busy":
                    key = "Busy";
                    break;
                case "NoAnswer":
                    key = "NoAnswer";
                    break;
                case "NoCarrier":
                    key = "NoCarrier";
                    break;
                default:
                    currentPlayer.ChatMessage(Msg("Generic", currentPlayer.UserIDString, reason));
                    return;
            }

            currentPlayer.ChatMessage(Msg(key, currentPlayer.UserIDString));
        }

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

The plugin declares OnPhoneDialFailed and stores the last dial attempt per player ID. When the hook fires it checks the player is still connected, formats a human-readable reason through the language file, and sends a single chat reply to the caller. A configurable cooldown suppresses repeats within a short window so players pressing dial over and over do not flood chat. Unknown enum values fall back to a generic message. Everything is cleaned up in Unload.

Common use cases

  • Explain failed calls in chat

    Map each DialFailReason to a localized message so players learn whether the line was busy, the receiver rejected the call, or the number was wrong.

  • Track call attempts for stats

    Count failures per player or per reason and expose totals through a console command for server owners reviewing usage.

  • Handle offline or busy targets

    Combine with stored numbers on your own records to show a custom notice when the target player was recently seen online but did not pick up.

Pitfalls

  • currentPlayer can be null

    Hook parameters are not guaranteed non-null; guard before calling ChatMessage or reading UserIDString.

  • Reason enum is small and may grow

    Do not switch without a default branch. Facepunch can add members, and an unhandled value would otherwise send nothing or throw.

  • Do not spam chat on every attempt

    Players often redial rapidly; add a per-player cooldown or the chat scroll will be unreadable.

Build a plugin with OnPhoneDialFailed

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

Prompt: Explain failed calls in chat using the OnPhoneDialFailed 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 OnPhoneDialFailed

Generate