OnVendingShopOpen
OnVendingShopOpen is called when a player tries to open a vending machine's shop interface, before OpenShop runs and before OnVendingShopOpened fires. Returning a non-null value blocks the open.
object OnVendingShopOpen(VendingMachine vendingMachine, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
vendingMachine | VendingMachine | The machine being opened. Usually a VendingMachine, but the hook also fires with InvisibleVendingMachine (NPC conversation shops) and NPCVendingMachine (travelling vendor), so declare a broader base type if you want all three. |
player | BasePlayer | The player who triggered the open. Null-check it before using; it is the RPC sender or conversation player. |
Return value
Returning null (or nothing meaningful) lets the shop open normally. Returning any non-null value (for example false) suppresses OpenShop and OnVendingShopOpened for that player, so the UI never appears.
How it works
The hook fires from three places: VendingMachine.RPC_OpenShop (normal player vending machines, after the occupied/access check passes), NPCTalking.OnConversationAction (invisible NPC shops, only when the player is within 5 m and the conversation is force-ended), and TravellingVendor.SV_OpenMenu (the roaming NPC vendor). In every case the game calls the hook inside the condition that gates OpenShop / PlayerOpenLoot, so it runs before the customer panel is shown.
Use player for permission checks, blocking during events, or per-player pricing messages. Use vendingMachine to identify which shop is being opened, inspect its sellOrders, or check ownership. Because the same hook is called with three different machine types, declaring the parameter as BaseEntity (or omitting a narrow type) keeps your method invoked for all of them; declaring VendingMachine makes Oxide skip calls coming from the NPC and travelling vendor paths.
The hook runs on the server main thread in the RPC/conversation path, so keep it fast and never call blocking code. It only covers opening — purchases are gated by CanPurchaseItem / OnBuyVendingItem.
Other signatures
Oxide also calls OnVendingShopOpen from other places in the game with these parameter types. Declare the overload you need, or several:
object OnVendingShopOpen(InvisibleVendingMachine vendingMachine, BasePlayer player)object OnVendingShopOpen(NPCVendingMachine vendingMachine, BasePlayer player)
Example plugin: Block vending shop access unless the player has a permission
using System.Collections.Generic;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Vending Shop Gate", "RustPluginGenerator", "1.0.0")]
[Description("Restricts vending shop access to players with a permission")]
public class VendingShopGate : RustPlugin
{
private const string PermUse = "vendingshopgate.use";
private void Init()
{
permission.RegisterPermission(PermUse, this);
}
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["NoPermission"] = "You are not allowed to use vending machines on this server."
}, this);
}
private string Msg(string key, string userId = null, params object[] args) =>
string.Format(lang.GetMessage(key, this, userId), args);
// BaseEntity keeps this firing for standard, invisible and NPC vending machines
private object OnVendingShopOpen(BaseEntity vendingMachine, BasePlayer player)
{
if (vendingMachine == null || player == null)
return null;
if (player.IsAdmin || permission.UserHasPermission(player.UserIDString, PermUse))
return null;
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return false;
}
}
}The plugin registers a vendingshopgate.use permission and listens on OnVendingShopOpen. When the hook fires, it checks the player and machine are valid, then tests permission.UserHasPermission. Players without the permission are blocked from opening the shop and get a localized chat message, while authorized players open normally. The method takes BaseEntity as the machine type so it also covers invisible NPC shops and the travelling vendor, not just standard machines. Unload simply clears state; there is no config or data to persist.
Common use cases
Permission-based shop access
Restrict premium or event shops to players holding a permission, blocking everyone else before the customer panel loads.
Pause shops during events
Return
falsewhile a server event or raid lock is active so trading is suspended without editing every machine.Per-player custom pricing
Use the hook to notice an open attempt, then adjust
sellOrdersor send a chat hint about a temporary discount before the UI appears.
Pitfalls
Declaring only VendingMachine misses NPC shops
The hook is also called with
InvisibleVendingMachineandNPCVendingMachine. AVendingMachineparameter means Oxide skips those calls, so your restrictions silently do nothing on NPC vendors.Blocking the open does not block purchases
This hook only gates the UI. A player already inside a shop can still buy, so combine it with
CanPurchaseItemif you need to stop transactions.Do not treat a return value as a boolean result
The game only checks for non-null here; any non-null object blocks the open. Returning
truedoes not mean 'allow' — it still blocks.
Build a plugin with OnVendingShopOpen
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 OnVendingShopOpen
Generate