Skip to content
RustPluginGenerator

OnItemUnwrap

OnItemUnwrap is called when a player triggers the unwrap command on an item that carries an ItemModUnwrap component, before the item is consumed and its contents are rolled.

Signature
object OnItemUnwrap(Item item, BasePlayer player, ItemModUnwrap itemModUnwrap)

Parameters

Hook parameters
ParameterTypeDescription
itemItemThe wrapped item being unwrapped (for example a present or a mystery box stack). Its amount is already known to be above zero when the hook runs.
playerBasePlayerThe BasePlayer who issued the unwrap command. May be null in edge cases, so null-check before calling player methods.
itemModUnwrapItemModUnwrapThe ItemModUnwrap component that is handling the command. Use it to read mod data such as reward configuration and ownership phrase settings.

Return value

Returning null lets the game continue: item.UseItem() runs and rewards are rolled. Returning any non-null value (for example true or an empty string) stops the original code path, so the item is not consumed and no rewards are given.

How it works

The hook fires inside ItemModUnwrap.ServerCommand when the command is unwrap, the item amount is above zero, and the hook returns null. This is the point where presents, boxes and similar wrapped items are about to be consumed and their rewards rolled. item is the stack being opened, player is the requester, and itemModUnwrap gives you the mod's reward configuration. Return a non-null value to stop the original unwrap entirely. Because the third parameter is typed ItemModUnwrap, declare it that way if you need to read mod fields; declaring a broader type such as BaseEntity still matches but loses direct access. This hook only covers the unwrap command path, not other item uses. Keep the body cheap: it can fire repeatedly on large stacks. Use it to gate unwrapping by permission, cooldown or condition rather than to duplicate the reward logic the game already runs.

Example plugin: Require a permission to open wrapped items

UnwrapPermissionGate.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Unwrap Permission Gate", "RustPluginGenerator", "1.0.0")]
    [Description("Requires a permission to unwrap items that carry an unwrap mod")]
    public class UnwrapPermissionGate : RustPlugin
    {
        private const string PermUse = "unwrappermissiongate.use";

        private PluginConfig config;
        private readonly Dictionary<ulong, float> lastDenied = new Dictionary<ulong, float>();
        private Timer cleanupTimer;

        private class PluginConfig
        {
            [JsonProperty("Require permission")]
            public bool RequirePermission { get; set; } = true;

            [JsonProperty("Denied message cooldown seconds")]
            public float MessageCooldown { get; set; } = 5f;

            [JsonProperty("Exempt item shortnames")]
            public List<string> ExemptShortnames { get; set; } = new List<string> { "present" };
        }

        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>
            {
                ["NoPermission"] = "You do not have permission to unwrap this item.",
            }, 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);
            cleanupTimer = timer.Every(60f, CleanupDenied);
        }

        private void CleanupDenied()
        {
            float now = Time.realtimeSinceStartup;
            foreach (var kvp in new List<KeyValuePair<ulong, float>>(lastDenied))
            {
                if (now - kvp.Value > 300f) lastDenied.Remove(kvp.Key);
            }
        }

        private object OnItemUnwrap(Item item, BasePlayer player, ItemModUnwrap itemModUnwrap)
        {
            if (player == null || item == null || item.info == null) return null;
            if (!config.RequirePermission) return null;
            if (config.ExemptShortnames != null && config.ExemptShortnames.Contains(item.info.shortname)) return null;
            if (permission.UserHasPermission(player.UserIDString, PermUse)) return null;

            float now = Time.realtimeSinceStartup;
            float last;
            if (!lastDenied.TryGetValue(player.userID, out last) || now - last > config.MessageCooldown)
            {
                lastDenied[player.userID] = now;
                player.ChatMessage(Msg("NoPermission", player.UserIDString));
            }
            return true;
        }

        private void Unload()
        {
            if (cleanupTimer != null) cleanupTimer.Destroy();
            lastDenied.Clear();
        }
    }
}

The plugin registers a single permission and blocks unwrapping for players who lack it. In OnItemUnwrap it null-checks player, then checks permission.UserHasPermission. If the check fails it sends a localized message, avoids hot-path logging, and returns true, which stops the game from consuming the item. A configurable exempt shortname list lets admins whitelist specific wraps. A short cooldown map prevents message spam when a player clicks repeatedly, and is cleaned by a timer that is destroyed in Unload.

Common use cases

  • Permission-gated unwrapping

    Only VIPs or event winners can open certain wrapped items. Returning non-null for unauthorized players keeps the item intact.

  • Event-only opening windows

    Allow unwrapping only during scheduled events by returning non-null outside the window, so players keep their items until the event starts.

  • Anti-abuse throttling

    Reject rapid repeated unwrap attempts to reduce spam or exploit attempts, letting legitimate players through once a cooldown expires.

Pitfalls

  • Returning false blocks too

    Any non-null return stops the unwrap, including false. Return null when you want to allow it.

  • Only the unwrap command is covered

    Other ways an item might be consumed or transformed are not routed through this hook, so do not assume it guards every path.

  • player can be null

    Some command invocations may not carry a player. Null-check before reading permission or sending messages.

Build a plugin with OnItemUnwrap

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Permission-gated unwrapping using the OnItemUnwrap hook, with a config file and a permission
Generate this plugin

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 OnItemUnwrap

Generate