OnLockRemove
OnLockRemove is called when a player requests removal of the car lock on a ModularCar through the modular car garage. Returning a non-null value cancels the removal.
object OnLockRemove(ModularCar carOccupant, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
carOccupant | ModularCar | The ModularCar whose car lock is being removed. Its CarLock property is the lockable component being acted on, and the garage that fired the request holds this car as its occupant. |
player | BasePlayer | The BasePlayer who sent the remove-lock request from the modular car garage UI. Can be null if the RPC arrives without an attached connection, so check it before use. |
Return value
Return null (or nothing) to let the game remove the lock, run the effect and clear the garage state. Returning any non-null value stops the original path, so the lock stays on the car and no effect plays.
How it works
This hook fires inside ModularCarGarage.RPC_RequestRemoveLock, which the client calls when the player presses the remove-lock control in the garage interface. The garage only reaches the hook when it has an occupant (HasOccupant) and that car's lock exists (CarLock.HasALock), so you will not see calls for empty garages or unlocked cars.
carOccupant is the ModularCar entity; read carOccupant.CarLock for the lock state, and carOccupant.OwnerID or carOccupant.net.ID.Value to identify the vehicle. player is the requesting player, useful for permission checks, ownership checks and messages. Both can be null in edge cases, so guard them.
Narrowing does not help here: the parameter types are already the exact game types, and declaring anything more specific (a subclass) would make Oxide skip the call. Practical uses are gating lock removal behind a permission or a fee, or logging who unlocked which car. The hook does not fire for admin-driven or plugin-driven RemoveLock() calls, only client garage requests.
Note the order of the game's condition: the lock is removed only if the hook returns null. Any non-null value keeps the lock in place.
Example plugin: Restrict car lock removal to the car owner
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Car Lock Owner Only", "RustPluginGenerator", "1.0.0")]
[Description("Only allows the car owner, admins or permitted players to remove a modular car lock")]
public class CarLockOwnerOnly : RustPlugin
{
private const string PermBypass = "carlockowneronly.bypass";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Notify player when denied")]
public bool NotifyOnDeny { get; set; } = true;
[JsonProperty("Allow admins")]
public bool AllowAdmins { get; set; } = 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>
{
["Denied"] = "Only the owner of this car can remove its lock."
}, 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 OnLockRemove(ModularCar carOccupant, BasePlayer player)
{
if (carOccupant == null || player == null) return null;
if (config.AllowAdmins && player.IsAdmin) return null;
if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;
if (carOccupant.OwnerID == player.userID.Get()) return null;
if (config.NotifyOnDeny && player.IsConnected)
player.ChatMessage(Msg("Denied", player.UserIDString));
return true;
}
}
}The plugin blocks lock removal requests from anyone who is not the car's owner or an admin, and otherwise lets the game proceed. OnLockRemove checks carOccupant and player for null, compares player.userID against carOccupant.OwnerID, and allows admins and the carlockowneronly.bypass permission holder through. Denied players get a localized chat message and a non-null return, which keeps the lock in place. Allowed removals return null so the default garage behavior runs unchanged. Messages live in the lang file, so admins can reword them without touching code.
Common use cases
Owner-only unlock
Only let the player who owns the car remove its lock, blocking passengers, clan members without permission or anyone who walked up to the garage.
Paid lock removal
Charge a fee through a referenced economy plugin before allowing the removal; deny the request when the player cannot pay or the plugin is missing.
Audit trail
Record who removed which car lock and when, so staff can trace misuse of shared garage vehicles without touching the removal flow.
Pitfalls
Null player
The RPC can be delivered without a valid connection, so
playermay be null. Always null-check before readinguserIDor callingChatMessage.Any non-null return cancels
Returning
falsestill blocks the removal because the game only proceeds when the hook result is null. Returnnullto allow, any object to deny.Does not cover plugin removals
The hook only fires from the garage RPC. Admin commands, plugins calling
RemoveLock()directly, or lock destruction through damage do not pass through it.
Build a plugin with OnLockRemove
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 OnLockRemove
Generate