CanVendingAcceptItem
CanVendingAcceptItem is called when a VendingMachine checks whether it can receive an item, letting a plugin override the accept/reject result before the machine's own rules run.
object CanVendingAcceptItem(VendingMachine vendingMachine, Item item, int targetSlot, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
vendingMachine | VendingMachine | The VendingMachine entity receiving the item. Use it to read the shop's stock, position, owner and flags. |
item | Item | The Item being placed into the machine, typically dragged in from a player's inventory. Null-check it and its info before reading shortname or amount. |
targetSlot | int | The inventory slot index the item is being moved into. Compare against the sell/attach slot counts when you only want to police specific slots. |
player | BasePlayer | The BasePlayer performing the move. This is the inventory owner, not necessarily the machine owner, so use it to gate by permission or team. |
Return value
Returning a bool replaces the machine's own accept decision: true lets the item in, false rejects it. Any other return value (including null) is ignored, so the original CanAcceptItem logic runs unchanged.
How it works
The hook fires inside VendingMachine.CanAcceptItem(BasePlayer player, Item item, int targetSlot), which the game calls when an item move targets the machine's inventory: dragging a stack into a shop slot, moving items back into the sell/attach containers, or any other transfer that goes through the machine's container. If your hook returns a bool, that value becomes the result of CanAcceptItem, so true forces the transfer through and false blocks it even when the machine would normally allow it. Returning null leaves the vanilla checks in place (stackable capacity, slot restrictions, ownership rules).
Because the injection hands the plugin the item and target slot, you can inspect item.info.shortname, item.amount, item.skin and the slot index to enforce per-item limits. vendingMachine gives access to sellOrders, ShopName, position and owner, while player identifies who is moving the item. Watch for item or player being null on edge cases (server-side moves, NPC-driven logic) and always null-check before reading members.
Example plugin: Restrict which items players can stock in vending machines
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("VendingItemWhitelist", "RustPluginGenerator", "1.0.0")]
[Description("Restricts which items can be placed into vending machines and warns the player on rejection.")]
public class VendingItemWhitelist : RustPlugin
{
private const string PermBypass = "vendingitemwhitelist.bypass";
private PluginConfig config;
private readonly Dictionary<ulong, float> lastWarn = new Dictionary<ulong, float>();
private class PluginConfig
{
[JsonProperty("Allowed shortnames")]
public List<string> Allowed = new List<string> { "scrap", "wood", "stone", "metal.fragments", "lowgradefuel", "cloth" };
[JsonProperty("Max amount per move")]
public int MaxAmount = 1000;
[JsonProperty("Warn cooldown seconds")]
public float WarnCooldown = 3f;
}
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>
{
["NotAllowed"] = "This vending machine does not accept {0}.",
["TooMany"] = "You can only move {0} of {1} at a time."
}, 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(PermBypass, this);
}
private object CanVendingAcceptItem(VendingMachine vendingMachine, Item item, int targetSlot, BasePlayer player)
{
if (vendingMachine == null || item == null || item.info == null) return null;
if (player == null || player.IsNpc) return null;
if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;
string shortname = item.info.shortname;
if (!config.Allowed.Contains(shortname))
{
Warn(player, Msg("NotAllowed", player.UserIDString, item.info.displayName.english));
return false;
}
if (item.amount > config.MaxAmount)
{
Warn(player, Msg("TooMany", player.UserIDString, config.MaxAmount, item.info.displayName.english));
return false;
}
return null;
}
private void Warn(BasePlayer player, string message)
{
float now = UnityEngine.Time.realtimeSinceStartup;
float last;
if (lastWarn.TryGetValue(player.userID, out last) && now - last < config.WarnCooldown) return;
lastWarn[player.userID] = now;
player.ChatMessage(message);
}
private void Unload()
{
lastWarn.Clear();
}
}
}The plugin keeps a configurable list of allowed shortnames and a per-slot cap. Every time a vending machine checks whether it can accept an item, CanVendingAcceptItem looks up the shortname against the list and rejects anything not present, so players cannot fill their shops with weapons, explosives or other banned goods. Permitted users skip the check via the vendingitemwhitelist.bypass permission, which is handy for admins. The rejection triggers a short chat message to the player, throttled per user so dragging stacks quickly does not spam them. All text goes through the language file, and the config defaults to a sensible list of trade goods. Unload simply unsubscribes nothing extra since no timers or UI are created.
Common use cases
Whitelist trade goods
Reject anything not on a configured shortname list so shops only carry food, resources or scrap and cannot be used to launder weapons.
Per-slot limits
Use targetSlot to cap the amount a player can place in specific sell slots, stopping stack exploits where huge stacks are inserted in one move.
Owner-only stocking
Block item moves when the player is not the machine owner or not authorized, preventing teammates or visitors from altering a shop's contents.
Pitfalls
Null player on server-side moves
The hook can run for transfers not driven by a real player. Check
playeranditemfor null before reading UserIDString or calling ChatMessage, or you will throw inside the move path.Overrides vanilla checks
Returning true skips the machine's own capacity and slot validation, so an unguarded true can let items into invalid slots and corrupt the container state. Only return true when you actually need to bypass.
Chat spam from fast drags
Players moving stacks generate several calls per second. Throttle rejection messages per user or send them once per command rather than every hook call.
Build a plugin with CanVendingAcceptItem
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 CanVendingAcceptItem
Generate