Skip to content
RustPluginGenerator

OnDigitalClockAlarmsSet

OnDigitalClockAlarmsSet is called when a player sends an RPC to change the alarm settings of a DigitalClock, before the server applies those settings. Returning a non-null value cancels the change.

Signature
object OnDigitalClockAlarmsSet(DigitalClock digitalClock, ProtoBuf.DigitalClockMessage digitalClockMessage)

Parameters

Hook parameters
ParameterTypeDescription
digitalClockDigitalClockThe DigitalClock entity whose alarm settings a player is trying to change. Use it to read its position, owner, net ID, or to run effects near it.
digitalClockMessageProtoBuf.DigitalClockMessageThe protobuf alarm message read from the incoming RPC. Its fields describe the requested alarm changes (for example alarm enable state and timer settings) before they are applied.

Return value

Returning null lets the original alarm-setting code run normally. Returning any non-null value makes the game return from RPC_SetAlarms early, so the requested alarm change is not applied to the clock.

How it works

This hook fires inside DigitalClock.RPC_SetAlarms (the RPC_SetAlarms handler on the DigitalClock entity), after the server confirms the sender passes CanPlayerAdmin and has read the DigitalClockMessage from the RPC. It fires before the game's own try block applies the requested alarm configuration, so it is your chance to inspect or veto the change. The first parameter is the clock entity itself; the second is the protobuf message describing the requested alarm state. Because the call happens right after deserialization, the message reflects exactly what the client asked for, not yet what the server will store. You can narrow the hook by declaring digitalClock as a more specific type only if you know every call will pass that type; for DigitalClock and the protobuf message the given types are already exact, so a narrower type would cause Oxide to skip calls at runtime. The hook fires only on actual alarm-setting RPCs, not on every interaction with the clock. This makes it a good place for permission gates, alarm limits, or audit logic, and a bad place for cheap logging inside high-traffic servers because RPCs arrive frequently.

Example plugin: Restrict who may set digital clock alarms

DigitalClockAlarmGuard.cs
using System.Collections.Generic;
using System;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("Digital Clock Alarm Guard", "RustPluginGenerator", "1.0.0")]
    [Description("Restricts who can change digital clock alarm settings using a permission.")]
    public class DigitalClockAlarmGuard : RustPlugin
    {
        private const string PermUse = "digitalclockalarmguard.set";

        private PluginConfig config;

        public class PluginConfig
        {
            [JsonProperty("Allow admin bypass")]
            public bool AllowAdminBypass { get; set; } = true;
        }

        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>
            {
                ["NoPermission"] = "You do not have permission to change digital clock alarm settings."
            }, 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 OnDigitalClockAlarmsSet(DigitalClock digitalClock, ProtoBuf.DigitalClockMessage digitalClockMessage)
        {
            if (digitalClock == null)
                return null;

            ulong ownerId = digitalClock.OwnerID;
            if (ownerId == 0)
                return true;

            BasePlayer player = BasePlayer.FindByID(ownerId);
            if (player == null || !player.IsConnected)
                return true;

            if (config.AllowAdminBypass && player.IsAdmin)
                return null;

            if (permission.UserHasPermission(player.UserIDString, PermUse))
                return null;

            player.ChatMessage(Msg("NoPermission", player.UserIDString));
            return true;
        }
    }
}

The plugin registers one permission, digitalclockalarmguard.set, and checks it in OnDigitalClockAlarmsSet. When a player tries to change a clock's alarm settings, the hook looks up the requesting owner from the entity and checks whether that player holds the permission. Players without it are informed through chat and the hook returns true, which cancels the RPC before the server stores the new alarm. Players with the permission get null, so the game proceeds as usual. The check uses digitalClock.OwnerID, which the game sets on entity placement, and handles the case where the owner is offline or the entity is unowned by refusing the change safely.

Common use cases

  • Permission-gated alarm configuration

    Only players with a specific permission may configure digital clock alarms, useful on RP or PvE servers where alarm spam is a problem.

  • Audit logging of alarm changes

    Record the requesting player and clock position before the RPC is applied, so admins can trace griefing or abuse patterns.

  • Block alarms during events

    Return non-null while a server event is active to prevent players from arming alarms that would interfere with the event.

Pitfalls

  • The hook fires on the server before the change applies

    Cancelling by returning non-null prevents the RPC from completing; returning false still counts as non-null and will cancel, so always return true or null deliberately.

  • OwnerID may be 0 or refer to an offline player

    Unowned or admin-placed clocks may have no valid owner. Handle OwnerID == 0 and missing BasePlayer.FindByID results explicitly rather than assuming a player is present.

  • The protobuf message is read but not yet applied

    You cannot inspect the resulting alarm state from the entity at hook time; read the requested fields from digitalClockMessage instead of digitalClock.

Build a plugin with OnDigitalClockAlarmsSet

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Permission-gated alarm configuration using the OnDigitalClockAlarmsSet 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 OnDigitalClockAlarmsSet

Generate