Skip to content
RustPluginGenerator

OnXmasGiftsDistribute

OnXmasGiftsDistribute is called when the Christmas XMasRefill component is about to hand out gifts to a specific player. Returning a non-null value cancels the distribution for that player.

Signature
object OnXmasGiftsDistribute(XMasRefill xMasRefill, BasePlayer player)

Parameters

Hook parameters
ParameterTypeDescription
xMasRefillXMasRefillThe XMasRefill entity running the gift distribution, a seasonal server component spawned for the Christmas event. Use it to read the entity position, owner or flags, and null-check it before use.
playerBasePlayerThe BasePlayer the gifts are about to be distributed to. This is the player whose eligibility for a gift drop is currently being evaluated.

Return value

Return null (or any other value from a method that returns object is not what you want here) to let distribution proceed normally. Returning any non-null value stops the original method early and makes DistributeGiftsForPlayer return false, so that player receives no gift drop from this refill.

How it works

This hook fires inside XMasRefill.DistributeGiftsForPlayer, which the seasonal gift system calls once per player that passes its earlier distance and eligibility checks. It runs before the gift count and spawn attempts are computed, so nothing has been spawned yet when your code executes.

The two parameters are the XMasRefill component doing the distribution and the BasePlayer receiving the gifts. You can use player for per-player rules (permissions, team, zone checks) and xMasRefill for location-based rules via xMasRefill.transform.position.

Oxide dispatches the hook only when every argument matches the declared parameter types. Declaring BasePlayer as the second parameter is already the narrowest useful type; a subtype of BasePlayer would skip most calls. The hook is not called for players the base game already filtered out, so you only ever see candidates.

Because it runs per eligible player, keep the body cheap: no entity enumeration loops or disk access. A single permission lookup or distance check is fine.

Example plugin: Restrict Christmas gift drops to permitted players

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

namespace Oxide.Plugins
{
    [Info("Xmas Gift Permission", "RustPluginGenerator", "1.0.0")]
    [Description("Restricts Christmas gift distribution from XMasRefill to players with a permission.")]
    public class XmasGiftPermission : RustPlugin
    {
        private const string PermReceive = "xmasgiftpermission.receive";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Require permission for admins")]
            public bool RequireForAdmins { get; set; } = true;

            [JsonProperty("Notify player when gift is blocked")]
            public bool NotifyPlayer { 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>
            {
                ["GiftBlocked"] = "Christmas gift drops are limited to players with the '{0}' permission."
            }, 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(PermReceive, this);
        }

        private object OnXmasGiftsDistribute(XMasRefill xMasRefill, BasePlayer player)
        {
            if (player == null || xMasRefill == null) return null;
            if (!player.IsConnected || player.IsNpc) return null;
            if (player.IsAdmin && !config.RequireForAdmins) return null;
            if (permission.UserHasPermission(player.UserIDString, PermReceive)) return null;

            if (config.NotifyPlayer)
            {
                player.ChatMessage(Msg("GiftBlocked", player.UserIDString, PermReceive));
            }

            // Non-null return cancels distribution for this player.
            return false;
        }
    }
}

The plugin registers a single permission, xmasgiftpermission.receive, and hooks OnXmasGiftsDistribute. When the refill tries to give a player gifts, the hook checks the permission and returns a non-null value if the player lacks it, which cancels the distribution for that player only. New players are told once in chat why they received nothing, with the message kept in the language file so admins can restate it. Config exposes a toggle to also block admins who lack the permission, useful on servers where staff test with vanilla rights. Everything is null-checked so a destroyed refill or disconnected player cannot throw.

Common use cases

  • Permission-gated holiday rewards

    Only players with a donated or event permission get Christmas gifts, letting you run the seasonal event as a perk without disabling the refill entirely.

  • Exclude building-blocked or PvP zones

    Check player.IsBuildingBlocked() or a distance to a monument and skip the drop, so gifts do not spawn inside raid bases or contested areas.

  • Team-limited distribution

    Use player.currentTeam together with RelationshipManager.ServerInstance.FindTeam to deny gifts to teams above a size threshold, keeping the event fair on large-pop servers.

Pitfalls

  • Any non-null value cancels

    The patched method checks only whether your return value is null. Returning false, 0 or an empty string still cancels distribution, so return null explicitly when you want gifts to proceed.

  • Per-player, not per-tick

    The hook runs once per eligible player per distribution pass. Avoid heavy work such as enumerating BaseNetworkable.serverEntities here, because it multiplies across the whole server during the event.

  • Refill may be null in edge cases

    A destroyed or unspawned refill can still reach the call during shutdown. Null-check xMasRefill and player before reading transform or permissions.

Build a plugin with OnXmasGiftsDistribute

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

Prompt: Permission-gated holiday rewards using the OnXmasGiftsDistribute 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 OnXmasGiftsDistribute

Generate