OnTeamKick
OnTeamKick is called when a team leader kicks a member through the in-game team UI, before the player is removed from the team. Returning a non-null value cancels the removal.
object OnTeamKick(RelationshipManager.PlayerTeam playerTeam, BasePlayer player, ulong targetSteamId)Parameters
| Parameter | Type | Description |
|---|---|---|
playerTeam | RelationshipManager.PlayerTeam | The RelationshipManager.PlayerTeam the caller belongs to, resolved from their currentTeam before the kick runs. Never null when the hook fires. |
player | BasePlayer | The BasePlayer issuing the kick command (the team leader in practice, since the game only reaches this code for leaders). |
targetSteamId | ulong | The ulong Steam ID of the team member being kicked, read from the command arguments. |
Return value
Returning null (or nothing, for a void handler) lets the game continue and call playerTeam.RemovePlayer(targetSteamId). Returning any non-null object, including false, skips the removal and the kicked player stays on the team.
How it works
The hook fires inside RelationshipManager.kickmember, which Rust exposes as the player-facing kick action in the team menu. By the time it runs, the game has already resolved the caller's team and checked that the caller is the leader and is not kicking themselves, so both playerTeam and player are valid objects. targetSteamId comes straight from the command argument and is not validated against team membership at this point: the game removes the player with RemovePlayer regardless of whether that ID is actually on the team, so validate it yourself when it matters. Declaring player as BasePlayer is already the most specific useful type; you cannot narrow this hook meaningfully by type because the team and the ID are always the same shapes. A non-null return from any OnTeamKick handler stops the removal entirely, which makes the hook suitable for cooldowns, permission gates, or protecting specific members. No team update is broadcast when you block the call, so clients may briefly show stale state until the next team packet.
Example plugin: Protect team members from being kicked within a grace period
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Team Kick Shield", "RustPluginGenerator", "1.0.0")]
[Description("Blocks team kicks of members who joined very recently and enforces a leader kick cooldown.")]
public class TeamKickShield : RustPlugin
{
private const string PermBypass = "teamkickshield.bypass";
private PluginConfig config;
private readonly Dictionary<ulong, double> joinedAt = new Dictionary<ulong, double>();
private readonly Dictionary<ulong, double> lastKick = new Dictionary<ulong, double>();
private class PluginConfig
{
[JsonProperty("Protection seconds after joining")]
public float ProtectionSeconds = 120f;
[JsonProperty("Seconds between kicks per leader")]
public float KickCooldownSeconds = 5f;
}
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>
{
["Protected"] = "{0} joined {1} seconds ago and cannot be kicked yet.",
["Cooldown"] = "You can kick another member in {0} seconds.",
["Kicked"] = "{0} was removed from your team."
}, 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(PermBypass, this);
}
private void OnTeamAcceptInvite(RelationshipManager.PlayerTeam team, BasePlayer player)
{
if (player != null) joinedAt[player.userID.Get()] = UnityEngine.Time.realtimeSinceStartup;
}
private void OnTeamCreated(BasePlayer player)
{
if (player != null) joinedAt[player.userID.Get()] = UnityEngine.Time.realtimeSinceStartup;
}
private void OnTeamLeave(RelationshipManager.PlayerTeam team, BasePlayer player)
{
if (player != null) joinedAt.Remove(player.userID.Get());
}
private void OnTeamDisbanded(RelationshipManager.PlayerTeam team)
{
if (team?.members == null) return;
foreach (ulong id in team.members) joinedAt.Remove(id);
}
private object OnTeamKick(RelationshipManager.PlayerTeam playerTeam, BasePlayer player, ulong targetSteamId)
{
if (playerTeam == null || player == null || player.IsNpc) return null;
if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;
double now = UnityEngine.Time.realtimeSinceStartup;
double last;
if (config.KickCooldownSeconds > 0f && lastKick.TryGetValue(player.userID.Get(), out last)
&& now - last < config.KickCooldownSeconds)
{
player.ChatMessage(Msg("Cooldown", player.UserIDString, Mathf.CeilToInt((float)(config.KickCooldownSeconds - (now - last)))));
return false;
}
double joined;
if (config.ProtectionSeconds > 0f && joinedAt.TryGetValue(targetSteamId, out joined))
{
double age = now - joined;
if (age < config.ProtectionSeconds)
{
string name = FindName(targetSteamId);
player.ChatMessage(Msg("Protected", player.UserIDString, name, Mathf.CeilToInt((float)age)));
return false;
}
}
lastKick[player.userID.Get()] = now;
joinedAt.Remove(targetSteamId);
player.ChatMessage(Msg("Kicked", player.UserIDString, FindName(targetSteamId)));
return null;
}
private string FindName(ulong steamId)
{
BasePlayer target = BasePlayer.FindByID(steamId);
return target != null ? target.displayName : steamId.ToString();
}
}
}The plugin tracks when each player joined their current team using OnTeamAcceptInvite and OnTeamCreated, and stores the join timestamp in memory keyed by Steam ID. OnTeamKick looks up the target's join time and compares it with the configured ProtectionSeconds. If the member joined recently, the plugin resolves the target's display name, sends a localized reply to the leader who issued the kick, and returns a non-null value so Rust never calls RemovePlayer. Team changes through OnTeamLeave and OnTeamDisbanded clear stale timestamps. Everything is driven by config, so admins can tune or disable the shield without recompiling.
Common use cases
Kick cooldowns per leader
Store the last kick time per leader Steam ID and return a non-null value when the cooldown has not elapsed, replying with the remaining seconds. This slows down leaders who kick and re-invite members in a loop.
Leader-only kick enforcement
Re-check that the calling player is still the team leader (or is authed in a staff list) before allowing the kick, which helps when a team's leadership changed through another plugin that bypassed the normal UI.
Grace period for new members
Record invite accept times and block kicks of members who joined in the last few minutes so leaders cannot use the team as a temporary loot transfer and kick players before they can react.
Pitfalls
The target ID is unvalidated
targetSteamIdis taken from the command argument before any membership check, so it may not be on the team. Do not assume it is a valid member when storing data or sending messages.Blocking silently desyncs the UI
When you return a value, the removal is skipped and no team update packet is sent. Players may see the target still listed only after the next team refresh, so always explain the block in chat.
Only the leader reaches this hook
The game checks
playerTeam.GetLeader() == playerand rejects self-kicks before calling the hook. Code that expects ordinary members to appear here will never run.
Plugin recipes that use OnTeamKick
- How to make a Rust team auto authorization plugin (TC, locks, turrets)Automatically authorizes a player on every tool cupboard, code lock and auto turret owned by their team when they join a team, and removes that authorization when they leave, are kicked or the team disbands. It uses OnTeamAcceptInvite, OnTeamLeave, OnTeamKick and OnTeamDisbanded.
- How to make a Rust team switch cooldown plugin (leave/kick lockout)Blocks a player from joining a team for N hours after leaving or being kicked, using OnTeamLeave, OnTeamKick and OnTeamAcceptInvite with per-player UTC timestamps saved in oxide/data.
Build a plugin with OnTeamKick
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 OnTeamKick
Generate