OnPlayerVoice
OnPlayerVoice is called on the server for every incoming voice packet before the audio is delivered to the rest of the server. Returning a non-null value drops that voice frame instead of passing it to BasePlayer.OnReceivedVoice.
object OnPlayerVoice(BasePlayer player, ArraySegment<byte> voiceData)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who sent the voice packet, resolved by the server from the network connection. It is never null at the hook call site. |
voiceData | ArraySegment<byte> | The raw voice payload as an ArraySegment<byte> with the packet header already stripped. Its Count is the byte length of this voice frame. |
Return value
Returning null passes the voice frame on to BasePlayer.OnReceivedVoice, which delivers it to listeners. Returning any non-null object (a bool, a string, anything) skips that delivery and the frame is dropped; the returned value itself is not used.
How it works
The hook fires inside ServerMgr.OnPlayerVoice after the server has read the sender from the network packet and sliced the voice payload into an ArraySegment<byte>. It runs for each voice frame a client uploads, so it can fire many times per second for an active speaker. player is the sender; voiceData holds the encoded audio bytes (the frame is capped by the server's maxpacketsize_voicedata convar before the hook is reached, so oversized frames never call it).
Declaring player as a more specific type is not useful here because only BasePlayer is passed, and narrowing it to a subclass would simply stop the hook from ever running. To drop a frame, return any non-null object; returning null lets the frame continue to the normal voice broadcast. Because this runs on the hot path of voice traffic, keep the body cheap: no allocations, no logging, no data file writes. Counting, muting or rate-limiting based on the sender are the practical uses.
Example plugin: Voice mute for players with a permission
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("VoiceMute", "RustPluginGenerator", "1.0.0")]
[Description("Grants admins a permission-driven server-side voice mute for players.")]
public class VoiceMute : RustPlugin
{
private const string PermUse = "voicemute.use";
private const string PermMuted = "voicemute.muted";
private void Init()
{
permission.RegisterPermission(PermUse, this);
permission.RegisterPermission(PermMuted, this);
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Muted"] = "{0} is now voice muted.",
["Unmuted"] = "{0} can speak again.",
["NoPermission"] = "You do not have permission to use this command.",
["NotFound"] = "No player found with that name or id.",
["Usage"] = "Usage: /voicemute <name or steamid>"
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
=> string.Format(lang.GetMessage(key, this, userId), args);
private object OnPlayerVoice(BasePlayer player, System.ArraySegment<byte> voiceData)
{
if (player == null || voiceData.Count == 0) return null;
if (!permission.UserHasPermission(player.UserIDString, PermMuted)) return null;
return false;
}
[ChatCommand("voicemute")]
private void CmdVoiceMute(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, PermUse))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return;
}
if (args == null || args.Length < 1)
{
player.ChatMessage(Msg("Usage", player.UserIDString));
return;
}
BasePlayer target = BasePlayer.FindAwakeOrSleeping(args[0]);
if (target == null)
{
player.ChatMessage(Msg("NotFound", player.UserIDString));
return;
}
if (permission.UserHasPermission(target.UserIDString, PermMuted))
{
permission.RevokeUserPermission(target.UserIDString, PermMuted);
player.ChatMessage(Msg("Unmuted", player.UserIDString, target.displayName));
}
else
{
permission.GrantUserPermission(target.UserIDString, PermMuted, this);
player.ChatMessage(Msg("Muted", player.UserIDString, target.displayName));
}
}
}
}The plugin registers a voicemute.muted permission that admins grant to silence a player. OnPlayerVoice checks whether the sender holds that permission and, if so, returns false so the frame never reaches OnReceivedVoice. Muted players can still hear others; only their outgoing audio is discarded. A chat command toggles the permission for a target player, and LoadDefaultMessages keeps the feedback text in the language files. No state is cached, so the mute takes effect on the very next voice frame and the body stays allocation-free on the voice hot path.
Common use cases
Permission-based voice mute
Silence outgoing audio for specific players by checking a permission inside the hook and returning a non-null value. Toggled from chat without touching config data.
Team-only comms
Drop voice frames from players who are not in a team, or restrict incoming audio by comparing
player.currentTeamagainst the listener's team in your own relay logic.Rate limiting and abuse handling
Track per-player frame counts in a dictionary and return non-null once a player exceeds a reasonable voice frequency, reducing spam audio without kicking.
Pitfalls
No listener information in the hook
The hook only tells you who spoke, not who will hear it. You cannot selectively mute one recipient here; you can only block the whole frame, which affects all listeners.
Hot path, keep it cheap
This fires per voice frame, so avoid allocating, iterating player lists or writing data. Cache permission results only if you have a cheap invalidation path, otherwise a single permission lookup is fine.
Muting is server-side only
Players who muted someone via the game client already stop hearing them; returning non-null here stops the frame from ever being broadcast, but does not change the client mute state.
Build a plugin with OnPlayerVoice
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 OnPlayerVoice
Generate