OnDeepSeaClose
OnDeepSeaClose is called at the start of DeepSeaManager.CloseDeepSeaAsync, before the manager clears its Open and Reserved1 flags and runs the rest of the close sequence.
void OnDeepSeaClose(DeepSeaManager deepSeaManager)Parameters
| Parameter | Type | Description |
|---|---|---|
deepSeaManager | DeepSeaManager | The DeepSeaManager entity running the close sequence. Use it for its position, net.ID and owner, and to read entity flags before they are cleared. |
Return value
The return value is ignored. The surrounding method returns bool for its coroutine state, not for your hook result, so returning a value has no effect on the close sequence.
How it works
The hook fires once inside the first step of the close coroutine, immediately after the Closing... log line and before the manager enters a flags-update scope that clears Flags.Open and Flags.Reserved1 and sends a network update. It is the close-side counterpart to the open hook, so it is the earliest point where you can observe an underwater/sunken site being shut down. deepSeaManager is the live entity: you can read transform.position, net.ID.Value, OwnerID and its current flags, and you can schedule follow-up work with a timer. Because the call happens before the flags change, HasFlag(BaseEntity.Flags.Open) still reports true at this moment, which is useful if you filter on state. The hook passes a single typed parameter, so declaring BaseEntity or another base type would only match if the argument is assignable to it; keep DeepSeaManager to avoid missing calls. Nothing here is per-player, so cleanup work should be broadcast or stored rather than tied to a connection.
Example plugin: Report and schedule cleanup when a deep sea closes
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Deep Sea Close Reporter", "RustPluginGenerator", "1.0.0")]
[Description("Reports deep sea close events to permitted players and schedules a follow-up check")]
public class DeepSeaCloseReporter : RustPlugin
{
private const string PermNotify = "deepseacloseReporter.notify";
private PluginConfig config;
private Timer followUpTimer;
private class PluginConfig
{
[JsonProperty("Notify online permitted players")]
public bool NotifyPlayers { get; set; } = true;
[JsonProperty("Follow-up delay in seconds")]
public float FollowUpDelay { get; set; } = 1f;
}
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>
{
["Closed"] = "Deep sea {0} started closing at {1} (open state: {2})",
["Verified"] = "Deep sea {0} close sequence finished."
}, 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(PermNotify, this);
}
private void OnDeepSeaClose(DeepSeaManager deepSeaManager)
{
if (deepSeaManager == null || deepSeaManager.IsDestroyed) return;
ulong netId = deepSeaManager.net != null ? deepSeaManager.net.ID.Value : 0UL;
Vector3 position = deepSeaManager.transform.position;
bool wasOpen = deepSeaManager.HasFlag(BaseEntity.Flags.Open);
if (config.NotifyPlayers)
{
string text = Msg("Closed", null, netId,
string.Format("({0:0},{1:0})", position.x, position.z),
wasOpen ? "yes" : "no");
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
if (player == null || !player.IsConnected) continue;
if (!permission.UserHasPermission(player.UserIDString, PermNotify)) continue;
player.ChatMessage(text);
}
}
if (followUpTimer != null) followUpTimer.Destroy();
followUpTimer = timer.Once(config.FollowUpDelay, () =>
{
followUpTimer = null;
BaseNetworkable entity = BaseNetworkable.serverEntities.Find(new NetworkableId(netId));
if (entity == null)
{
Puts(string.Format(Msg("Verified"), netId));
}
});
}
private void Unload()
{
if (followUpTimer != null)
{
followUpTimer.Destroy();
followUpTimer = null;
}
}
}
}The plugin announces every deep sea close to players who hold the deepseacloseReporter.notify permission and schedules a one-second follow-up check on the manager entity. OnDeepSeaClose records the entity net ID and position and sends a localized chat message through the permission filter. Because the hook fires before the entity flags change, the example captures HasFlag(BaseEntity.Flags.Open) and includes it in the message, which shows whether the site was still open when the close began. The timer re-checks that the net ID is still resolvable and prints a single confirmation message, so late cleanup jobs have a safe window to run. All text comes from the language file so server owners can translate it.
Common use cases
Notify staff of deep sea shutdowns
Send an admin-only chat or console note when a deep sea site closes so operators can verify the cycle ended as expected.
Run delayed cleanup after the close
Start a short timer that inspects nearby entities or removes your own temporary markers once the manager finishes clearing its flags.
Track session statistics
Increment a counter with the manager's net ID and position so you can report how long each deep sea instance stayed open.
Pitfalls
Flags still report open
The hook runs before
Flags.OpenandFlags.Reserved1are cleared, so checkingHasFlag(Flags.Open)here gives the pre-close state, not the post-close one.Do not assume a player context
The hook only provides the manager entity. Any player-facing output must be sent to a chosen audience (permission group, team, or all players), never to an initiator.
Destroying the manager is risky
The close coroutine continues using
deepSeaManagerafter the hook returns, so callingKill()or mutating flags inside the hook can break the rest of the sequence.
Build a plugin with OnDeepSeaClose
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 OnDeepSeaClose
Generate