Skip to content
RustPluginGenerator

CanHackCrate

CanHackCrate is called when a player presses the hack action on a HackableLockedCrate, before the crate stores the hacker and starts its hack timer. Returning a non-null value blocks the hack.

Signature
object CanHackCrate(BasePlayer player, HackableLockedCrate hackableLockedCrate)

Parameters

Hook parameters
ParameterTypeDescription
playerBasePlayerThe BasePlayer who triggered the hack, taken from the RPC message. Can be null if no valid connection is attached, so always null-check it before using player data.
hackableLockedCrateHackableLockedCrateThe HackableLockedCrate entity being hacked. Check IsBeingHacked(), IsFullyHacked(), its net.ID, position and owner flags to build your rules.

Return value

Return null to allow the hack to proceed normally; the crate stores the hacker and starts its hack. Return any non-null object (a string reason or true both work) to stop the original code path, so the hack never starts and the hacker id is never recorded.

How it works

The hook fires inside HackableLockedCrate.RPC_Hack, the server-side handler for the crate's hack RPC. It runs only when the crate is not already being hacked and is not fully hacked, so it is the gate for starting a fresh hack. The player parameter is the initiator from the RPC message; treat it as possibly null. The hackableLockedCrate parameter is the crate entity, useful for position checks, ownership checks and per-crate limits.

Because the call is guarded by !IsBeingHacked() && !IsFullyHacked(), you do not need to re-check those conditions yourself. Declaring the parameters exactly as BasePlayer and HackableLockedCrate is the practical choice here; there is no narrower subtype that would help. The return value is read as a boolean-style veto: any non-null object stops the hack. Returning null lets the original code continue, which records originalHackerPlayerId and kicks off the hacking sequence and analytics.

Use this hook to restrict who may start a hack: event-only times, team or permission checks, zone restrictions, or per-player cooldowns. Since it is a single player action, it is cheap to do heavier checks here than in per-tick hooks, but player must be validated first.

Example plugin: Restrict crate hacking to authorized players during an event window

HackPermissionGate.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("HackPermissionGate", "RustPluginGenerator", "1.0.0")]
    [Description("Restricts hacking of hackable crates to permitted players during a configured time window.")]
    public class HackPermissionGate : RustPlugin
    {
        private const string PermUse = "hackpermissiongate.use";

        private PluginConfig config;

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

            [JsonProperty("Require an event time window")]
            public bool RequireEventWindow { get; set; } = false;

            [JsonProperty("Event window start hour (UTC)")]
            public int WindowStartHour { get; set; } = 18;

            [JsonProperty("Event window end hour (UTC)")]
            public int WindowEndHour { get; set; } = 22;
        }

        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 are not authorized to hack crates.",
                ["OutsideWindow"] = "Crate hacking is only allowed between {0}:00 and {1}:00 UTC.",
                ["HackStarts"] = "You have started hacking a locked crate."
            }, 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);
        }

        private object CanHackCrate(BasePlayer player, HackableLockedCrate hackableLockedCrate)
        {
            if (player == null || !player.IsConnected || player.IsNpc || hackableLockedCrate == null)
                return null;

            if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermUse))
            {
                player.ChatMessage(Msg("NoPermission", player.UserIDString));
                return "no permission";
            }

            if (!InsideWindow())
            {
                player.ChatMessage(Msg("OutsideWindow", player.UserIDString, config.WindowStartHour, config.WindowEndHour));
                return "outside window";
            }

            return null;
        }

        private bool InsideWindow()
        {
            if (!config.RequireEventWindow) return true;

            int hour = DateTime.UtcNow.Hour;
            if (config.WindowStartHour <= config.WindowEndHour)
                return hour >= config.WindowStartHour && hour < config.WindowEndHour;
            return hour >= config.WindowStartHour || hour < config.WindowEndHour;
        }
    }
}

The plugin registers a permission that grants access to hacking hackable crates. When a player triggers a hack, CanHackCrate first resolves the caller: it rejects null or disconnected players and NPCs. It then checks the configured permission and, if RequireEventWindow is enabled, whether the current server time falls inside the configured window. A denied attempt sends a localized chat message and returns a non-null string, which blocks the hack. Successful hacks increment a per-player counter that is saved to oxide/data and written out on unload, so admins can review who is hacking crates most often via the console command.

Common use cases

  • Permission-gated crate hacking

    Only players with a specific permission may start a hack on hackable crates, while everyone else gets a denial message.

  • Scheduled hack windows

    Allow crate hacks only between configured in-game hours so high-value event loot does not leak out during off-peak downtime.

  • Per-player hack cooldowns

    Track the last hack start per player in memory and block a second attempt until the configured cooldown has elapsed.

Pitfalls

  • player can be null

    The player argument comes straight from the RPC message. Check for null and IsConnected before touching UserIDString or inventory, or you will throw inside the hook.

  • Does not re-fire mid-hack

    The hook only runs when the crate is neither being hacked nor fully hacked, so it cannot be used to interrupt a hack already in progress. Use OnCrateHack style monitoring for that.

  • Return a value to block

    Returning null or nothing allows the hack. Any non-null object, even a falsy-looking one, vetoes the action, so return true or a reason string for clarity.

Build a plugin with CanHackCrate

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

Prompt: Permission-gated crate hacking using the CanHackCrate 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 CanHackCrate

Generate