Skip to content
RustPluginGenerator

OnEntityFromOwnerCheck

OnEntityFromOwnerCheck is called when a BaseEntity receives the FromOwner RPC, right before the server compares the entity's network ID against the player's network ID to decide whether the entity belongs to that player.

Signature
object OnEntityFromOwnerCheck(BaseEntity entity, BasePlayer player, uint ownerId, string debugName)

Parameters

Hook parameters
ParameterTypeDescription
entityBaseEntityThe BaseEntity whose ownership relationship is being compared, usually the entity that was sent to the client in the FromOwner RPC.
playerBasePlayerThe BasePlayer whose network connection received the RPC. Use this to identify the spectator or owner being checked against the entity.
ownerIduintThe raw uint owner identifier carried by the RPC packet. It is the value the client claims as the entity owner before the server compares it to network IDs.
debugNamestringA string label sent along with the RPC, typically used for diagnostics. It can be empty and should not be treated as gameplay data.

Return value

Return a bool to override the RPC result: true or false is returned directly from FromOwner.Test. Returning null (or any non-bool value) lets the server proceed to its own entity.net.ID == player.net.ID comparison.

How it works

This hook fires inside the FromOwner.Test server RPC handler on BaseEntity. When a client sends the FromOwner RPC, the server already has the entity, the sending player, an owner id and a debug name. Before Oxide continues into the ID comparison (entity.net.ID == player.net.ID), it calls your hook. Returning a bool decides the RPC result; returning anything else lets the original comparison run.

The parameters are useful for auditing or filtering owner checks: entity is the target network object, player is the connection's player, ownerId is the claimed owner value from the packet and debugName is a label for logging. Because the hook is called per RPC, you can inspect which entities and players are exchanging owner checks, or force a specific outcome.

Narrowing parameters does not help much here: entity is always a BaseEntity and player a BasePlayer. If you need to react only to certain entity types, cast and compare inside the hook. Keep the method cheap, avoid Puts here, and never block the original path unless you are deliberately overriding ownership semantics on your server.

Example plugin: Audit and allow owner RPCs for a whitelist of prefabs

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

namespace Oxide.Plugins
{
    [Info("Owner Rpc Guard", "RustPluginGenerator", "1.0.0")]
    [Description("Restricts which entity prefabs may pass the FromOwner RPC ownership check.")]
    public class OwnerRpcGuard : RustPlugin
    {
        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Allow all prefabs (disable guard)")]
            public bool AllowAll = false;

            [JsonProperty("Allowed prefab short names")]
            public List<string> AllowedPrefabs = new List<string>
            {
                "box.wooden.large",
                "cupboard.tool.deployed",
                "furnace",
                "woodbox_deployed"
            };

            [JsonProperty("Log rejected RPCs")]
            public bool LogRejected = false;
        }

        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);

        private object OnEntityFromOwnerCheck(BaseEntity entity, BasePlayer player, uint ownerId, string debugName)
        {
            if (entity == null || player == null) return null;
            if (config.AllowAll) return null;

            string shortName = entity.ShortPrefabName;
            if (string.IsNullOrEmpty(shortName)) return null;

            if (config.AllowedPrefabs != null && config.AllowedPrefabs.Contains(shortName))
                return null;

            if (config.LogRejected)
                Interface.Oxide.LogWarning("Rejected FromOwner RPC from {0} for prefab {1} (owner {2})",
                    player.userID, shortName, ownerId);

            return false;
        }
    }
}

The plugin tracks which entity prefabs are allowed to send FromOwner RPCs. It keeps a short list of prefab short names in the config file, so admins can edit it without recompiling. When OnEntityFromOwnerCheck fires, the plugin checks the entity's ShortPrefabName against the whitelist. If the prefab is not listed, it returns false to reject the RPC; otherwise it returns null so the normal ID comparison runs. A debug option logs rejections to the server console at a throttled rate to avoid flooding output.

Common use cases

  • Reject unexpected FromOwner RPCs

    Block RPCs for prefabs that should never receive an owner check, cutting off malformed or spammy client traffic on a hardened server.

  • Log owner checks per player

    Record which players are sending FromOwner RPCs and to which entities, useful when investigating entities behaving oddly after client interaction.

  • Force ownership for custom entities

    Return true for specific prefabs so a custom entity is considered owned even when the player's network ID differs from the entity's, if your plugin manages ownership itself.

Pitfalls

  • Returning true weakens validation

    Returning true for every entity skips the built-in network-ID comparison, so any connected player can pass the ownership check. Only override for prefabs you fully control.

  • Called per RPC, not per tick

    This hook can fire often on busy servers. Keep the body to a dictionary lookup or cast, and never call PrintWarning or Puts inside it.

  • debugName is not trusted data

    The debug name is supplied by the client RPC and can be arbitrary. Do not branch gameplay logic on it or persist it without sanitizing.

Build a plugin with OnEntityFromOwnerCheck

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

Prompt: Reject unexpected FromOwner RPCs using the OnEntityFromOwnerCheck 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 OnEntityFromOwnerCheck

Generate