OnItemLock
OnItemLock is called when an item is about to be flagged as locked (IsLocked), just before Item.LockUnlock sets the flag. Returning a non-null value cancels the lock.
object OnItemLock(Item item)Parameters
| Parameter | Type | Description |
|---|---|---|
item | Item | The Item instance whose locked flag is about to be set to true. Check `item.info.shortname`, `item.skin`, `item.amount` or `item.parent` to decide whether to allow the lock. |
Return value
Return null (or do nothing and let the method fall through) to allow the lock. Return any non-null object to stop the original code path: SetFlag(Flag.IsLocked, true) and MarkDirty() are skipped, so the item is never flagged as locked and clients are not updated.
How it works
The hook fires inside Item.LockUnlock(bool), which the game calls whenever an item needs to transition into the locked state. A lock attempt only reaches the hook when the item is not already locked, so repeated calls on an already-locked item are skipped before Oxide is involved. The single argument is the Item being locked; nothing has changed yet at this point, HasFlag(Item.Flag.IsLocked) is still false. Use it to veto locks on specific items: restricted skins, items inside a particular container, event rewards, or anything an admin has pinned. Because Oxide dispatches by parameter type, you can declare Item (as in the signature) and you will receive every lock attempt; there is no more specific subtype to narrow to. The hook is paired with OnItemUnlock, which runs on the reverse transition and has the same cancellation semantics. Locking is used by the game for items in certain deployables and containers (for example items held in slots that must not be moved); if you block the lock, the item stays movable, so only reject when you intend that.
Example plugin: Block locking of admin-pinned items
using System.Linq;
using UnityEngine;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Pinned Item Lock Guard", "RustPluginGenerator", "1.0.0")]
[Description("Prevents configured item shortnames from ever entering the locked state.")]
public class PinnedItemLockGuard : RustPlugin
{
private const string PermNotify = "pinneditemlockguard.notify";
private PluginConfig config;
private readonly Dictionary<ulong, float> lastNotice = new Dictionary<ulong, float>();
private class PluginConfig
{
[JsonProperty("Pinned shortnames (lock attempts are cancelled)")]
public List<string> PinnedShortnames = new List<string> { "scrap", "supply.signal" };
[JsonProperty("Notify the item owner when a lock is blocked")]
public bool NotifyOwner = true;
}
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>
{
["LockBlocked"] = "This item is pinned and cannot be locked."
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, userId), args);
}
private void Init()
{
permission.RegisterPermission(PermNotify, this);
}
private object OnItemLock(Item item)
{
if (item == null || item.info == null || config.PinnedShortnames == null) return null;
if (!config.PinnedShortnames.Contains(item.info.shortname)) return null;
if (!config.NotifyOwner) return true;
var player = item.GetOwnerPlayer();
if (player == null || !player.IsConnected) return true;
if (!permission.UserHasPermission(player.UserIDString, PermNotify)) return true;
ulong id = player.userID;
float now = UnityEngine.Time.realtimeSinceStartup;
float last;
if (lastNotice.TryGetValue(id, out last) && now - last < 10f) return true;
lastNotice[id] = now;
player.ChatMessage(Msg("LockBlocked", player.UserIDString));
return true;
}
}
}The plugin keeps a list of item shortnames that must stay freely movable, for example event tokens or tools that players transfer between containers. In OnItemLock it looks up item.info.shortname; if the shortname is in the configured deny list, it returns true to cancel the lock and optionally messages the item owner with a rate-limit so chat is not spammed. Everything else returns null and behaves normally. The deny list comes from the config file (Pinned shortnames) so admins can edit it without recompiling, and the owner lookup uses item.GetOwnerPlayer() with a null check because items in world containers have no player owner.
Common use cases
Keep event currency movable
Cancel locks on custom currency items so they can never get stuck in a slot that blocks transfers, which would otherwise strand player balances.
Protect admin-locked gear
Reject the lock transition on items whose skin matches an admin-issued set, forcing the item to stay in normal, transferable state.
Diagnose stuck inventory items
Temporarily allow all locks but record which shortnames are being locked, then correlate with player reports of items that will not move.
Pitfalls
Returning false still cancels
The engine only checks for null. Returning
falseis non-null and blocks the lock just liketrue, which surprises developers expecting a boolean gate.Only fires on transitions
LockUnlock short-circuits when the flag already matches the requested state, so your hook will not run for items that are already locked. Do not rely on it as a periodic audit.
No unlock counterpart in this hook
OnItemLock never fires when an item is unlocked; pair it with OnItemUnlock if your logic must stay symmetric, otherwise denied locks may leave state out of sync.
Build a plugin with OnItemLock
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 OnItemLock
Generate