OnAdventGiftAwarded
OnAdventGiftAwarded is called after an AdventCalendar has given its reward item to a player, at the end of AdventCalendar.AwardGift.
void OnAdventGiftAwarded(AdventCalendar adventCalendar, BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
adventCalendar | AdventCalendar | The AdventCalendar entity that awarded the gift (the in-world advent calendar object the player interacted with). Use net.ID or transform.position to identify which calendar fired the hook. |
player | BasePlayer | The BasePlayer who received the gift. The item has already been created and given to this player's inventory before the hook is called, so you can inspect or adjust their inventory here. |
Return value
The return value is ignored. The original AwardGift method continues and returns normally regardless of what your hook returns, so a return value cannot cancel or alter the gift.
How it works
The hook fires inside AdventCalendar.AwardGift, after the calendar has built the reward item, applied item ownership (the AdventCalendar ownership phrase) and handed it to the player through GiveItem. It runs once per award, so it is the place to react to a specific gift being handed out.
adventCalendar lets you identify the source object; player is the recipient. Because the item is added before the call, you can look at the player's inventory to find the newly granted item, but note the vanilla code only gives the item when itemAmount.itemDef.IsAllowed(EraRestriction.Loot) is true, so a no-gift award can still reach the hook.
Both parameters are always the concrete types AdventCalendar and BasePlayer, so narrowing the types is not useful here. A typical use is to grant extra rewards, run a countdown of awards per player, or send feedback; keep the body light since it runs on every gift.
The hook is ignored at its injection site (the original method returns void), so it does not change whether the gift is given.
Example plugin: Announce advent gifts and track how many each player received
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Advent Gift Announcer", "RustPluginGenerator", "1.0.0")]
[Description("Tracks advent calendar gift awards and announces them to the recipient or the whole server")]
public class AdventGiftAnnouncer : RustPlugin
{
private const string PermBonus = "adventgiftannouncer.bonus";
private PluginConfig config;
private Dictionary<ulong, int> awardCounts = new Dictionary<ulong, int>();
private class PluginConfig
{
[JsonProperty("Announce to all players")]
public bool BroadcastAll { get; set; } = true;
[JsonProperty("Bonus item at milestone")]
public bool GiveBonus { get; set; } = true;
[JsonProperty("Milestone count")]
public int Milestone { get; set; } = 5;
[JsonProperty("Bonus item shortname")]
public string BonusShortname { get; set; } = "scrap";
[JsonProperty("Bonus item amount")]
public int BonusAmount { get; set; } = 50;
}
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>
{
["Received"] = "You opened an advent gift. Total gifts this season: {0}",
["Broadcast"] = "{0} just opened an advent gift ({1} total this season).",
["Bonus"] = "Milestone reached: you received {0} x {1} for opening {2} advent gifts.",
["InvalidBonus"] = "Bonus item shortname is invalid, reward skipped."
}, 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(PermBonus, this);
awardCounts = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, int>>(Name) ??
new Dictionary<ulong, int>();
}
private void Unload()
{
Interface.Oxide.DataFileSystem.WriteObject(Name, awardCounts);
}
private void OnAdventGiftAwarded(AdventCalendar adventCalendar, BasePlayer player)
{
if (player == null || player.net == null) return;
int count;
awardCounts.TryGetValue(player.userID, out count);
count++;
awardCounts[player.userID] = count;
player.ChatMessage(Msg("Received", player.UserIDString, count));
if (config.BroadcastAll)
{
foreach (var target in BasePlayer.activePlayerList)
{
if (target != null && target != player && target.IsConnected)
target.ChatMessage(Msg("Broadcast", target.UserIDString, player.displayName, count));
}
}
if (config.GiveBonus && config.Milestone > 0 && count % config.Milestone == 0 &&
permission.UserHasPermission(player.UserIDString, PermBonus))
{
var bonus = ItemManager.CreateByName(config.BonusShortname, Mathf.Max(1, config.BonusAmount));
if (bonus == null)
{
player.ChatMessage(Msg("InvalidBonus", player.UserIDString));
return;
}
player.GiveItem(bonus);
player.ChatMessage(Msg("Bonus", player.UserIDString, bonus.amount, bonus.info.displayName.english, count));
}
}
}
}The plugin keeps a per-player award count in a data file under oxide/data and writes it on unload. In OnAdventGiftAwarded it increments the counter for the receiving player, sends a chat message through the language file with the new total, and optionally announces the award to the whole server. It finds the just-granted item by scanning the player's main container for the highest-value item, which is enough to name the reward in the message. The whole body is short and does no logging, since the hook fires on every calendar award. Config exposes a toggle for the global broadcast and a permission that controls who gets rewarded with an extra item on milestone counts.
Common use cases
Reward streak tracking
Count how many advent gifts each player has claimed and give a bonus item at a configurable milestone. Persist the count with Oxide's data file system so it survives restarts.
Server-wide announcement
Broadcast a short message naming the player who just opened a calendar gift, to draw attention to the seasonal event. Keep the message in the language file so admins can edit it.
Seasonal event analytics
Log a one-line record of each gift award to a data file with the player's id and the calendar position, then review participation after the event ends.
Pitfalls
The item may not have been given
The vanilla code only calls
GiveItemwhen the item definition passes the era restriction check. The hook still fires afterwards, so do not assume the player's inventory contains the reward.Runs on a game method, not a timer
Avoid heavy inventory scans or entity lookups in this hook. Use NextTick if you need to do more expensive work after the award completes.
Build a plugin with OnAdventGiftAwarded
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 OnAdventGiftAwarded
Generate