OnBuildingPrivilege
OnBuildingPrivilege is called from BaseEntity.GetBuildingPrivilege whenever the game resolves which building privilege (tool cupboard) applies to an entity, and lets a plugin override the result.
object OnBuildingPrivilege(BaseEntity entity, OBB obb, bool cached, float cacheDuration, BuildingPrivlidge exclude, bool ignorePosition)Parameters
| Parameter | Type | Description |
|---|---|---|
entity | BaseEntity | The BaseEntity whose building privilege is being resolved. Usually a player, a deployed deployable or a projectile asking whether it stands inside a cupboard zone. |
obb | OBB | The oriented bounding box used for the position test against each cupboard's privilege volume. |
cached | bool | True when the caller allows the cached privilege result to be reused; false forces a fresh computation. |
cacheDuration | float | How long, in seconds, a cached privilege lookup stays valid before it is recomputed. |
exclude | BuildingPrivlidge | A BuildingPrivlidge that must be ignored in the lookup, typically the cupboard itself when it is checking its own zone. |
ignorePosition | bool | When true the position/OBB test is skipped, so the lookup does not depend on where the entity stands. |
Return value
Return a BuildingPrivlidge to use that cupboard as the privilege result for this call. Returning null or any other type leaves the original method running, so the cached check and the regular OBB-based lookup produce the result.
How it works
The hook fires inside BaseEntity.GetBuildingPrivilege(OBB obb, bool cached, float cacheDuration, BuildingPrivlidge exclude, bool ignorePosition). That method is used all over the server: player build checks, deployable placement, damage and decay logic, raid protection tests and anything else that needs to know which cupboard governs a position. The hook receives the entity doing the query, the OBB used for the position test, the cache flags, the cupboard to exclude (often the cupboard performing its own check) and the ignorePosition flag.
Returning a BuildingPrivlidge replaces the game's answer. Returning null (or any other type) lets the original method run: the cached result, then the normal spatial lookup. You can narrow entity to a more specific type such as BasePlayer; Oxide then only calls your method when the argument really is that type, which lets you scope rules to players. Keep the method cheap because build, damage and decay code calls it frequently, and avoid Puts inside it.
Example plugin: Infinite upkeep privilege for a protected zone
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Upkeep Zone Privilege", "RustPluginGenerator", "1.0.0")]
[Description("Treats players standing near configured tool cupboards as privileged there.")]
public class UpkeepZonePrivilege : RustPlugin
{
private const string PermUse = "upkeepzoneprivilege.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Enable plugin")]
public bool Enabled = true;
[JsonProperty("Only players with permission")]
public bool RequirePermission = false;
[JsonProperty("Cupboards and radius (cupboard name -> radius in metres)")]
public Dictionary<string, float> Zones = new Dictionary<string, float>
{
["shop_cupboard"] = 15f
};
}
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 void Init()
{
permission.RegisterPermission(PermUse, this);
}
private object OnBuildingPrivilege(BaseEntity entity, OBB obb, bool cached, float cacheDuration, BuildingPrivlidge exclude, bool ignorePosition)
{
if (!config.Enabled || ignorePosition || entity == null) return null;
var player = entity as BasePlayer;
if (player == null || player.IsNpc) return null;
if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermUse)) return null;
Vector3 position = player.transform.position;
foreach (var pair in config.Zones)
{
var cupboards = FindCupboard(pair.Key);
for (int i = 0; i < cupboards.Count; i++)
{
var cupboard = cupboards[i];
if (cupboard == null || cupboard == exclude || cupboard.IsDestroyed) continue;
if (Vector3.Distance(cupboard.transform.position, position) > pair.Value) continue;
return cupboard;
}
}
return null;
}
private List<BuildingPrivlidge> FindCupboard(string shortname)
{
var result = new List<BuildingPrivlidge>();
foreach (var networkable in BaseNetworkable.serverEntities)
{
var cupboard = networkable as BuildingPrivlidge;
if (cupboard == null || cupboard.IsDestroyed) continue;
if (cupboard.ShortPrefabName != shortname) continue;
result.Add(cupboard);
}
return result;
}
}
}The plugin keeps a list of cupboard names in its config. When the game looks up building privilege for a player, it compares the player's position to the configured cupboards and, if the player is within range, returns that cupboard so the game treats the player as authorized there.
OnBuildingPrivilege returns null for anything that is not a BasePlayer, so deployables, projectiles and NPCs behave normally. Because the player is genuinely authorized, the existing building and raid rules stay intact; only the cupboard match is widened. The example only runs when ignorePosition is false, since an ignore-position lookup is an administrative query rather than a real position test.
Common use cases
Granted build rights in a shop or event area
Return a designated cupboard for players inside a radius so they can build without being added to the authorize list.
Custom raid protection
Return null or a specific cupboard depending on your own rules so damage checks against the right privilege zone.
Per-player privilege overrides
Narrow the entity parameter to BasePlayer and return a cupboard only for players meeting a permission or team check.
Pitfalls
This hook fires constantly
Build, decay and damage code all call GetBuildingPrivilege. Keep the checks inside short and avoid chat messages or logging.
Returning the wrong type is ignored
Only a BuildingPrivlidge return value takes effect. Returning true, a bool or an unrelated entity falls through to the original lookup.
Cached answers may skip your override
If you return null, the game may reuse a cached privilege. Return a cupboard explicitly when you need a specific result every time.
Build a plugin with OnBuildingPrivilege
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 OnBuildingPrivilege
Generate