OnTeamRejectInvite
OnTeamRejectInvite is called when a player rejects a pending invite to a team, before the invite is removed from the team. Returning a non-null value blocks the rejection and leaves the invite pending.
object OnTeamRejectInvite(BasePlayer player, RelationshipManager.PlayerTeam playerTeam)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer who rejected the team invite. Can be null-checked and used to read UserIDString, displayName or team state. |
playerTeam | RelationshipManager.PlayerTeam | The RelationshipManager.PlayerTeam the invite came from, already resolved from the team ID. Use its teamID and members list to decide whether to allow the rejection. |
Return value
The original method returns void, so the hook is checked for a valid return value: returning null (or nothing) lets playerTeam.RejectInvite(player) run and the invite is dropped. Returning any non-null value stops that call, so the pending invite stays on the player and the team.
How it works
The hook fires inside RelationshipManager.rejectinvite, which the game calls when a player declines a team invitation (for example through the accept/decline prompt or the client-side team UI). The method first resolves the team from the stored team ID; if no team exists it just clears the player's pending invite and the hook never runs. When a team is found, Oxide calls OnTeamRejectInvite with the rejecting player and the resolved playerTeam. The playerTeam parameter is a live PlayerTeam object, so teamID, teamLeader and members are readable at this point and the invite is still outstanding. Because both parameters are already strongly typed, declaring the exact signature is enough; declaring BasePlayer is the only usable type for the first argument. Practical uses are server rules that lock a player into a team invite (forced recruitment events), audit logging of declines, or giving feedback when a rejection is blocked. The hook fires once per rejection attempt, not per team member.
Example plugin: Force players to accept a pending invite during a draft event
using System.Linq;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Forced Team Invite", "RustPluginGenerator", "1.0.0")]
[Description("Blocks team invite rejections for a configured list of players and persists the locks.")]
public class ForcedTeamInvite : RustPlugin
{
private const string PermManage = "forcedteaminvite.manage";
private PluginConfig config;
private StoredData data;
private readonly HashSet<string> locked = new HashSet<string>();
private class PluginConfig
{
[JsonProperty("Data file name")]
public string DataFile = "ForcedTeamInvite";
}
private class StoredData
{
[JsonProperty("Locked Steam IDs")]
public List<string> LockedIds = new List<string>();
}
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>
{
["InviteLocked"] = "You cannot decline this invite: your team placement is locked by staff.",
["Toggled"] = "Invite lock for {0} is now {1}.",
["Usage"] = "Usage: /forcedinvite <steamid>",
["NoPermission"] = "You do not have permission to use this command."
}, 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(PermManage, this);
LoadData();
}
private void LoadData()
{
data = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(config.DataFile);
if (data == null) data = new StoredData();
locked.Clear();
foreach (var id in data.LockedIds) locked.Add(id);
}
private void SaveData()
{
data.LockedIds = new List<string>(locked);
Interface.Oxide.DataFileSystem.WriteObject(config.DataFile, data);
}
private object OnTeamRejectInvite(BasePlayer player, RelationshipManager.PlayerTeam playerTeam)
{
if (player == null || playerTeam == null) return null;
if (!locked.Contains(player.UserIDString)) return null;
player.ChatMessage(Msg("InviteLocked", player.UserIDString));
return true;
}
[ChatCommand("forcedinvite")]
private void CmdForcedInvite(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, PermManage))
{
player.ChatMessage(Msg("NoPermission", player.UserIDString));
return;
}
if (args == null || args.Length < 1)
{
player.ChatMessage(Msg("Usage", player.UserIDString));
return;
}
Toggle(args[0], player.UserIDString);
}
[ConsoleCommand("forcedinvite.toggle")]
private void CcmdToggle(ConsoleSystem.Arg arg)
{
if (arg == null || arg.Player() != null) return;
string id = arg.GetString(0, "");
if (string.IsNullOrEmpty(id)) return;
Toggle(id, null);
}
private void Toggle(string id, string userId)
{
bool nowLocked;
if (locked.Contains(id))
{
locked.Remove(id);
nowLocked = false;
}
else
{
locked.Add(id);
nowLocked = true;
}
SaveData();
string state = nowLocked ? "locked" : "unlocked";
if (userId != null) SendReply(BasePlayer.FindByID(ulong.Parse(userId)), Msg("Toggled", userId, id, state));
else Puts(string.Format("Invite lock for {0} is now {1}.", id, state));
}
private void Unload()
{
SaveData();
foreach (var player in BasePlayer.activePlayerList)
{
if (player != null) CuiHelper.DestroyUi(player, "ForcedTeamInvitePanel");
}
}
}
}The plugin keeps a configurable list of Steam IDs whose pending team invites cannot be declined. When OnTeamRejectInvite fires, it checks the player against that list and, if locked, returns a non-null object to stop RejectInvite from running. The player gets a chat message telling them the invite must be accepted. Admins toggle a player's lock with the forcedinvite.toggle <steamid> console command or forcedinvite chat command; state is persisted to oxide/data so it survives restarts. Returning null for everyone else keeps normal decline behavior untouched, and no logging happens in the hook itself, just a saved flag check.
Common use cases
Event drafts
Lock chosen players to an invite so a draft or tournament cannot be dodged by declining. Return non-null for locked players and null otherwise.
Invite audit trail
Record which players declined invites from which team into a data file for staff review. Return null afterwards so the rejection proceeds normally.
Anti-harassment cooldown
Block a rejection when the same team has spammed invites, forcing the player to stay pending until staff clears it.
Pitfalls
Only fires when the team exists
If the team ID no longer resolves to a team, the game just clears the pending invite and the hook is skipped, so you cannot intercept that case.
Blocking leaves state stuck
Returning non-null keeps the invite pending. If your plugin later fails to release the lock, the player cannot join another team normally until the invite is cleared.
Not the accept path
This hook only covers declines. Accepting an invite goes through
OnTeamAcceptInvite, so rules that must cover both directions need both hooks.
Build a plugin with OnTeamRejectInvite
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 OnTeamRejectInvite
Generate