CanRaiseSail
CanRaiseSail is called when a player tries to raise a sail on a boat, before the game checks whether they are authorized to control that boat. Returning a non-null value skips the built-in auth check.
object CanRaiseSail(Sail sail, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
sail | Sail | The Sail entity the player is trying to raise. Its parent entity is the boat, so use sail.GetParentEntity() or walk up to the BaseBoat to inspect ownership, auth or team. |
player | BasePlayer | The BasePlayer attempting the action. Can be null when the call does not originate from a player, so null-check before reading any player state. |
Return value
Return null (or any non-bool value) to let the original method continue with the game's own auth and lock checks. Return a bool to bypass the original method: true allows the raise immediately without the built-in auth check and false denies it outright.
How it works
Oxide fires this hook from Sail.CanBeRaised, which the boat code calls while resolving whether a sail may be raised. It runs for the sail entity being acted on and the player requesting the action. The hook runs before the game's own PlayerBoat.IsPlayerAuthedOnChildEntity check, so your decision takes precedence: if you return a non-null value, the game skips its auth and lock check entirely. That means returning a value is a decision about the final result, not a veto you can stack on top of vanilla rules. Read sail for the boat relationship (sail.GetParentEntity()), and player for identity, team or permission. Both can be null depending on how the call was reached; guard them. Since it only fires on an attempted raise, it is cheap to run moderate checks, but avoid chatty logging or heavy entity scans. Use it to gate sails by permission, team membership or boat ownership, or to extend vanilla auth rules on custom boats.
Example plugin: Restrict raising sails to authorized players
using System.Collections.Generic;
using System;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("SailPermissionGate", "RustPluginGenerator", "1.0.0")]
[Description("Restricts who can raise a boat's sail to permissioned players, the owner and optionally their team.")]
public class SailPermissionGate : RustPlugin
{
private const string PermUse = "sailpermissiongate.use";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Allow team members of the owner")]
public bool AllowTeam = true;
[JsonProperty("Allow anyone on unowned boats")]
public bool AllowUnownedBoats = false;
}
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"] = "You are not authorized to raise this sail."
}, 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 CanRaiseSail(Sail sail, BasePlayer player)
{
if (sail == null || player == null) return null;
var boat = sail.GetParentEntity();
if (boat == null || boat.OwnerID == 0) return config.AllowUnownedBoats ? (object)true : null;
// Permission always wins, regardless of ownership.
if (permission.UserHasPermission(player.UserIDString, PermUse)) return true;
if (player.userID.Get() == boat.OwnerID) return true;
if (config.AllowTeam && player.currentTeam != 0)
{
var owner = BasePlayer.FindByID(boat.OwnerID);
if (owner != null && owner.currentTeam == player.currentTeam) return true;
}
player.ChatMessage(Msg("Denied", player.UserIDString));
return false;
}
}
}The plugin adds a permission sailpermissiongate.use and, optionally, a teamwork rule. When CanRaiseSail fires, it checks player and the sail's parent boat for null. If the boat's OwnerID is a real player, we allow the owner, anyone in the owner's team (when enabled in config), and holders of the permission. Otherwise we fall back to returning null so vanilla auth and lock handling still apply. When the player has neither permission nor team membership, the hook returns false, which stops the raise without waiting on the built-in check. Chat messages routed through lang tell the player why the raise was blocked, but only when a raise is actually denied.
Common use cases
Permission-gated sail control
Require a permission to raise sails so server staff or a paid role can control specific boats. Return
truefor holders andfalsefor everyone else.Team-based boat control
Allow the boat owner and their current team members to raise sails. Check
owner.currentTeamagainst the boat'sOwnerIDand returnfalsefor outsiders.Heroic rescues despite locks
For event plugins, permit a designated set of players to raise sails even when a boat is locked. Return
truefor those players so the vanilla check is skipped.
Pitfalls
Returning a value overrides vanilla auth
A returned bool replaces the entire
CanBeRaisedresult, so the game's auth and lock test is never run. Only returntrueafter you have verified the player yourself.Null player and orphaned sails
playercan be null andsail.GetParentEntity()may not be a boat. Guard both before touchingOwnerID,currentTeamor team lookups.Not handling teams correctly
currentTeamis0for players with no team and the boat owner may not be online. Check the boat'sOwnerIDagainstBasePlayer.FindByIDcarefully and treat missing data as not authorized.
Build a plugin with CanRaiseSail
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 CanRaiseSail
Generate