OnPlayerSleepEnded
OnPlayerSleepEnded is called when a player finishes the wake-up routine and control returns to their character, after the game has refreshed their main, belt and wear inventories.
void OnPlayerSleepEnded(BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who just finished waking up. Their inventory containers have already been refreshed when this hook fires, and the player is controlled again by the client. |
Return value
The return value is ignored. The injection calls the hook and continues with the rest of EndSleeping (EAC logging and ping sync), so returning null or any value changes nothing.
How it works
This hook fires from BasePlayer.EndSleeping, the method the server runs when a sleeping player becomes active again. That happens when the player receives a respawn/wake signal from the client, for example after selecting a sleeping bag or bed or reconnecting into their existing body. By the time the hook runs, inventory.containerMain, containerBelt and containerWear have already been marked dirty, so the client-side inventory is in sync with the server.
The single parameter is the freshly awake BasePlayer. Use it to read position, team, health or inventory state and react. Because the hook fires after waking rather than after spawning, it is the right place for logic that should apply every time a player stands up: welcome-back messages, scheduled rewards, region checks, re-applying buffs or vanish states, or kicking a player who woke inside a blocked area. It fires once per wake event, not per frame, so light work here is safe. Do heavier work behind a short timer if it touches many entities.
Declaring the parameter as BasePlayer is the natural choice; a broader type offers no benefit since the argument is always a player.
Example plugin: Welcome-back message with a cooldown-limited reward
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Sleep End Reward", "RustPluginGenerator", "1.0.0")]
[Description("Greets players when they wake up and grants a cooldown-limited reward.")]
public class SleepEndReward : RustPlugin
{
private const string PermReward = "sleependreward.reward";
private PluginConfig config;
private Dictionary<string, long> lastReward;
private class PluginConfig
{
[JsonProperty("Welcome message enabled")]
public bool WelcomeEnabled = true;
[JsonProperty("Reward item shortname")]
public string RewardShortname = "scrap";
[JsonProperty("Reward amount")]
public int RewardAmount = 25;
[JsonProperty("Reward cooldown in seconds")]
public long CooldownSeconds = 43200;
}
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>
{
["Welcome"] = "Welcome back, {0}. You are at {1}.",
["Reward"] = "You received {0} x {1}.",
["RewardCooldown"] = "Your wake-up reward is on cooldown."
}, 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(PermReward, this);
lastReward = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, long>>(Name) ?? new Dictionary<string, long>();
}
private void Unload()
{
Interface.Oxide.DataFileSystem.WriteObject(Name, lastReward);
}
private void OnPlayerSleepEnded(BasePlayer player)
{
if (player == null || !player.IsConnected) return;
string userId = player.UserIDString;
Vector3 pos = player.transform.position;
// Give the client a moment to finish the wake transition before chatting.
timer.Once(1f, () =>
{
if (player == null || !player.IsConnected) return;
if (config.WelcomeEnabled)
player.ChatMessage(Msg("Welcome", userId, player.displayName, $"({(int)pos.x}, {(int)pos.z})"));
if (!permission.UserHasPermission(userId, PermReward)) return;
long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
long last;
if (lastReward.TryGetValue(userId, out last) && now - last < config.CooldownSeconds)
{
player.ChatMessage(Msg("RewardCooldown", userId));
return;
}
Item item = ItemManager.CreateByName(config.RewardShortname, config.RewardAmount);
if (item == null) return;
player.GiveItem(item);
lastReward[userId] = now;
player.ChatMessage(Msg("Reward", userId, config.RewardAmount, item.info.displayName.english));
});
}
}
}The plugin listens for OnPlayerSleepEnded and, for each waking player, resolves their permission group and sends a localized welcome-back message through the language file. If they hold the reward permission and their per-player cooldown stored in oxide/data has expired, it grants a configurable item via ItemManager.CreateByName and GiveItem, then records the current unix time. Team members are also greeted count if they are awake. A short timer.Once is used only to let the client finish its initial network update before the chat line is sent, avoiding a message that can be missed during the wake transition. The cooldown map is saved on unload.
Common use cases
Reward players for returning
Grant a small item or currency the first time a player wakes each real-time day, tracked with a timestamp per user ID.
Re-apply status effects
Re-add custom modifiers, vanish state or UI overlays that are wiped when a player sleeps, so they persist across logouts.
Send server info on wake
Print the current wipe countdown, active event or rules reminder once the player is back in control of their character.
Pitfalls
Not a spawn hook
This only fires when an existing body wakes. Fresh spawns and respawns after death run other paths, so pair it with a spawn hook if you need full coverage.
Client may still be loading
Chat and CUI sent immediately can be missed while the client finishes the wake transition. A one-second timer is usually enough.
Sleeping bag wake spam
Waking is frequent on active servers, so keep the handler cheap and never log or print warnings inside it.
Plugin recipes that use OnPlayerSleepEnded
- How to make a Rust kill feed plugin (CUI, last 5 kills)Draws a CUI kill feed on the right side of every player's screen showing the last 5 player kills with killer, weapon and victim, using OnEntityDeath. Entries expire after a configurable number of seconds.
- How to make a Rust rules acceptance screen plugin (CUI + persistent accept)Shows a CUI rules panel with Accept and Decline buttons to players who have not accepted yet, kicks on decline, and stores accepted Steam IDs in oxide/data so the panel never reappears.
- How to make a Rust sleeper protection plugin (timed spawn protection)Gives sleeping players a configurable grace period after disconnect during which other players cannot damage them, and optionally blocks looting their body. It uses OnPlayerDisconnected to start the timer, OnEntityTakeDamage to block hits, and CanLootPlayer to deny looting.
- How to make a Rust welcome messages plugin (first-join aware)Sends a configurable multi-line private welcome message when a player fully wakes up, with a separate message for players who have never joined the server before. Uses OnPlayerConnected to mark new players and OnPlayerSleepEnded to deliver the text.
- How to make a Rust welcome panel plugin (CUI on spawn)Shows a configurable CUI welcome panel with a title, message lines and server links when a player wakes up, closing on a button click or after a timeout. Uses OnPlayerSleepEnded and OnPlayerDisconnected.
Build a plugin with OnPlayerSleepEnded
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 OnPlayerSleepEnded
Generate