OnPhoneCallStart
OnPhoneCallStart is called when a phone begins placing an outgoing call, before the game proceeds with connecting the handset to its target. Returning a non-null value cancels the call.
object OnPhoneCallStart(PhoneController phoneController, PhoneController activeCallTo, BasePlayer currentPlayer)Parameters
| Parameter | Type | Description |
|---|---|---|
phoneController | PhoneController | The PhoneController of the phone that is placing the call, i.e. the caller's handset. Use it to read its position, owner ID or network ID. |
activeCallTo | PhoneController | The PhoneController on the receiving end of the call. May be null when the phone has no target set yet, so null-check before reading it. |
currentPlayer | BasePlayer | The BasePlayer who is starting the call. Can be null in edge cases, so guard against it before using inventory, team or permission data. |
Return value
Returning null lets the call continue to the game's normal logic. Returning any non-null object cancels the original code path inside PhoneController.BeginCall, so the call is not placed. Since the method returns void, the actual value you return only matters as a signal; true is the conventional choice.
How it works
The hook fires at the top of PhoneController.BeginCall, which runs when a player uses a telephone in Rust to dial out to another handset. phoneController is the caller's handset, activeCallTo is the handset being called (this can be null if no target has been assigned yet), and currentPlayer is the player using the phone. The hook runs before the game checks whether the phone is a mobile handset and whether the target requires power, so anything you do here happens before any call state is established.
Because the dispatch only checks that each argument matches the declared parameter type, declaring BasePlayer currentPlayer (as in the signature) is the normal choice. You cannot narrow PhoneController to a more specific type since there is nothing below it to narrow to. Null-check activeCallTo and currentPlayer; when a call is placed through an unusual path one of them can be absent.
This is the place to enforce rules such as a permission gate, a cooldown between calls, blocking calls during a server event, or logging who dials whom. The hook can fire on every dial attempt, so keep the body cheap and avoid logging unless a debug flag is enabled.
Example plugin: Block phone calls without a permission
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Phone Call Permission", "RustPluginGenerator", "1.0.0")]
[Description("Requires a permission before a player can place an outgoing phone call.")]
public class PhoneCallPermission : RustPlugin
{
private const string PermUse = "phonecallpermission.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Notify player when call is blocked")]
public bool NotifyBlocked { get; set; } = true;
[JsonProperty("Admins bypass permission")]
public bool AdminsBypass { 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>
{
["NoPermission"] = "You do not have permission to use the telephone."
}, this);
}
private string Msg(string key, string userId = null) => lang.GetMessage(key, this, userId);
private void Init()
{
permission.RegisterPermission(PermUse, this);
}
private object OnPhoneCallStart(PhoneController phoneController, PhoneController activeCallTo, BasePlayer currentPlayer)
{
if (currentPlayer == null || currentPlayer.IsNpc)
return null;
if (config.AdminsBypass && currentPlayer.IsAdmin)
return null;
if (permission.UserHasPermission(currentPlayer.UserIDString, PermUse))
return null;
if (config.NotifyBlocked)
currentPlayer.ChatMessage(Msg("NoPermission", currentPlayer.UserIDString));
return true;
}
}
}The plugin registers phonecallpermission.use in Init and gives administrators access automatically. When OnPhoneCallStart fires it verifies currentPlayer and the permission, and returns true to cancel the call when the player is not authorised. Denied players additionally receive a chat message from the language file, and the config controls both the denial message toggle and whether admins bypass the check. Because the hook fires on each dial, the permission lookup is the only work done on the hot path; there is no periodic timer or global state.
Common use cases
Permission-gated telephone
Allow only players with a specific permission to place outgoing calls, for example on a VIP-only server or during a restricted event.
Call cooldown
Record the last call time per player ID in a dictionary and return non-null when a new call is attempted before the cooldown expires.
Audit log of dial attempts
Write the caller's name and the target handset's owner to a data file so staff can review who is spamming the phone network.
Pitfalls
activeCallTo can be null
The receiving handset may not be set when the hook runs. Always null-check it before reading its owner or network ID, otherwise you will throw inside the hook.
Hook fires before phone state is established
Anything the game does after the injection (mobile checks, power requirements) has not run yet, so do not assume the call is actually in progress inside this hook.
Do not log on every call
Busy servers can see many dial attempts from the same player. Guard any
Putsor chat output behind a debug flag so it does not spam the console.
Build a plugin with OnPhoneCallStart
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 OnPhoneCallStart
Generate