How to make a Rust hackable crate timer plugin (shorter VIP hack)
Overrides the hack duration of HackableLockedCrate entities and lets players with a VIP permission unlock them faster, using the OnCrateHack hook and a server-wide announcement when a hack begins.
Hackable locked crates on Oil Rigs, Cargo Ships and CH47 drops use a fixed hack time that rarely fits a custom server's pacing. Changing it means intercepting the crate when a player starts the hack and writing your own duration into hackSeconds. The catch is that you usually want two durations: a normal one for everyone and a faster one for donors. This plugin hooks OnCrateHack, resolves the owning player via BasePlayer.FindByID(crate.OwnerID), and replaces the crate's hackSeconds value with the base time from config or the VIP time when that player holds a permission. It also broadcasts a configurable chat announcement so the rest of the server knows a crate is being cracked. If no player is attached or the player lacks the permission, the base value applies. Everything is config-driven: both durations, whether the announcement fires, and whether it names the player.
The plugin code
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Hackable Crate Timer", "RustPluginGenerator", "1.0.0")]
[Description("Overrides hackable locked crate hack time and gives VIP players a shorter duration.")]
public class HackableCrateTimer : RustPlugin
{
private const string PermVip = "hackablecratetimer.vip";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Normal hack seconds")]
public float NormalHackSeconds = 900f;
[JsonProperty("VIP hack seconds")]
public float VipHackSeconds = 450f;
[JsonProperty("Announce hack in chat")]
public bool AnnounceHack = true;
[JsonProperty("Include player name in announcement")]
public bool AnnouncePlayerName = true;
}
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>
{
["HackStarted"] = "<color=#e07b39>{0}</color> started hacking a locked crate!",
["HackStartedAnonymous"] = "A locked crate is being hacked somewhere on the map!"
}, 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(PermVip, this);
}
private void OnCrateHack(HackableLockedCrate crate)
{
if (crate == null || crate.net == null || crate.IsDestroyed) return;
float seconds = config.NormalHackSeconds;
BasePlayer hacker = BasePlayer.FindByID(crate.OwnerID);
if (hacker != null && !hacker.IsNpc && permission.UserHasPermission(hacker.UserIDString, PermVip))
{
seconds = config.VipHackSeconds;
}
// Overrides the vanilla duration the crate counts down from.
crate.hackSeconds = seconds;
if (!config.AnnounceHack) return;
if (config.AnnouncePlayerName && hacker != null && !hacker.IsNpc)
{
Server.Broadcast(Msg("HackStarted", null, hacker.displayName));
}
else
{
Server.Broadcast(Msg("HackStartedAnonymous"));
}
}
private void Unload()
{
config = null;
}
}
}Hooks used: OnCrateHack
Config file
Created automatically on first load at oxide/config/HackableCrateTimer.json.
{
"Normal hack seconds": 900,
"VIP hack seconds": 450,
"Announce hack in chat": true,
"Include player name in announcement": true
}Commands and permissions
No chat commands. The plugin works on its own.
| Permission | Grants |
|---|---|
hackablecratetimer.vip | Gives the player the shorter VIP hack duration when they start hacking a locked crate. |
How the code works
Register the VIP permission
Initregistershackablecratetimer.vipwithpermission.RegisterPermission(PermVip, this). The prefix matches the lowercase class nameHackableCrateTimer, which is how Oxide expects permission strings to look. Grant it withoxide.grant user <steamid> hackablecratetimer.vipor to a group withoxide.group add vipfollowed byoxide.grant group vip hackablecratetimer.vip. Without the permission a player always gets the normal duration.Read both durations from config
The nested
PluginConfigclass holdsNormalHackSeconds,VipHackSeconds,AnnounceHackandAnnouncePlayerName, each with a[JsonProperty]name so the generatedoxide/config/HackableCrateTimer.jsonis readable.LoadDefaultConfigfills the defaults,LoadConfigreads the file and falls back to defaults if parsing fails, andSaveConfigwrites it back. Admins edit the JSON and reload the plugin; no recompile needed.Intercept the crate before its countdown runs
OnCrateHack(HackableLockedCrate crate)fires when a player starts a hack. The plugin null-checkscrate,crate.netandcrate.IsDestroyedbecause the entity can be gone or dying. It then assignscrate.hackSecondsto the value it wants. AssigninghackSecondshere replaces the total duration the crate counts down from, so the number you write is the number of seconds the hack takes.Find out who started the hack
The plugin resolves the hacker with
BasePlayer.FindByID(crate.OwnerID)into a localBasePlayer hacker. It checks the reference is non-null, thathacker.IsNpcis false, and then callspermission.UserHasPermission(hacker.UserIDString, PermVip). That call is what selectsVipHackSecondsoverNormalHackSeconds. If the lookup returns null or the player is an NPC, the localsecondsvariable stays atNormalHackSeconds.Announce the hack in chat
After setting
crate.hackSeconds, the plugin returns early unlessAnnounceHackis true. It builds the text from theHackStartedlanguage key withhacker.displayNameas the{0}argument passed toMsg, or fromHackStartedAnonymouswhenAnnouncePlayerNameis false or the hacker reference is not a real player.Server.Broadcastsends the resulting line to every connected player. Language strings live inLoadDefaultMessagesand can be edited inoxide/lang/en/HackableCrateTimer.json.Keep the hook cheap
OnCrateHackonly fires when a player starts a hack, not on every tick, so a singleServer.Broadcastand one permission lookup are fine. The plugin still avoidsPrintWarninginside the hook and only logs a configuration problem at load time. The broadcast is gated behindAnnounceHackso servers that want the timer change without the noise can silence it entirely in the config file.
Install it on your server
Save HackableCrateTimer.cs
Keep the file name exactly as the class name. Oxide matches them.Upload it to the plugins folder
Oxide:oxide/plugins/. Carbon:carbon/plugins/. The server compiles and loads it within a few seconds, no restart needed.Edit the config if you want
On first load the default config is written tooxide/config/HackableCrateTimer.json(Carbon:carbon/configs/HackableCrateTimer.json). After editing, reload it:oxide.reload HackableCrateTimer c.reload HackableCrateTimer # CarbonGrant the permission
Give it to every player, or swapdefaultfor a group such asvip:oxide.grant group default hackablecratetimer.vip c.grant group default hackablecratetimer.vip # Carbon
Variations
Each one opens the generator with a ready prompt you can tweak.
Per-location timing
Give Oil Rig crates a different hack time than Cargo Ship or CH47 drops.
Generate this versionTeam-based VIP
Treat a hacking player as VIP when any member of their team has the permission.
Generate this versionBroadcast with map marker
Drop a temporary map marker on the crate position when a hack starts.
Generate this version
FAQ
Does setting `hackSeconds` in `OnCrateHack` actually override the vanilla timer?
OnCrateHack runs when a player starts a hack, and the plugin writes a new value into crate.hackSeconds, which the crate uses as the total duration for its countdown. Test after Rust patches in case the order of events changes.
What happens if a player without the VIP permission starts the hack?
The plugin falls back to NormalHackSeconds from your config. No permission error is shown, because the permission is optional and only affects the duration. Players without it still see the announcement when it is enabled and still get loot.
Can I disable the chat announcement?
Yes. Set Announce hack in chat to false in oxide/config/HackableCrateTimer.json and reload. The timer change still applies. If you want the announcement but not the player's name, keep it enabled and set Include player name in announcement to false.
Where do I install it and do I need Carbon?
Drop HackableCrateTimer.cs into oxide/plugins on an Oxide server, or the Carbon plugins folder on a Carbon server. Carbon loads the same file. Run oxide.reload HackableCrateTimer after editing the config, and grant the permission with oxide.grant user <steamid> hackablecratetimer.vip.
Customize it for your server
Change the reward, add a cooldown, restrict it to VIPs. Start from this prompt and edit anything.
Edit the prompt on the next screen. 2 free plugins a month, no card.
More loot plugins
- Barrel scrap bonusAwards bonus scrap when a player destroys a loot barrel, with a configurable chance and a VIP multiplier permission.OnEntityDeath
- First opener crate lockThis plugin gives the first player who opens a loot container a temporary claim on it, enforced through the CanLootEntity hook, so anyone outside…CanLootEntityOnEntityKill
- Custom loot tablesReplaces the contents of configured LootContainer crates, matched by short prefab name, with weighted items that have per-item chances and min/max…OnLootSpawn
Last updated Oct 26, 2026.
Customize locked crate hack timer
Customize