Skip to content
RustPluginGenerator

OnPlayerPingsSend

OnPlayerPingsSend is called in BasePlayer.SendPingsToClient right before the server RPCs the player's ping list to their client. It lets you inspect or modify the MapNoteList that will be transmitted.

Signature
void OnPlayerPingsSend(BasePlayer player, ProtoBuf.MapNoteList mapNoteList)

Parameters

Hook parameters
ParameterTypeDescription
playerBasePlayerThe BasePlayer whose ping list is being serialized to the client. This is the recipient of the Client_ReceivePings RPC and is never null at this point in the call.
mapNoteListProtoBuf.MapNoteListA pooled ProtoBuf.MapNoteList already populated with the player's current team pings from State.pings. Its notes list is what will be sent over the wire; edit, add or remove MapNote entries here to change what the client receives.

Return value

The return value is ignored. This hook cannot block or alter the RPC by returning a value; to change what is sent you must mutate mapNoteList.notes directly.

How it works

This hook fires inside BasePlayer.SendPingsToClient, immediately after the game copies the player's team pings (State.pings) into a pooled ProtoBuf.MapNoteList and right before the Client_ReceivePings RPC is sent to that client. It runs whenever the server pushes a ping update to a player, so it can fire frequently for players on active teams.

The player parameter is the receiving client and is never null. mapNoteList.notes is the live list that is about to be serialized; entries are ProtoBuf.MapNote objects carrying a position, type and label. If you clear, add or rewrite notes here, those changes go to the client and the list is cleared afterwards when the pooled object is returned.

Oxide only calls this hook, and there is only one injection site with an ignored return value, so there is no narrower overload to declare and no return value that changes behavior. Because it can fire often, do not print to console or log in the body; keep the work to cheap list edits. Anything you add only affects what that specific client sees, not the stored State.pings.

Example plugin: Filter ping types shown to clients

PingTypeFilter.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using ProtoBuf;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("Ping Type Filter", "RustPluginGenerator", "1.0.0")]
    [Description("Filters selected ping types out of the list sent to a player's client")]
    public class PingTypeFilter : RustPlugin
    {
        private const string PermUse = "pingtypefilter.use";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Hidden ping types")]
            public List<int> HiddenTypes = new List<int>();
        }

        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>
            {
                ["Reloaded"] = "Ping filter reloaded. Hiding {0} ping type(s).",
                ["NoPermission"] = "You do not have permission to use this command."
            }, 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(PermUse, this);
        }

        private void OnPlayerPingsSend(BasePlayer player, MapNoteList mapNoteList)
        {
            if (player == null || mapNoteList == null || mapNoteList.notes == null || config.HiddenTypes.Count == 0)
                return;

            for (int i = mapNoteList.notes.Count - 1; i >= 0; i--)
            {
                MapNote note = mapNoteList.notes[i];
                if (note == null) continue;

                if (config.HiddenTypes.Contains((int)note.icon))
                    mapNoteList.notes.RemoveAt(i);
            }
        }

        [ChatCommand("pingfilter")]
        private void CmdPingFilter(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;
            if (!permission.UserHasPermission(player.UserIDString, PermUse))
            {
                SendReply(player, Msg("NoPermission", player.UserIDString));
                return;
            }

            LoadConfig();
            SendReply(player, Msg("Reloaded", player.UserIDString, config.HiddenTypes.Count));
        }
    }
}

The plugin reads a config of ping type numbers that should be hidden from clients. When the server sends a player's ping list, OnPlayerPingsSend runs and the plugin walks mapNoteList.notes, removing any MapNote whose icon value (cast to int) is in the HiddenTypes list. Because the list is the exact object about to be sent, the player never receives the filtered pings. The hook only manipulates the in-memory list, so it stays cheap, and it does not touch the server's stored pings. Admins can run the pingfilter chat command (permission pingtypefilter.use) to reload the config; the reply reports how many ping types are hidden.

Common use cases

  • Hide noisy ping types

    Remove or rewrite specific ping types so they never reach a player's client, useful when a plugin floods the map with pings of one kind.

  • Add custom pings per viewer

    Append MapNote entries to the outgoing list to show a player marker only they can see, without storing it in State.pings.

  • Clamp ping coordinates

    Adjust a note's position before it is serialized, for example to snap pings to a grid or offset ones placed worse than a threshold.

Pitfalls

  • Do not log here

    This can fire many times a second for players on active teams. Printing or writing to data inside the hook will spam the console and hurt performance; keep the body to list edits.

  • Changes are per-client

    Editing mapNoteList only affects the RPC for that player. The server's State.pings list is untouched, so other players and future sends see the original data.

  • The list is pooled

    mapNoteList and its notes list are pooled objects used for just this send. Do not cache references to them or mutate them after the hook returns.

Build a plugin with OnPlayerPingsSend

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

Prompt: Hide noisy ping types using the OnPlayerPingsSend 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 OnPlayerPingsSend

Generate