Skip to content
RustPluginGenerator

OnPhoneDialTimeout

OnPhoneDialTimeout is called on the server when a player's phone stops ringing without being answered. It runs inside PhoneController.TimeOutDialing and lets you suppress the answering-machine message.

Signature
object OnPhoneDialTimeout(PhoneController activeCallTo, PhoneController phoneController, BasePlayer currentPlayer)

Parameters

Hook parameters
ParameterTypeDescription
activeCallToPhoneControllerThe PhoneController the caller is trying to reach; it holds the dialing state and its currentPlayer is who would pick up.
phoneControllerPhoneControllerThe PhoneController of the phone that is dialing out (the caller's phone).
currentPlayerBasePlayerThe player the ringing phone is assigned to, i.e. activeCallTo.currentPlayer. Can be null if the target phone lost its owner.

Return value

Returning null lets the original code continue, so the answering message is played to the caller. Returning any non-null value stops the remainder of TimeOutDialing, so no answering message is sent and the call ends silently.

How it works

The hook fires in PhoneController.TimeOutDialing, which the game runs after a dialed phone has rung for the full timeout period without anyone picking up. At that point the answering message (the recorded greeting on the target phone) is about to be sent to the caller through ServerPlayAnsweringMessage. You get both ends of the attempt: phoneController is the dialing phone, activeCallTo is the target PhoneController, and currentPlayer is the player the target belongs to. All three can be inspected, and null checks are necessary because a phone may have been destroyed or its owner disconnected during the ring. Declaring a more specific type is not possible here since the parameters are already concrete classes. Return something non-null to skip the answering message entirely, which turns a missed call into a silent drop; return null to let the normal behavior run.

Example plugin: Silence missed-call greetings on a PvE server

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

namespace Oxide.Plugins
{
    [Info("Phone Timeout Control", "RustPluginGenerator", "1.0.0")]
    [Description("Suppresses the answering-machine greeting on dial timeouts and notifies the caller.")]
    public class PhoneTimeoutControl : RustPlugin
    {
        private const string PermKeepGreeting = "phonetimeoutcontrol.keepgreeting";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Suppress answering message on timeout")]
            public bool SuppressGreeting { get; set; } = true;

            [JsonProperty("Notify caller about the missed call")]
            public bool NotifyCaller { 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>
            {
                ["MissedCall"] = "Your call was not answered. The phone stopped ringing.",
                ["GreetingKept"] = "Your call timed out and the greeting played."
            }, 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(PermKeepGreeting, this);
        }

        private object OnPhoneDialTimeout(PhoneController activeCallTo, PhoneController phoneController, BasePlayer currentPlayer)
        {
            if (phoneController == null) return null;

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

            if (!config.SuppressGreeting) return null;
            if (permission.UserHasPermission(caller.UserIDString, PermKeepGreeting)) return null;

            if (config.NotifyCaller)
            {
                caller.ChatMessage(Msg("MissedCall", caller.UserIDString));
            }

            return true;
        }
    }
}

The plugin watches for dial timeouts and decides whether the answering machine should play. A config flag turns the feature on, and a permission lets staff keep the vanilla greeting. It also counts timeouts per player and pushes a short chat note to the caller, so players know the target simply did not answer instead of hearing a recording. activeCallTo.currentPlayer is read defensively because the phone owner may be null or disconnected at timeout. Returning a non-null object blocks ServerPlayAnsweringMessage; returning null keeps vanilla behavior.

Common use cases

  • Serve a custom greeting instead of the recorded one

    Block the default answering message and broadcast your own notice so every unanswered call is handled uniformly across the server.

  • End calls silently on roleplay servers

    Skip the answering machine entirely so a missed call just stops ringing, which suits servers that treat voice messages as out of character.

  • Log unanswered dial attempts

    Record who called whom at timeout for staff review of harassment reports, while still letting the normal greeting play.

Pitfalls

  • Owner may be gone

    activeCallTo.currentPlayer can be null if the target disconnected or the phone was destroyed mid-ring; always null-check before reading player data.

  • Returning a value cancels the greeting

    Any non-null return short-circuits the rest of TimeOutDialing, including the play-answering-message call — return null whenever you want vanilla behavior.

  • The call is already closing

    The timeout means the connection is being torn down; do not try to re-dial or keep the call alive from this hook, the call state is already finishing.

Build a plugin with OnPhoneDialTimeout

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

Prompt: Serve a custom greeting instead of the recorded one using the OnPhoneDialTimeout 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 OnPhoneDialTimeout

Generate