CanAcceptItem
CanAcceptItem is called by ItemContainer.CanAcceptItem while a container works out whether it may take a given item into a given slot. Return ItemContainer.CanAcceptResult.CannotAccept to block the move, or null to let the vanilla rules decide.
object CanAcceptItem(ItemContainer itemContainer, Item item, int targetPos, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
itemContainer | ItemContainer | The ItemContainer that is deciding whether to accept the item. Compare against player.inventory containers or plugin-stored container references to scope your rule. |
item | Item | The Item instance being offered. Use item.info (shortname, category, itemid), item.amount, item.skin and item.condition to build the rule. |
targetPos | int | The slot index the item is being moved into, or -1 when the game is choosing a slot automatically. |
player | BasePlayer | The player responsible for the move, or null when the move is not player-driven (loot spawning, NPC fills, plugin code). |
Return value
Return ItemContainer.CanAcceptResult.CannotAccept (or CanAccept) to replace the method's result and stop the original container logic. Any other value, including null, is ignored and the game's own blocked-item and category checks run as normal.
How it works
The hook fires inside ItemContainer.CanAcceptItem, the method the game calls for every insertion attempt: picking loot up into a player inventory, moving an item between the belt and main inventory, dragging items between loot and inventory, and also when core code fills containers. It runs after the game's own early checks (for example a full stack or a container that cannot take the item at all) and before blocked-item and item-category checks, so a returned result short-circuits the whole decision.
itemContainer is the destination, item is the item being offered, targetPos is the requested slot (often -1), and player is the moving player when the move came from a client action. Because player can be null, gate player-specific rules on a null check and let non-player moves through. The return value must be an ItemContainer.CanAcceptResult enum value for Oxide to honor it; anything else is ignored and the original method continues. Returning CannotAccept silently refuses the move, which appears to the player as the drag simply not completing.
This hook does not filter what can be looted from a container, only what a container accepts. For pickup filters inside inventories there is no dispatch narrowing worth relying on here; always null-check every parameter.
Example plugin: Block valuable items from a restricted loot container
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Container Item Filter", "RustPluginGenerator", "1.0.0")]
[Description("Blocks configured items from being placed into containers marked as restricted")]
public class ContainerItemFilter : RustPlugin
{
private const string PermUse = "containeritemfilter.use";
private const string DataFile = "ContainerItemFilter/marked";
private const string BlockedResult = "false";
private PluginConfig config;
private HashSet<ulong> marked = new HashSet<ulong>();
private HashSet<int> blockedItemIds = new HashSet<int>();
private class PluginConfig
{
[JsonProperty("Blocked shortnames")]
public List<string> BlockedShortnames = new List<string> { "explosive.satchel", "explosive.timed", "rocket.launcher" };
}
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);
marked = Interface.Oxide.DataFileSystem.ReadObject<HashSet<ulong>>(DataFile) ?? new HashSet<ulong>();
blockedItemIds.Clear();
foreach (var shortname in config.BlockedShortnames)
{
var def = ItemManager.FindItemDefinition(shortname);
if (def != null) blockedItemIds.Add(def.itemid);
}
}
private void Unload()
{
Interface.Oxide.DataFileSystem.WriteObject(DataFile, marked);
}
[ConsoleCommand("containerfilter.mark")]
private void CmdMark(ConsoleSystem.Arg arg)
{
var player = arg.Player();
if (player == null) { arg.ReplyWith("Run this in game."); return; }
if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermUse))
{
arg.ReplyWith("No permission.");
return;
}
var entity = GetLookingEntity(player);
if (entity == null) { arg.ReplyWith("Look at a container."); return; }
if (!marked.Add(entity.net.ID.Value))
{
marked.Remove(entity.net.ID.Value);
arg.ReplyWith("Container unmarked.");
}
else arg.ReplyWith("Container marked.");
Interface.Oxide.DataFileSystem.WriteObject(DataFile, marked);
}
private BaseEntity GetLookingEntity(BasePlayer player)
{
RaycastHit hit;
if (!Physics.Raycast(player.eyes.HeadRay(), out hit, 4f)) return null;
return hit.GetEntity();
}
private object CanAcceptItem(ItemContainer itemContainer, Item item, int targetPos, BasePlayer player)
{
if (itemContainer == null || item == null || item.info == null) return null;
var owner = itemContainer.entityOwner;
if (owner == null || !marked.Contains(owner.net.ID.Value)) return null;
if (!blockedItemIds.Contains(item.info.itemid)) return null;
return ItemContainer.CanAcceptResult.CannotAccept;
}
}
}The plugin hooks CanAcceptItem and checks whether the destination container has been marked as restricted by a server administrator via the containerfilter.mark console command. Marked containers store their net.ID.Value in a data file, and inside the hook the plugin compares itemContainer.entityOwner against that set. When the item's category or shortname is in the configured blocked list, the hook returns ItemContainer.CanAcceptResult.CannotAccept, which makes the move fail. The config holds the blocked shortnames, the unmark command reverses it, and the data file persists markings across restarts.
Common use cases
Blacklist explosives from loot containers
Refuse rocket and C4 items from being placed into player-owned containers that are accessible to raiders, keeping sensitive gear out of easy reach.
Reserve slots for specific item categories
Combine
targetPoswith slot knowledge to keep, for example, the last slots of a locker free for medical items only.Sorting crates for custom events
When players drop items into an event crate, only accept items whose shortname appears in a whitelist so the crate contents stay predictable.
Pitfalls
player can be null
Loot spawning, NPC fills and plugin-driven insertions call this hook without a player. Always check
player == nullbefore reading player state, otherwise the hook throws and the insertion is aborted.Wrong return type silently does nothing
Returning a bool or string has no effect; only an
ItemContainer.CanAcceptResultvalue is honoured. If you see no change in behaviour, check that the returned value has the correct enum type.Overlapping with blockedItems
The game runs its own blocked-item checks after this hook. Blocking things here will not override container capacity or stack rules the game enforces afterwards.
Build a plugin with CanAcceptItem
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 CanAcceptItem
Generate