C#:
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Core.Libraries.Covalence;
using UnityEngine;
using Network;
namespace Oxide.Plugins
{
[Info("Admin Utilities", "dFxPhoeniX", "2.6.2")]
[Description("Toggle NoClip, teleport Under Terrain and more")]
public class AdminUtilities : RustPlugin
{
private const string permTerrain = "adminutilities.disconnectteleport";
private const string permInventory = "adminutilities.saveinventory";
private const string permHHT = "adminutilities.maxhht";
private const string permNoClip = "adminutilities.nocliptoggle";
private const string permGodMode = "adminutilities.godmodetoggle";
private const string permKick = "adminutilities.kick";
private const string permBan = "adminutilities.ban";
private const string permBanIp = "adminutilities.banip";
private const string permUnban = "adminutilities.unban";
private const string permBanList = "adminutilities.banlist";
private const string permPreventKick = "adminutilities.preventkick";
private const string permPreventBan = "adminutilities.preventban";
private const string permPreventBanIp = "adminutilities.preventbanip";
private const string permGive = "adminutilities.give";
private const string permGiveTo = "adminutilities.giveto";
private const string permGiveAll = "adminutilities.giveall";
private const string permSpawn = "adminutilities.spawn";
private const string permSpawnTo = "adminutilities.spawnto";
private const string permSpawnAll = "adminutilities.spawnall";
private const string permDespawn = "adminutilities.despawn";
private const string permBypassBlacklist = "adminutilities.bypassblacklist";
private const string permBypassDisabledPlayerConsoleCommands = "adminutilities.bypassplayerconsolecommands";
private const string permBypassDisabledChatCommands = "adminutilities.bypasschatcommands";
private DataFileSystem dataFile;
private DataFileSystem dataFileItems;
private ModerationData moderationData = new ModerationData();
private readonly HashSet<ulong> pendingForceNoClip = new HashSet<ulong>();
private readonly HashSet<string> allPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, string> prefabLookup = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private bool newSave;
////////////////////////////////////////////////////////////
// Files
////////////////////////////////////////////////////////////
private class PlayerInfo
{
public string Teleport { get; set; } = Vector3.zero.ToString();
public bool SaveInventory { get; set; } = true;
public bool UnderTerrain { get; set; } = false;
public bool NoClip { get; set; } = false;
public bool GodMode { get; set; } = false;
}
private Dictionary<string, PlayerInfo> playerInfoCache = new Dictionary<string, PlayerInfo>();
private class PlayerInfoItems
{
public List<AdminUtilitiesItem> Items { get; set; } = new List<AdminUtilitiesItem>();
public bool SnapshotOnly { get; set; } = false;
}
private Dictionary<string, PlayerInfoItems> playerInfoItemsCache = new Dictionary<string, PlayerInfoItems>();
private class AdminUtilitiesItem
{
public List<AdminUtilitiesItem> contents { get; set; }
public string container { get; set; } = "main";
public int ammo { get; set; }
public int amount { get; set; }
public int flags { get; set; }
public int containerSlots { get; set; }
public bool hasInstanceData { get; set; }
public string ammoType { get; set; }
public float condition { get; set; }
public float fuel { get; set; }
public int frequency { get; set; }
public int itemid { get; set; }
public float maxCondition { get; set; }
public string name { get; set; }
public int position { get; set; } = -1;
public ulong skin { get; set; }
public string text { get; set; }
public int blueprintAmount { get; set; }
public int blueprintTarget { get; set; }
public int dataInt { get; set; }
public ulong subEntity { get; set; }
public bool shouldPool { get; set; }
public AdminUtilitiesItem() { }
public AdminUtilitiesItem(string container, Item item)
{
this.container = container;
itemid = item.info.itemid;
name = item.name;
text = item.text;
amount = item.amount;
condition = item.condition;
maxCondition = item.maxCondition;
fuel = item.fuel;
position = item.position;
skin = item.skin;
flags = (int)item.flags;
hasInstanceData = item.instanceData != null;
if (item.instanceData != null)
{
dataInt = item.instanceData.dataInt;
blueprintAmount = item.instanceData.blueprintAmount;
blueprintTarget = item.instanceData.blueprintTarget;
subEntity = item.instanceData.subEntity.Value;
shouldPool = item.instanceData.ShouldPool;
}
if (item.contents != null)
{
containerSlots = item.contents.capacity;
if (item.contents.itemList != null && item.contents.itemList.Count > 0)
{
contents = new List<AdminUtilitiesItem>();
foreach (var mod in item.contents.itemList)
contents.Add(new AdminUtilitiesItem("default", mod));
}
}
if (item.GetHeldEntity() is HeldEntity e)
{
if (e is BaseProjectile baseProjectile)
{
ammo = baseProjectile.primaryMagazine.contents;
ammoType = baseProjectile.primaryMagazine.ammoType?.shortname;
}
else if (e is FlameThrower flameThrower)
{
ammo = flameThrower.ammo;
}
}
if (ItemModAssociatedEntity<PagerEntity>.GetAssociatedEntity(item) is PagerEntity pagerEntity)
{
frequency = pagerEntity.GetFrequency();
}
}
public static Item Create(AdminUtilitiesItem aui, bool restoreContents = true)
{
if (aui.itemid == 0 || string.IsNullOrEmpty(aui.container))
return null;
Item item;
if (aui.blueprintTarget != 0)
{
item = ItemManager.Create(Workbench.GetBlueprintTemplate());
item.blueprintTarget = aui.blueprintTarget;
item.amount = aui.blueprintAmount;
}
else item = ItemManager.CreateByItemID(aui.itemid, aui.amount, aui.skin);
if (item == null) return null;
item.flags = (Item.Flag)aui.flags;
if (aui.hasInstanceData)
{
item.instanceData = aui.shouldPool ? Pool.Get<ProtoBuf.Item.InstanceData>() : new ProtoBuf.Item.InstanceData();
item.instanceData.ShouldPool = aui.shouldPool;
item.instanceData.blueprintAmount = aui.blueprintAmount;
item.instanceData.blueprintTarget = aui.blueprintTarget;
item.instanceData.dataInt = aui.dataInt;
item.instanceData.subEntity = new NetworkableId(aui.subEntity);
}
if (!string.IsNullOrEmpty(aui.name)) item.name = aui.name;
if (!string.IsNullOrEmpty(aui.text)) item.text = aui.text;
if (item.GetHeldEntity() is HeldEntity e)
{
if (item.skin != 0) e.skinID = item.skin;
if (e is BaseProjectile bp)
{
bp.primaryMagazine.contents = aui.ammo;
if (!string.IsNullOrEmpty(aui.ammoType))
bp.primaryMagazine.ammoType = ItemManager.FindItemDefinition(aui.ammoType);
bp.DelayedModsChanged();
}
else if (e is FlameThrower ft) ft.ammo = aui.ammo;
else if (e is Chainsaw cs) cs.ammo = aui.ammo;
e.SendNetworkUpdate();
}
if (aui.frequency > 0 && item.info.GetComponentInChildren<ItemModRFListener>() != null)
{
if (item.instanceData != null && item.instanceData.subEntity.IsValid &&
BaseNetworkable.serverEntities.Find(item.instanceData.subEntity) is PagerEntity pagerEntity)
{
pagerEntity.ChangeFrequency(aui.frequency);
}
}
if (restoreContents)
{
var slots = System.Math.Max(aui.containerSlots, aui.contents?.Count ?? 0);
EnsureContainer(item, slots);
RestoreContents(null, item, aui.contents);
}
if (item.hasCondition)
{
item._maxCondition = aui.maxCondition;
item._condition = aui.condition;
}
item.fuel = aui.fuel;
item.MarkDirty();
return item;
}
private static T FindItemMod<T>(Item item) where T : ItemMod
{
var mods = item?.info?.itemMods;
if (mods == null) return null;
foreach (var m in mods)
if (m is T t) return t;
return null;
}
private static void EnsureContainer(Item item, int slots)
{
if (item == null || slots <= 0) return;
// Armor inserts container
var armorSlot = FindItemMod<ItemModContainerArmorSlot>(item);
if (armorSlot != null)
{
armorSlot.CreateAtCapacity(slots, item);
return;
}
// fallback generic container
if (item.contents == null)
{
item.contents = Pool.Get<ItemContainer>();
item.contents.ServerInitialize(item, slots);
if (!item.contents.uid.IsValid)
item.contents.GiveUID();
}
}
private static void RestoreContents(BasePlayer player, Item parent, List<AdminUtilitiesItem> saved)
{
if (saved == null || saved.Count == 0) return;
if (parent?.contents == null) return;
foreach (var aum in saved)
{
var mod = Create(aum, true);
if (mod == null) continue;
if (mod.MoveToContainer(parent.contents, aum.position, true) || mod.MoveToContainer(parent.contents))
continue;
if (player != null) player.GiveItem(mod);
else mod.Remove();
}
parent.contents.MarkDirty();
}
public static void Restore(BasePlayer player, AdminUtilitiesItem aui)
{
Item item = Create(aui, restoreContents: false);
if (item == null) return;
ItemContainer target;
switch (aui.container)
{
case "belt":
target = player.inventory.containerBelt;
break;
case "wear":
target = player.inventory.containerWear;
break;
case "main":
default:
target = player.inventory.containerMain;
break;
}
bool moved = item.MoveToContainer(target, aui.position, true);
if (!moved) player.GiveItem(item);
var slots = System.Math.Max(aui.containerSlots, aui.contents?.Count ?? 0);
EnsureContainer(item, slots);
RestoreContents(player, item, aui.contents);
if (item.GetHeldEntity() is BaseProjectile bp)
{
bp.DelayedModsChanged();
bp.SendNetworkUpdate();
}
item.MarkDirty();
}
}
private class ModerationData
{
public Dictionary<string, BanRecord> PlayerBans { get; set; } = new Dictionary<string, BanRecord>();
public Dictionary<string, BanRecord> IpBans { get; set; } = new Dictionary<string, BanRecord>();
public Dictionary<string, string> LastKnownIps { get; set; } = new Dictionary<string, string>();
public Dictionary<string, string> LastKnownNames { get; set; } = new Dictionary<string, string>();
}
private class BanRecord
{
public string Target { get; set; }
public string DisplayName { get; set; }
public string Reason { get; set; }
public string Source { get; set; }
public long CreatedAt { get; set; }
public long ExpiresAt { get; set; } // 0 = permanent
}
private PlayerInfo LoadPlayerInfo(BasePlayer player)
{
if (dataFile == null || player == null) return null;
if (playerInfoCache.TryGetValue(player.UserIDString, out var cached))
return cached;
var user = dataFile.ReadObject<PlayerInfo>(player.UserIDString) ?? new PlayerInfo();
playerInfoCache[player.UserIDString] = user;
return user;
}
private void SavePlayerInfo(BasePlayer player, PlayerInfo playerInfo)
{
if (dataFile == null) return;
dataFile.WriteObject($"{player.UserIDString}", playerInfo);
playerInfoCache[player.UserIDString] = playerInfo;
}
private PlayerInfoItems LoadPlayerInfoItems(BasePlayer player)
{
if (dataFileItems == null || player == null) return null;
if (playerInfoItemsCache.TryGetValue(player.UserIDString, out var cached))
return cached;
var userItems = dataFileItems.ReadObject<PlayerInfoItems>(player.UserIDString) ?? new PlayerInfoItems();
playerInfoItemsCache[player.UserIDString] = userItems;
return userItems;
}
private void SavePlayerInfoItems(BasePlayer player, PlayerInfoItems playerInfoItems)
{
if (dataFileItems == null) return;
dataFileItems.WriteObject($"{player.UserIDString}", playerInfoItems);
playerInfoItemsCache[player.UserIDString] = playerInfoItems;
}
private void LoadModerationData()
{
if (dataFile == null)
return;
moderationData = dataFile.ReadObject<ModerationData>("global") ?? new ModerationData();
}
private void SaveModerationData()
{
if (dataFile == null)
return;
dataFile.WriteObject("global", moderationData);
}
////////////////////////////////////////////////////////////
// Oxide Hooks
////////////////////////////////////////////////////////////
private void OnNewSave()
{
newSave = true;
}
private void Init()
{
InitConfig();
dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\AdminUtilities\\Settings");
dataFileItems = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\AdminUtilities\\Items");
LoadModerationData();
}
private void Loaded()
{
permission.RegisterPermission(permTerrain, this);
permission.RegisterPermission(permInventory, this);
permission.RegisterPermission(permHHT, this);
permission.RegisterPermission(permNoClip, this);
permission.RegisterPermission(permGodMode, this);
permission.RegisterPermission(permKick, this);
permission.RegisterPermission(permBan, this);
permission.RegisterPermission(permBanIp, this);
permission.RegisterPermission(permUnban, this);
permission.RegisterPermission(permBanList, this);
permission.RegisterPermission(permPreventKick, this);
permission.RegisterPermission(permPreventBan, this);
permission.RegisterPermission(permPreventBanIp, this);
permission.RegisterPermission(permGive, this);
permission.RegisterPermission(permGiveTo, this);
permission.RegisterPermission(permGiveAll, this);
permission.RegisterPermission(permSpawn, this);
permission.RegisterPermission(permSpawnTo, this);
permission.RegisterPermission(permSpawnAll, this);
permission.RegisterPermission(permDespawn, this);
permission.RegisterPermission(permBypassBlacklist, this);
permission.RegisterPermission(permBypassDisabledPlayerConsoleCommands, this);
permission.RegisterPermission(permBypassDisabledChatCommands, this);
}
private void OnServerInformationUpdated()
{
foreach (var player in BasePlayer.activePlayerList)
{
if (player == null || !player.IsConnected) continue;
bool relevant = player.IsFlying || player.IsGod() || player.IsDeveloper;
if (!relevant) continue;
var user = LoadPlayerInfo(player);
if (user == null) continue;
if (!player.IsFlying && user.NoClip)
{
user.NoClip = false;
SavePlayerInfo(player, user);
}
if (!player.IsGod() && user.GodMode)
{
user.GodMode = false;
SavePlayerInfo(player, user);
}
if (player.IsDeveloper && !player.IsFlying && !player.IsGod())
player.SetPlayerFlag(BasePlayer.PlayerFlags.IsDeveloper, false);
}
}
private object OnClientCommand(Connection connection, string command)
{
if (string.IsNullOrWhiteSpace(command))
return null;
BasePlayer player = BasePlayer.FindByID(connection.userid);
if (player == null)
return null;
PlayerInfo user = LoadPlayerInfo(player);
if (user == null)
return null;
string lowerCommand = command.ToLowerInvariant();
if (lowerCommand.Contains("setinfo \"global.god\" \"true\""))
{
if (!HasPermission(player, permGodMode) && !user.GodMode && !player.IsGod())
return false;
}
string playerConsoleCommand = ExtractPlayerConsoleCommandName(lowerCommand);
if (IsDisabledPlayerConsoleCommand(playerConsoleCommand) &&
!HasPermission(player, permBypassDisabledPlayerConsoleCommands))
return false;
string chatCommand = ExtractChatCommandName(command);
if (IsDisabledChatCommand(chatCommand) &&
!HasPermission(player, permBypassDisabledChatCommands))
return false;
return null;
}
private object OnServerCommand(ConsoleSystem.Arg arg)
{
if (arg?.cmd == null || arg.Connection != null)
return null;
string cmd = arg.cmd.FullName.ToLowerInvariant();
string[] args = arg.Args ?? Array.Empty<string>();
return TryHandleServerConsoleCommand(arg, cmd, args) ? (object)true : null;
}
private object OnRconCommand(IPAddress ipAddress, string command, string[] args)
{
if (string.IsNullOrWhiteSpace(command))
return null;
return TryHandleServerConsoleCommand(null, command.ToLowerInvariant(), args ?? Array.Empty<string>()) ? (object)true : null;
}
private void OnBroadcastCommand(string command, object[] args)
{
TryApplyGlobalServerIcon(command, args);
}
private void OnSendCommand(Connection cn, string command, object[] args)
{
TryApplyGlobalServerIcon(command, args);
}
private void OnSendCommand(List<Connection> cn, string command, object[] args)
{
TryApplyGlobalServerIcon(command, args);
}
private void OnPlayerTick(BasePlayer player)
{
if (player == null || !player.IsConnected) return;
if (player.IsNpc || player is NPCPlayer) return;
if (!player.IsFlying) return;
if (HasPermission(player, permNoClip)) return;
if (pendingForceNoClip.Contains(player.userID))
return;
var user = LoadPlayerInfo(player);
if (user == null) return;
if (user.NoClip) return;
pendingForceNoClip.Add(player.userID);
timer.Once(0.05f, () =>
{
if (player == null || !player.IsConnected)
{
pendingForceNoClip.Remove(player.userID);
return;
}
pendingForceNoClip.Remove(player.userID);
if (!HasPermission(player, permNoClip) && player.IsFlying)
player.SendConsoleCommand("noclip");
});
}
private void OnServerInitialized()
{
if (GetSave())
{
if (wipeSettings)
{
string folderPath = $"{Interface.Oxide.DataDirectory}/AdminUtilities/Settings";
if (Directory.Exists(folderPath))
{
foreach (string file in Directory.GetFiles(folderPath))
File.Delete(file);
}
}
if (wipeItems)
{
string folderItemsPath = $"{Interface.Oxide.DataDirectory}/AdminUtilities/Items";
if (Directory.Exists(folderItemsPath))
{
foreach (string file in Directory.GetFiles(folderItemsPath))
File.Delete(file);
}
}
newSave = false;
}
CachePrefabs();
CleanupExpiredBans();
}
private void OnUserBanned(string name, string id, string ipAddress, string reason, long expiry)
{
if (string.IsNullOrWhiteSpace(id))
return;
long now = UnixNow();
long newExpiry = expiry > 0 ? expiry : 0;
bool changed = false;
if (!moderationData.PlayerBans.TryGetValue(id, out var existing) || existing == null)
{
moderationData.PlayerBans[id] = new BanRecord
{
Target = id,
DisplayName = string.IsNullOrWhiteSpace(name) ? id : name,
Reason = string.IsNullOrWhiteSpace(reason) ? defaultBanReason : reason,
Source = "Native",
CreatedAt = now,
ExpiresAt = newExpiry
};
changed = true;
}
else
{
string newName = string.IsNullOrWhiteSpace(name) ? existing.DisplayName : name;
string newReason = string.IsNullOrWhiteSpace(reason) ? existing.Reason : reason;
if (existing.DisplayName != newName)
{
existing.DisplayName = newName;
changed = true;
}
if (existing.Reason != newReason)
{
existing.Reason = newReason;
changed = true;
}
if (existing.Source != "Native")
{
existing.Source = "Native";
changed = true;
}
// Native event should be authoritative for the current player-ban state
if (existing.ExpiresAt != newExpiry)
{
existing.ExpiresAt = newExpiry;
changed = true;
}
// Optional: refresh CreatedAt when the native ban is re-applied/changed
if (existing.CreatedAt <= 0)
{
existing.CreatedAt = now;
changed = true;
}
}
if (!string.IsNullOrWhiteSpace(ipAddress) && ipAddress != "0")
{
if (IsValidStoredIp(ipAddress))
{
if (!moderationData.LastKnownIps.TryGetValue(id, out var oldIp) || oldIp != ipAddress)
{
moderationData.LastKnownIps[id] = ipAddress;
changed = true;
}
}
}
if (!string.IsNullOrWhiteSpace(name))
{
if (!moderationData.LastKnownNames.TryGetValue(id, out var oldName) || oldName != name)
{
moderationData.LastKnownNames[id] = name;
changed = true;
}
}
if (changed)
SaveModerationData();
}
private void OnUserUnbanned(string name, string id, string ipAddress)
{
if (string.IsNullOrWhiteSpace(id))
return;
bool changed = false;
if (moderationData.PlayerBans.Remove(id))
changed = true;
if (changed)
SaveModerationData();
}
private void OnEntityTakeDamage(BasePlayer player, HitInfo info)
{
if (player == null || info == null)
return;
if (player.IsNpc || (player is NPCPlayer))
return;
PlayerInfo user = LoadPlayerInfo(player);
if (user == null)
return;
if (user.UnderTerrain)
{
info.damageTypes = new Rust.DamageTypeList();
}
}
private void OnPlayerDisconnected(BasePlayer player, string reason)
{
pendingForceNoClip.Remove(player.userID);
var user = LoadPlayerInfo(player);
if (user == null)
{
playerInfoCache.Remove(player.UserIDString);
playerInfoItemsCache.Remove(player.UserIDString);
return;
}
if (!HasPermission(player, permNoClip) && user.NoClip)
{
user.NoClip = false;
SavePlayerInfo(player, user);
}
if (!HasPermission(player, permGodMode) && user.GodMode)
{
user.GodMode = false;
SavePlayerInfo(player, user);
}
if (!persistentNoClip && user.NoClip)
{
user.NoClip = false;
SavePlayerInfo(player, user);
}
if (!persistentGodMode && user.GodMode)
{
user.GodMode = false;
SavePlayerInfo(player, user);
}
if (!player.IsDead())
{
if (HasPermission(player, permTerrain))
DisconnectTeleport(player);
if (HasPermission(player, permInventory) && user.SaveInventory)
SaveInventory(player, player.IsSleeping());
}
playerInfoCache.Remove(player.UserIDString);
playerInfoItemsCache.Remove(player.UserIDString);
}
private void OnPlayerConnected(BasePlayer player)
{
UpdateLastKnownPlayerIdentity(player);
PlayerInfo user = LoadPlayerInfo(player);
if (user == null)
return;
if (!HasPermission(player, permTerrain) && user.UnderTerrain)
{
NoUnderTerrain(player);
}
if (persistentNoClip && HasPermission(player, permNoClip) && user.NoClip)
{
player.SetPlayerFlag(BasePlayer.PlayerFlags.IsDeveloper, true);
timer.Once(0.2f, () =>
{
if (player == null || !player.IsConnected) return;
player.SendConsoleCommand("noclip");
});
}
if (persistentGodMode && HasPermission(player, permGodMode) && user.GodMode)
{
player.SetPlayerFlag(BasePlayer.PlayerFlags.IsDeveloper, true);
timer.Once(0.2f, () =>
{
if (player == null || !player.IsConnected) return;
player.SendConsoleCommand("setinfo \"global.god\" \"true\"");
});
}
timer.Once(0.5f, () =>
{
if (player == null || !player.IsConnected) return;
RestoreSavedInventory(player);
});
}
private void OnPlayerRespawned(BasePlayer player)
{
if (HasPermission(player, permHHT))
{
player.health = 100f;
player.metabolism.hydration.value = player.metabolism.hydration.max;
player.metabolism.calories.value = player.metabolism.calories.max;
}
}
private void OnPlayerSleepEnded(BasePlayer player)
{
if (!player || !player.IsConnected)
return;
PlayerInfo user = LoadPlayerInfo(player);
if (user == null)
return;
if (HasPermission(player, permTerrain) && user.UnderTerrain)
{
NoUnderTerrain(player);
}
RestoreSavedInventory(player);
}
private object OnPlayerViolation(BasePlayer player, AntiHackType type)
{
if (player.IsSleeping() && (type == AntiHackType.InsideTerrain) && HasPermission(player, permTerrain))
return true;
if (player.IsFlying && (type == AntiHackType.FlyHack || type == AntiHackType.InsideTerrain || type == AntiHackType.NoClip) && HasPermission(player, permNoClip))
return true;
return null;
}
private object CanUserLogin(string name, string id, string ip)
{
string message = BuildLoginBanMessage(id, ip, id);
if (!string.IsNullOrWhiteSpace(message))
return message;
return null;
}
////////////////////////////////////////////////////////////
// Commands
////////////////////////////////////////////////////////////
[ChatCommand("disconnectteleport")]
private void cmdDisconnectTeleport(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permTerrain))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
PlayerInfo user = LoadPlayerInfo(player);
if (user == null)
return;
if (args.Length >= 1)
{
switch (args[0].ToLower())
{
case "set":
{
if (args.Length == 4 && float.TryParse(args[1], out float x) && float.TryParse(args[2], out float y) && float.TryParse(args[3], out float z))
{
var customPos = new Vector3(x, y, z);
if (Vector3.Distance(customPos, Vector3.zero) <= TerrainMeta.Size.x / 1.5f && customPos.y > -100f && customPos.y < 4400f)
{
user.Teleport = customPos.ToString();
ReplyPlayerLocalized(player, "PositionAdded", FormatPosition(customPos));
}
else
{
ReplyPlayerLocalized(player, "OutOfBounds");
}
}
else
{
ReplyPlayerLocalized(player, "DisconnectTeleportSet", "/disconnectteleport", FormatPosition(user.Teleport.ToVector3()));
}
SavePlayerInfo(player, user);
return;
}
case "reset":
{
user.Teleport = defaultPos.ToString();
if (defaultPos != Vector3.zero)
ReplyPlayerLocalized(player, "PositionRemoved2", FormatPosition(defaultPos));
else
ReplyPlayerLocalized(player, "PositionRemoved1");
SavePlayerInfo(player, user);
return;
}
}
}
string teleportPos = FormatPosition(user.Teleport.ToVector3() == Vector3.zero ? defaultPos : user.Teleport.ToVector3());
ReplyPlayerLocalized(player, "DisconnectTeleportSet", "/disconnectteleport", teleportPos);
ReplyPlayerLocalized(player, "DisconnectTeleportReset", "/disconnectteleport");
}
[ChatCommand("saveinventory")]
private void cmdSaveInventory(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permInventory))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
PlayerInfo user = LoadPlayerInfo(player);
if (user == null)
return;
user.SaveInventory = !user.SaveInventory;
ReplyPlayerLocalized(player, user.SaveInventory ? "SavingInventory" : "NotSavingInventory");
SavePlayerInfo(player, user);
}
[ChatCommand("noclip")]
private void cmdNoClip(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permNoClip))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
ToggleNoClip(player);
}
[ChatCommand("nocliptoggle")]
private void cmdNoClipAlias(BasePlayer player, string command, string[] args)
{
cmdNoClip(player, command, args);
}
[ConsoleCommand("nocliptoggle")]
private void cmdNoClipConsole(ConsoleSystem.Arg arg)
{
BasePlayer player = arg.Player();
if (player == null)
{
ReplyConsoleLocalized(arg, "PlayersOnly", "nocliptoggle");
return;
}
if (!HasPermission(player, permNoClip))
{
ReplyPlayerConsoleLocalized(player, "NoPermission");
return;
}
ToggleNoClip(player, true);
}
[ChatCommand("god")]
private void cmdGodMode(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permGodMode))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
ToggleGodMode(player);
}
[ChatCommand("godmode")]
private void cmdGodModeAlias(BasePlayer player, string command, string[] args)
{
cmdGodMode(player, command, args);
}
[ConsoleCommand("godmode")]
private void cmdGodModeConsole(ConsoleSystem.Arg arg)
{
BasePlayer player = arg.Player();
if (player == null)
{
ReplyConsoleLocalized(arg, "PlayersOnly", "godmode");
return;
}
if (!HasPermission(player, permGodMode))
{
ReplyPlayerConsoleLocalized(player, "NoPermission");
return;
}
ToggleGodMode(player, true);
}
[ChatCommand("kick")]
private void cmdKick(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permKick))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
if (args.Length < 1)
{
ReplyPlayerLocalized(player, "KickUsage", "/kick");
return;
}
var target = FindOnlinePlayer(args[0]);
if (target == null)
{
ReplyPlayerLocalized(player, "PlayerNotFound");
return;
}
if (permission.UserHasPermission(target.UserIDString, permPreventKick))
{
ReplyPlayerLocalized(player, "TargetProtectedFromKick", target.displayName);
return;
}
string reason = string.Join(" ", args.Skip(1));
if (string.IsNullOrWhiteSpace(reason))
reason = defaultKickReason;
target.IPlayer.Kick(reason);
NotifyKickEvent(target.displayName, target.UserIDString, reason, true);
ReplyPlayerLocalized(player, "KickSuccess", target.displayName);
}
[ChatCommand("ban")]
private void cmdBan(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permBan))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
if (!TryParseModerationArgs(args, out var targetInput, out var duration, out var reason))
{
ReplyPlayerLocalized(player, "BanUsage", "/ban");
return;
}
if (IsIpAddress(targetInput))
{
AddIpBan(targetInput, targetInput, reason, duration, player.UserIDString);
KickAllPlayersByIp(targetInput);
NotifyBanEvent(targetInput, null, targetInput, duration, reason, false, false, 0, true);
if (duration.HasValue)
ReplyPlayerLocalized(player, "TempIpOnlyBanSuccess", targetInput, FormatDuration(duration.Value));
else
ReplyPlayerLocalized(player, "IpOnlyBanSuccess", targetInput);
return;
}
if (!TryResolveSteamId(targetInput, out var steamId, out var displayName, out var ip, out var onlinePlayer))
{
ReplyPlayerLocalized(player, "PlayerNotFound");
return;
}
if (permission.UserHasPermission(steamId, permPreventBan))
{
ReplyPlayerLocalized(player, "TargetProtectedFromBan", displayName ?? steamId);
return;
}
AddOrUpdatePlayerBan(steamId, displayName, reason, duration, player.UserIDString);
SetNativeBan(steamId, displayName ?? steamId, reason, duration);
onlinePlayer?.IPlayer?.Kick(BuildLoginBanMessage(steamId, ip, onlinePlayer?.UserIDString));
NotifyBanEvent(displayName ?? steamId, steamId, ip, duration, reason, false, false, 0, true);
if (duration.HasValue)
ReplyPlayerLocalized(player, "TempBanSuccess", displayName ?? steamId, FormatDuration(duration.Value));
else
ReplyPlayerLocalized(player, "BanSuccess", displayName ?? steamId);
}
[ChatCommand("banip")]
private void cmdBanIp(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permBanIp))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
if (!TryParseModerationArgs(args, out var targetInput, out var duration, out var reason))
{
ReplyPlayerLocalized(player, "BanIpUsage", "/banip");
return;
}
if (IsIpAddress(targetInput))
{
AddIpBan(targetInput, targetInput, reason, duration, player.UserIDString);
KickAllPlayersByIp(targetInput);
int bannedAccounts = BanKnownAccountsOnIp(targetInput, duration, reason, player.UserIDString);
NotifyBanEvent(targetInput, null, targetInput, duration, reason, true, true, bannedAccounts, true);
if (duration.HasValue)
ReplyPlayerLocalized(player, "TempIpAndAccountsBanSuccess", targetInput, FormatDuration(duration.Value), bannedAccounts);
else
ReplyPlayerLocalized(player, "IpAndAccountsBanSuccess", targetInput, bannedAccounts);
return;
}
if (!TryResolveSteamId(targetInput, out var steamId, out var displayName, out var ip, out var onlinePlayer))
{
ReplyPlayerLocalized(player, "PlayerNotFound");
return;
}
if (permission.UserHasPermission(steamId, permPreventBanIp))
{
ReplyPlayerLocalized(player, "TargetProtectedFromBanIp", displayName ?? steamId);
return;
}
AddOrUpdatePlayerBan(steamId, displayName, reason, duration, player.UserIDString);
SetNativeBan(steamId, displayName ?? steamId, reason, duration);
if (IsValidStoredIp(ip))
{
AddIpBan(ip, displayName ?? ip, reason, duration, player.UserIDString);
KickAllPlayersByIp(ip);
}
else if (onlinePlayer != null)
{
onlinePlayer.IPlayer.Kick(BuildLoginBanMessage(steamId, null, onlinePlayer.UserIDString));
}
NotifyBanEvent(displayName ?? steamId, steamId, ip, duration, reason, true, false, 0, true);
string shownIp = IsValidStoredIp(ip) ? ip : "unknown";
if (duration.HasValue)
ReplyPlayerLocalized(player, "TempBanIpSuccess", displayName ?? steamId, shownIp, FormatDuration(duration.Value));
else
ReplyPlayerLocalized(player, "BanIpSuccess", displayName ?? steamId, shownIp);
}
[ChatCommand("unban")]
private void cmdUnban(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permUnban))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
if (args.Length != 1)
{
ReplyPlayerLocalized(player, "UnbanUsage", "/unban");
return;
}
if (!TryResolveUnbanTarget(args[0], out var steamId, out var ip))
{
ReplyPlayerLocalized(player, "NotBanned");
return;
}
if (!string.IsNullOrWhiteSpace(ip))
{
bool removedIpBan = moderationData.IpBans.Remove(ip);
if (!removedIpBan)
{
ReplyPlayerLocalized(player, "NotBanned");
return;
}
SaveModerationData();
NotifyUnbanEvent(ip, true, true);
ReplyPlayerLocalized(player, "UnbanIpSuccess", ip);
return;
}
if (!string.IsNullOrWhiteSpace(steamId))
{
moderationData.PlayerBans.TryGetValue(steamId, out var banRecordBeforeRemove);
string displayName =
banRecordBeforeRemove != null &&
!string.IsNullOrWhiteSpace(banRecordBeforeRemove.DisplayName) &&
!string.Equals(banRecordBeforeRemove.DisplayName, steamId, StringComparison.OrdinalIgnoreCase)
? banRecordBeforeRemove.DisplayName
: GetKnownDisplayName(steamId);
bool removedPlayerBan = moderationData.PlayerBans.Remove(steamId);
bool removedIpBan = false;
string linkedIp = null;
if (moderationData.LastKnownIps.TryGetValue(steamId, out linkedIp) && IsValidStoredIp(linkedIp))
removedIpBan = moderationData.IpBans.Remove(linkedIp);
else
linkedIp = null;
if (!removedPlayerBan && !removedIpBan)
{
ReplyPlayerLocalized(player, "NotBanned");
return;
}
if (removedPlayerBan)
RemoveNativeBan(steamId);
SaveModerationData();
if (removedPlayerBan && removedIpBan)
NotifyUnbanPlayerAndIpEvent(displayName, steamId, linkedIp, true);
else if (removedPlayerBan)
NotifyUnbanEvent(displayName, false, true, steamId);
else if (removedIpBan)
NotifyUnbanEvent(linkedIp, true, true);
if (removedPlayerBan && removedIpBan)
ReplyPlayerLocalized(player, "UnbanPlayerAndIpSuccess", displayName, linkedIp);
else if (removedPlayerBan)
ReplyPlayerLocalized(player, "UnbanPlayerSuccess", displayName);
else if (removedIpBan)
ReplyPlayerLocalized(player, "UnbanIpSuccess", linkedIp);
}
}
[ChatCommand("banlist")]
private void cmdBanList(BasePlayer player, string command, string[] args)
{
if (!HasPermission(player, permBanList))
{
ReplyPlayerLocalized(player, "NoPermission");
return;
}
string mode = "all";
int page = 1;
if (args.Length >= 1)
mode = args[0].ToLower();
if (args.Length >= 2 && !int.TryParse(args[1], out page))
{
ReplyPlayerLocalized(player, "BanListUsage", "/banlist");
return;
}
if (page < 1)
page = 1;
var entries = GetBanListEntries(mode).ToList();
if (entries.Count == 0)
{
ReplyPlayerLocalized(
// ... [Code preview truncated due to length. Full source in attached file] ...