OnElevatorButtonPress
OnElevatorButtonPress is called when a player presses a floor button on an elevator lift, before the lift processes the move request.
object OnElevatorButtonPress(ElevatorLift elevatorLift, BasePlayer player, int floor, bool wantsMoveUp)Parameters
| Parameter | Type | Description |
|---|---|---|
elevatorLift | ElevatorLift | The ElevatorLift entity whose panel button was pressed. Null-check it and use net.ID for identification or coordinate-based checks. |
player | BasePlayer | The BasePlayer who sent the raise/lower RPC. May be null if the message has no attached connection, so guard before reading player data. |
floor | int | The floor index the player requested, read as Int32 from the RPC. Treat it as untrusted client input. |
wantsMoveUp | bool | True when the client requested upward movement, false for downward. The game uses this to decide which lift flag to set. |
Return value
Returning null (or nothing in a void hook) lets the lift proceed with the vanilla Server_RaiseLowerElevator call and flag update. Returning any non-null object skips that code path entirely, so the lift never moves for that press and the reserved flag is not set.
How it works
This hook fires inside ElevatorLift.Server_RaiseLowerFloor, which handles the RPC a client sends when pressing a lift's floor button. The RPC payload supplies the target floor and the wantsMoveUp direction; the server then calls into the lift owner to start the move and sets the corresponding reserved flag for network sync.
Because the call happens before Server_RaiseLowerElevator runs, this is the point to validate or reject a move: check building privilege, cooldowns, distance to the lift, or team membership. elevatorLift is the entity, player the requesting client (guard against null since it comes from msg.player), floor the requested index, and wantsMoveUp the direction.
The patched signature only accepts ElevatorLift and BasePlayer for the first two parameters. You cannot narrow these to another type to filter calls; declare them exactly as given. Returning a non-null value from any handler cancels the vanilla move for that press, so a single plugin blocking the action stops the lift from moving even if other plugins would allow it.
Example plugin: Require building privilege before moving a lift
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Elevator Auth Guard", "RustPluginGenerator", "1.0.0")]
[Description("Requires building privilege and an optional permission before a player can move an elevator lift.")]
public class ElevatorAuthGuard : RustPlugin
{
private const string PermUse = "elevatorauthguard.use";
private const string PermBypass = "elevatorauthguard.bypass";
private PluginConfig config;
private readonly Dictionary<ulong, float> lastPress = new Dictionary<ulong, float>();
private class PluginConfig
{
[JsonProperty("Require building privilege")]
public bool RequirePrivilege = true;
[JsonProperty("Require permission to use lifts")]
public bool RequirePermission = false;
[JsonProperty("Cooldown between presses (seconds)")]
public float Cooldown = 1.5f;
}
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>
{
["NotAuthorized"] = "You are not authorized to use this elevator.",
["NoPermission"] = "You do not have permission to use elevators.",
["Cooldown"] = "Please wait {0:0.0}s before moving the elevator again."
}, 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);
permission.RegisterPermission(PermBypass, this);
}
private object OnElevatorButtonPress(ElevatorLift elevatorLift, BasePlayer player, int floor, bool wantsMoveUp)
{
if (elevatorLift == null || player == null || !player.IsConnected) return null;
if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;
if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermUse))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return true;
}
float now = UnityEngine.Time.realtimeSinceStartup;
float last;
if (config.Cooldown > 0f && lastPress.TryGetValue(player.userID, out last) && now - last < config.Cooldown)
{
player.ChatMessage(Msg("Cooldown", player.UserIDString, config.Cooldown - (now - last)));
return true;
}
if (config.RequirePrivilege)
{
var privilege = elevatorLift.GetBuildingPrivilege();
if (privilege != null && !privilege.IsAuthed(player))
{
player.ChatMessage(Msg("NotAuthorized", player.UserIDString));
return true;
}
}
lastPress[player.userID] = now;
return null;
}
}
}The plugin listens on OnElevatorButtonPress and looks up the building privilege that owns the lift via GetBuildingPrivilege(). If a privilege exists and the player is not authorized on it, the hook returns a non-null value to block the move and sends a localized chat message. A per-player cooldown keyed on user ID prevents message spam when players hammer the buttons. Floors and permissions are configurable, so admins can require a specific permission node (elevatorauthguard.use) in addition to cupboard auth. Players with the bypass permission skip the check entirely.
Common use cases
Block unauthorized lift use
Return non-null when the player is not authorized on the lift's building privilege, stopping strangers from riding base elevators.
Enforce a cooldown
Track the last press time per player and reject rapid repeated presses so the lift cannot be spammed up and down.
Restrict specific floors
Reject requests for certain floor indices (for example a private top floor) unless the player holds a permission node.
Pitfalls
Null player on malformed RPC
msg.playercan be null. Always checkplayerbefore callingUserIDString,ChatMessage, or permission lookups.One plugin blocks for everyone
The return check is a simple non-null test, so any plugin returning a value cancels the move even if others would allow it. Return non-null only when you truly intend to deny the press.
Missing privilege is not a denial
GetBuildingPrivilege()returns null when the lift is not inside a tool cupboard range. Decide explicitly whether that case should allow or block movement.
Build a plugin with OnElevatorButtonPress
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 OnElevatorButtonPress
Generate