Skip to content
RustPluginGenerator

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.

Signature
object CanRaiseSail(Sail sail, BasePlayer player)

Parameters

Hook parameters
ParameterTypeDescription
sailSailThe 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.
playerBasePlayerThe 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

SailPermissionGate.cs
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 true for holders and false for everyone else.

  • Team-based boat control

    Allow the boat owner and their current team members to raise sails. Check owner.currentTeam against the boat's OwnerID and return false for outsiders.

  • Heroic rescues despite locks

    For event plugins, permit a designated set of players to raise sails even when a boat is locked. Return true for those players so the vanilla check is skipped.

Pitfalls

  • Returning a value overrides vanilla auth

    A returned bool replaces the entire CanBeRaised result, so the game's auth and lock test is never run. Only return true after you have verified the player yourself.

  • Null player and orphaned sails

    player can be null and sail.GetParentEntity() may not be a boat. Guard both before touching OwnerID, currentTeam or team lookups.

  • Not handling teams correctly

    currentTeam is 0 for players with no team and the boat owner may not be online. Check the boat's OwnerID against BasePlayer.FindByID carefully 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.

Prompt: Permission-gated sail control using the CanRaiseSail 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 CanRaiseSail

Generate