Иконка ресурса

FREE AdminUtilities : 2.6.2 2.6.2

Нет прав для скачивания
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] ...

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху