OnDoorKnocked
OnDoorKnocked is called when a player knocks on a door, firing after the knock RPC is accepted and the knock sound effect is played. It covers both plain Door knock and DoorKnocker knock paths.
void OnDoorKnocked(Door door, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
door | Door | The Door (or DoorKnocker) component that was knocked. Use it for its position, OwnerID, building privilege lookup, or to inspect buildingID; it is the entity that plays the knock effect. |
player | BasePlayer | The BasePlayer who performed the knock. Can be null-safe checked, and gives you UserIDString, currentTeam and IsBuildingAuthed for permission logic. |
Return value
The return value is ignored at both injection sites. Returning null or any value has no effect on whether the knock proceeds, plays its sound, or reaches the client.
How it works
The hook fires inside Door.RPC_KnockDoor after the server has validated the player and scheduled the knock sound effect, and also inside DoorKnocker.Knock after it broadcasts the client knock RPC. In practice this means it runs whenever a player uses the knock input on an interactive door or a knocker placed on one. Both door and player are passed at the call site, so you can read the entity's OwnerID, its transform.position, check door.GetBuildingPrivilege() or player.IsBuildingAuthed(), and compare player.currentTeam against the door owner. Because the door argument can be either a Door or a DoorKnocker, declaring the parameter as Door only receives the door path; declaring BaseEntity or BaseNetworkable lets your method run for both call sites. You cannot cancel the knock through this hook; the door knock RPC already ran. Use it for logging, welcome notices, raid-callout systems, or telemetry that records which doors are being probed.
Other signatures
Oxide also calls OnDoorKnocked from other places in the game with these parameter types. Declare the overload you need, or several:
void OnDoorKnocked(DoorKnocker doorKnocker, BasePlayer player)
Example plugin: Notify teammates when a raider knocks on their door
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Door Knock Alerts", "RustPluginGenerator", "1.0.0")]
[Description("Sends a chat alert to a door owner and their team when an unauthorized player knocks.")]
public class DoorKnockAlerts : RustPlugin
{
private const string PermUse = "doorknockalerts.use";
private class PluginConfig
{
[JsonProperty("Alert cooldown per player in seconds")]
public float CooldownSeconds = 30f;
[JsonProperty("Only alert when no building privilege")]
public bool RequireNoPrivilege = true;
}
private PluginConfig config;
private readonly Dictionary<string, double> lastAlert = new Dictionary<string, double>();
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>
{
["Alert"] = "{0} knocked on your door at {1}."
}, 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 OnDoorKnocked(Door door, BasePlayer player)
{
if (door == null || player == null || player.IsNpc) return;
var owner = BasePlayer.FindAwakeOrSleeping(door.OwnerID.ToString());
if (owner == null || owner.userID == player.userID) return;
if (config.RequireNoPrivilege)
{
var privilege = door.GetBuildingPrivilege();
if (privilege != null && privilege.IsAuthed(player)) return;
}
string key = player.UserIDString + "|" + door.net.ID.Value;
double now = UnityEngine.Time.realtimeSinceStartup;
double last;
if (lastAlert.TryGetValue(key, out last) && now - last < config.CooldownSeconds) return;
lastAlert[key] = now;
string message = Msg("Alert", owner.UserIDString, player.displayName,
door.transform.position.ToString("F0"));
owner.ChatMessage(message);
if (owner.currentTeam != 0)
{
var team = RelationshipManager.ServerInstance.FindTeam(owner.currentTeam);
if (team != null)
{
foreach (ulong memberId in team.members)
{
if (memberId == owner.userID.Get()) continue;
var member = BasePlayer.FindByID(memberId);
if (member != null && member.IsConnected)
member.ChatMessage(message);
}
}
}
}
private void Unload()
{
lastAlert.Clear();
}
}
}The plugin watches every door knock and, if the knocking player is not authorized on the door's building privilege and is not on the door owner's team, sends a short alert to the owner and every team member. The owner is looked up from door.OwnerID, the privilege is fetched with door.GetBuildingPrivilege(), and the team is resolved through RelationshipManager.ServerInstance.FindTeam(owner.currentTeam). A configurable cooldown per player and door prevents alert spam from repeated knocks. All chat output goes through the language file, and any offline owner is skipped. This gives base owners a real-time signal that someone is probing their doors without needing to add extra hooks.
Common use cases
Raid-callout notifications
Broadcast a warning to the door owner and their team whenever a non-authorized player knocks, so they learn someone is at their base even while looking the other way.
Door probing telemetry
Record the door position, owner ID and knocker ID for anti-grief review or admin auditing, so staff can see which doors a suspect has been testing.
Raid-event scoring
In a staged event, award points or start a timer the first time a contestant knocks on an objective door, using the door ID to track which objectives are in play.
Pitfalls
Hook fires twice for knockers
A DoorKnocker entity runs
DoorKnocker.Knock, while a Door runsDoor.RPC_KnockDoor. If you declare the parameter asDoor, the knocker path is skipped; declaring it asBaseEntityorBaseNetworkableruns for both, so deduplicate if it matters.The knock already happened
The sound effect and client RPC have already been sent before the hook fires, so you cannot cancel or silence the knock from here. Use a permission or CUI prompt earlier in the flow if you need to prevent it.
No building privilege on some doors
Doors on unowned or unclaimed bases return null from
GetBuildingPrivilege(), and every player is then considered unauthorized. Guard against null results before comparing auth state.
Build a plugin with OnDoorKnocked
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 OnDoorKnocked
Generate