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

FREE RemoverTool : 4.3.31 4.3.31

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using VLB;
using Time = UnityEngine.Time;
namespace Oxide.Plugins {
    [Info("Remover Tool", "Reneb/Fuji/Arainrr", "4.3.31", ResourceId = 651)]
    [Description("Building and entity removal tool")]
    public class RemoverTool : RustPlugin {
#region Fields
        [PluginReference]
        private readonly Plugin Friends, ServerRewards, Clans, Economics, ImageLibrary, BuildingOwners, RustTranslationAPI, NoEscape;
        private const string ECONOMICS_KEY = "economics";
        private const string SERVER_REWARDS_KEY = "serverrewards";
        private const string PERMISSION_ALL = "removertool.all";
        private const string PERMISSION_ADMIN = "removertool.admin";
        private const string PERMISSION_NORMAL = "removertool.normal";
        private const string PERMISSION_TARGET = "removertool.target";
        private const string PERMISSION_EXTERNAL = "removertool.external";
        private const string PERMISSION_OVERRIDE = "removertool.override";
        private const string PERMISSION_STRUCTURE = "removertool.structure";
        private const string PREFAB_ITEM_DROP = "assets/prefabs/misc/item drop/item_drop.prefab";
        private const int LAYER_ALL = 1 << 0 | 1 << 8 | 1 << 21;
        private const int LAYER_TARGET = ~(1 << 2 | 1 << 3 | 1 << 4 | 1 << 10 | 1 << 18 | 1 << 28 | 1 << 29);
        private static object False;
        private static RemoverTool _rt;
        private static BUTTON _removeButton;
        private static RemoveMode _removeMode;
        private bool _removeOverride;
        private Coroutine _removeAllCoroutine;
        private Coroutine _removeStructureCoroutine;
        private Coroutine _removeExternalCoroutine;
        private Coroutine _removePlayerEntityCoroutine;
        private Hash<uint, float> _entitySpawnedTimes;
        private readonly Hash<ulong, float> _cooldownTimes = new Hash<ulong, float>();
        private enum RemoveMode {
            None, NoHeld, MeleeHit, SpecificTool
        }
        private enum RemoveType {
            None, All, Admin, Normal, External, Structure
        }
        private enum PlayerEntityRemoveType {
            All, Cupboard, Building,
        }
#endregion Fields
#region Oxide Hooks
        private void Init() {
            _rt = this;
            False = false;
            permission.RegisterPermission(PERMISSION_ALL, this);
            permission.RegisterPermission(PERMISSION_ADMIN, this);
            permission.RegisterPermission(PERMISSION_NORMAL, this);
            permission.RegisterPermission(PERMISSION_TARGET, this);
            permission.RegisterPermission(PERMISSION_OVERRIDE, this);
            permission.RegisterPermission(PERMISSION_EXTERNAL, this);
            permission.RegisterPermission(PERMISSION_STRUCTURE, this);
            Unsubscribe(nameof(OnHammerHit));
            Unsubscribe(nameof(OnEntitySpawned));
            Unsubscribe(nameof(OnEntityKill));
            Unsubscribe(nameof(OnPlayerAttack));
            Unsubscribe(nameof(OnActiveItemChanged));
            Unsubscribe(nameof(OnServerSave));
            Unsubscribe(nameof(OnRaidBlock));
            Unsubscribe(nameof(OnCombatBlock));
            foreach (var perm in configData.permS.Keys) {
                if (!permission.PermissionExists(perm, this)) {
                    permission.RegisterPermission(perm, this);
                }
            }
            cmd.AddChatCommand(configData.chatS.command, this, nameof(CmdRemove));
        }
        private void OnServerInitialized() {
            Initialize();
            UpdateConfig();
            _removeMode = RemoveMode.None;
            if (configData.removerModeS.noHeldMode) _removeMode = RemoveMode.NoHeld;
            if (configData.removerModeS.meleeHitMode) _removeMode = RemoveMode.MeleeHit;
            if (configData.removerModeS.specificToolMode) _removeMode = RemoveMode.SpecificTool;
            if (_removeMode == RemoveMode.MeleeHit) {
                BaseMelee beseMelee;
                ItemDefinition itemDefinition;
                if (string.IsNullOrEmpty(configData.removerModeS.meleeHitItemShortname) || (itemDefinition = ItemManager.FindItemDefinition(configData.removerModeS.meleeHitItemShortname)) == null || (beseMelee = itemDefinition.GetComponent<ItemModEntity>()?.entityPrefab.Get()?.GetComponent<BaseMelee>()) == null) {
                    PrintError($"{configData.removerModeS.meleeHitItemShortname} is not an item shortname for a melee tool");
                    _removeMode = RemoveMode.None;
                }
                else {
                    Subscribe(beseMelee is Hammer ? nameof(OnHammerHit) : nameof(OnPlayerAttack));
                }
            }
            if (configData.noEscapeS.useRaidBlocker) {
                Subscribe(nameof(OnRaidBlock));
            }
            if (configData.noEscapeS.useCombatBlocker) {
                Subscribe(nameof(OnCombatBlock));
            }
            if (configData.globalS.entityTimeLimit) {
                _entitySpawnedTimes = new Hash<uint, float>();
                Subscribe(nameof(OnEntitySpawned));
                Subscribe(nameof(OnEntityKill));
                Subscribe(nameof(OnServerSave));
            }
            if (configData.globalS.logToFile) {
                debugStringBuilder = new StringBuilder();
                Subscribe(nameof(OnServerSave));
            }
            if (_removeMode == RemoveMode.MeleeHit && configData.removerModeS.meleeHitEnableInHand || _removeMode == RemoveMode.SpecificTool && configData.removerModeS.specificToolEnableInHand) {
                Subscribe(nameof(OnActiveItemChanged));
            }
            if (!Enum.TryParse(configData.globalS.removeButton, true, out _removeButton) || !Enum.IsDefined(typeof(BUTTON), _removeButton)) {
                PrintError($"{configData.globalS.removeButton} is an invalid button.The remove button has been changed to 'FIRE_PRIMARY'.");
                _removeButton = BUTTON.FIRE_PRIMARY;
                configData.globalS.removeButton = _removeButton.ToString();
                SaveConfig();
            }
            if (ImageLibrary != null) {
                foreach (var image in configData.imageUrls) {
                    AddImageToLibrary(image.Value, image.Key);
                }
                if (configData.uiS.showCrosshair) {
                    AddImageToLibrary(configData.uiS.crosshairImageUrl, UINAME_CROSSHAIR);
                }
            }
        }
        private void Unload() {
            if (_removeAllCoroutine != null) ServerMgr.Instance.StopCoroutine(_removeAllCoroutine);
            if (_removeStructureCoroutine != null) ServerMgr.Instance.StopCoroutine(_removeStructureCoroutine);
            if (_removeExternalCoroutine != null) ServerMgr.Instance.StopCoroutine(_removeExternalCoroutine);
            if (_removePlayerEntityCoroutine != null) ServerMgr.Instance.StopCoroutine(_removePlayerEntityCoroutine);
            foreach (var player in BasePlayer.activePlayerList) {
                player.GetComponent<ToolRemover>()?.DisableTool();
            }
            SaveDebug();
            configData = null;
            False = _rt = null;
        }
        private void OnServerSave() {
            if (configData.globalS.logToFile) {
                timer.Once(UnityEngine.Random.Range(0f, 60f), SaveDebug);
            }
            if (_entitySpawnedTimes != null) {
                var currentTime = Time.realtimeSinceStartup;
                foreach (var entry in _entitySpawnedTimes.ToArray()) {
                    if (currentTime - entry.Value > configData.globalS.limitTime) {
                        _entitySpawnedTimes.Remove(entry.Key);
                    }
                }
            }
        }
        private void OnEntitySpawned(BaseEntity entity) {
            if (entity == null || entity.net == null) return;
            // if (!CanEntityBeSaved(entity)) return;
            _entitySpawnedTimes[entity.net.ID] = Time.realtimeSinceStartup;
        }
        private void OnEntityKill(BaseEntity entity) {
            if (entity == null || entity.net == null) return;
            _entitySpawnedTimes.Remove(entity.net.ID);
        }
        private object OnPlayerAttack(BasePlayer player, HitInfo info) => OnHammerHit(player, info);
        private object OnHammerHit(BasePlayer player, HitInfo info) {
            if (player == null || info.HitEntity == null) return null;
            var toolRemover = player.GetComponent<ToolRemover>();
            if (toolRemover == null) return null;
            if (!IsMeleeTool(player)) return null;
            toolRemover.hitEntity = info.HitEntity;
            return False;
        }
        private void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem) {
            if (newItem == null) return;
            if (player == null || !player.userID.IsSteamId()) return;
            if (IsToolRemover(player)) return;
            if (_removeMode == RemoveMode.MeleeHit && IsMeleeTool(newItem)) {
                ToggleRemove(player, RemoveType.Normal);
                return;
            }
            if (_removeMode == RemoveMode.SpecificTool && IsSpecificTool(newItem)) {
                ToggleRemove(player, RemoveType.Normal);
                return;
            }
        }
#endregion Oxide Hooks
#region Initializing
        private readonly HashSet<Construction> _constructions = new HashSet<Construction>();
        private readonly Dictionary<string, int> _itemShortNameToItemId = new Dictionary<string, int>();
        private readonly Dictionary<string, string> _prefabNameToStructure = new Dictionary<string, string>();
        private readonly Dictionary<string, string> _shortPrefabNameToDeployable = new Dictionary<string, string>();
        private void Initialize() {
            foreach (var itemDefinition in ItemManager.GetItemDefinitions()) {
                if (!_itemShortNameToItemId.ContainsKey(itemDefinition.shortname)) {
                    _itemShortNameToItemId.Add(itemDefinition.shortname, itemDefinition.itemid);
                }
                var deployablePrefab = itemDefinition.GetComponent<ItemModDeployable>()?.entityPrefab?.resourcePath;
                if (string.IsNullOrEmpty(deployablePrefab)) {
                    continue;
                }
                var shortPrefabName = Utility.GetFileNameWithoutExtension(deployablePrefab);
                if (!string.IsNullOrEmpty(shortPrefabName) && !_shortPrefabNameToDeployable.ContainsKey(shortPrefabName)) {
                    _shortPrefabNameToDeployable.Add(shortPrefabName, itemDefinition.shortname);
                }
            }
            foreach (var entry in PrefabAttribute.server.prefabs) {
                var construction = entry.Value.Find<Construction>().FirstOrDefault();
                if (construction != null && construction.deployable == null && !string.IsNullOrEmpty(construction.info.name.english)) {
                    _constructions.Add(construction);
                    if (!_prefabNameToStructure.ContainsKey(construction.fullName)) {
                        _prefabNameToStructure.Add(construction.fullName, construction.info.name.english);
                    }
                }
            }
        }
#endregion Initializing
#region Methods
        private static string GetRemoveTypeName(RemoveType removeType) => configData.removeTypeS[removeType].displayName;
        private static void DropItemContainer(ItemContainer itemContainer, Vector3 position, Quaternion rotation) => itemContainer?.Drop(PREFAB_ITEM_DROP, position, rotation);
        private static bool IsExternalWall(StabilityEntity stabilityEntity) => stabilityEntity.ShortPrefabName.Contains("external");
        private static bool CanEntityBeDisplayed(BaseEntity entity, BasePlayer player) {
            var stash = entity as StashContainer;
            return stash == null || !stash.IsHidden() || stash.PlayerInRange(player);
        }
        private static bool CanEntityBeSaved(BaseEntity entity) {
            if (entity is BuildingBlock) {
                return true;
            }
            EntitySettings entitySettings;
            if (configData.removeS.entityS.TryGetValue(entity.ShortPrefabName, out entitySettings) && entitySettings.enabled) {
                return true;
            }
            return false;
        }
        private static bool HasEntityEnabled(BaseEntity entity) {
            var buildingBlock = entity as BuildingBlock;
            if (buildingBlock != null) {
                bool valid;
                if (configData.removeS.validConstruction.TryGetValue(buildingBlock.grade, out valid) && valid) {
                    return true;
                }
            }
            EntitySettings entitySettings;
            if (configData.removeS.entityS.TryGetValue(entity.ShortPrefabName, out entitySettings) && entitySettings.enabled) {
                return true;
            }
            return false;
        }
        private static bool IsRemovableEntity(BaseEntity entity) {
            if (_rt._shortPrefabNameToDeployable.ContainsKey(entity.ShortPrefabName) || _rt._prefabNameToStructure.ContainsKey(entity.PrefabName) || configData.removeS.entityS.ContainsKey(entity.ShortPrefabName)) {
                var baseCombatEntity = entity as BaseCombatEntity;
                if (baseCombatEntity != null) {
                    if (baseCombatEntity.IsDead()) {
                        return false;
                    }
                    if (baseCombatEntity.pickup.itemTarget != null) {
                        return true;
                    }
                }
                return true;
            }
            return false;
        }
        private static string GetEntityImage(string name) {
            if (configData.imageUrls.ContainsKey(name)) {
                return GetImageFromLibrary(name);
            }
            if (_rt._itemShortNameToItemId.ContainsKey(name)) {
                return GetImageFromLibrary(name);
            }
            return null;
        }
        private static string GetItemImage(string shortname) {
            switch (shortname.ToLower()) {
                case ECONOMICS_KEY : return GetImageFromLibrary(ECONOMICS_KEY);
                case SERVER_REWARDS_KEY : return GetImageFromLibrary(SERVER_REWARDS_KEY);
            }
            return GetEntityImage(shortname);
        }
        private static void TryFindEntityName(BasePlayer player, BaseEntity entity, out string displayName, out string imageName) {
            var target = entity as BasePlayer;
            if (target != null) {
                imageName = target.userID.IsSteamId() ? target.UserIDString : target.ShortPrefabName;
                displayName = $"{target.displayName} ({GetOtherDisplayName(target.ShortPrefabName)})";
                return;
            }
            EntitySettings entitySettings;
            if (configData.removeS.entityS.TryGetValue(entity.ShortPrefabName, out entitySettings)) {
                imageName = entity.ShortPrefabName;
                displayName = _rt.GetDeployableDisplayName(player, entity.ShortPrefabName, entitySettings.displayName);
                return;
            }
            string structureName;
            if (_rt._prefabNameToStructure.TryGetValue(entity.PrefabName, out structureName)) {
                BuildingBlocksSettings buildingBlockSettings;
                if (configData.removeS.buildingBlockS.TryGetValue(structureName, out buildingBlockSettings)) {
                    imageName = structureName;
                    displayName = _rt.GetConstructionDisplayName(player, entity.PrefabName, buildingBlockSettings.displayName);
                    return;
                }
            }
            imageName = entity.ShortPrefabName;
            displayName = GetOtherDisplayName(entity.ShortPrefabName);
        }
        private static string GetDisplayNameByPriceName(string language, string priceName) {
            var itemDefinition = ItemManager.FindItemDefinition(priceName);
            if (itemDefinition != null) {
                var displayName = _rt.GetItemDisplayName(language, itemDefinition.shortname);
                if (!string.IsNullOrEmpty(displayName)) {
                    return displayName;
                }
                return GetOtherDisplayName(itemDefinition.displayName.english);
            }
            return GetOtherDisplayName(priceName);
        }
        private static string GetOtherDisplayName(string name) {
            string displayName;
            if (configData.displayNames.TryGetValue(name, out displayName)) {
                return displayName;
            }
            configData.displayNames.Add(name, name);
            _rt.SaveConfig();
            return name;
        }
        private static PermissionSettings GetPermissionS(BasePlayer player) {
            int priority = 0;
            PermissionSettings permissionSettings = null;
            foreach (var entry in configData.permS) {
                if (entry.Value.priority >= priority && _rt.permission.UserHasPermission(player.UserIDString, entry.Key)) {
                    priority = entry.Value.priority;
                    permissionSettings = entry.Value;
                }
            }
            return permissionSettings ?? new PermissionSettings();
        }
        private static Vector2 GetAnchor(string anchor) {
            var array = anchor.Split(' ');
            return new Vector2(float.Parse(array[0]), float.Parse(array[1]));
        }
        private static bool AddImageToLibrary(string url, string shortname, ulong skin = 0) => (bool)_rt.ImageLibrary.Call("AddImage", url, shortname.ToLower(), skin);
        private static string GetImageFromLibrary(string shortname, ulong skin = 0, bool returnUrl = false) => string.IsNullOrEmpty(shortname) ? null : (string)_rt.ImageLibrary.Call("GetImage", shortname.ToLower(), skin, returnUrl);
#endregion Methods
#region NoEscape
        private void OnRaidBlock(BasePlayer player) {
            if (configData.noEscapeS.useRaidBlocker) {
                //TODO lang
                player.GetComponent<ToolRemover>()?.DisableTool(false);
            }
        }
        private void OnCombatBlock(BasePlayer player) {
            if (configData.noEscapeS.useCombatBlocker) {
                //TODO lang
                player.GetComponent<ToolRemover>()?.DisableTool(false);
            }
        }
        private bool IsPlayerBlocked(BasePlayer player, out string reason) {
            if (NoEscape == null) {
                reason = null;
                return false;
            }
            if (configData.noEscapeS.useRaidBlocker && IsRaidBlocked(player.UserIDString)) {
                //TODO lang
                reason = Lang("RaidBlocked", player.UserIDString);
                return true;
            }
            if (configData.noEscapeS.useCombatBlocker && IsCombatBlocked(player.UserIDString)) {
                //TODO lang
                reason = Lang("CombatBlocked", player.UserIDString);
                return true;
            }
            reason = null;
            return false;
        }
        private bool IsRaidBlocked(string playerID) => (bool)NoEscape.Call("IsRaidBlocked", playerID);
        private bool IsCombatBlocked(string playerID) => (bool)NoEscape.Call("IsCombatBlocked", playerID);
#endregion NoEscape
#region UI
        private static class UI {
            public static CuiElementContainer CreateElementContainer(string parent, string panelName, string backgroundColor, string anchorMin, string anchorMax, string offsetMin = "", string offsetMax = "", bool cursor = false) {
                return new CuiElementContainer() {
                    {
                        new CuiPanel {
                            Image = {
                                Color = backgroundColor
                            }
                            , RectTransform = {
                                AnchorMin = anchorMin, AnchorMax = anchorMax , OffsetMin = offsetMin, OffsetMax = offsetMax
                            }
                            , CursorEnabled = cursor
                        }
                        , parent, panelName
                    }
                }
                ;
            }
            public static void CreatePanel(ref CuiElementContainer container, string panelName, string backgroundColor, string anchorMin, string anchorMax, bool cursor = false) {
                container.Add(new CuiPanel {
                    Image = {
                        Color = backgroundColor
                    }
                    , RectTransform = {
                        AnchorMin = anchorMin, AnchorMax = anchorMax
                    }
                    , CursorEnabled = cursor
                }
                , panelName);
            }
            public static void CreateLabel(ref CuiElementContainer container, string panelName, string textColor, string text, int fontSize, string anchorMin, string anchorMax, TextAnchor align = TextAnchor.MiddleCenter, float fadeIn = 0f) {
                container.Add(new CuiLabel {
                    Text = {
                        Color = textColor, FontSize = fontSize, Align = align, Text = text, FadeIn = fadeIn
                    }
                    , RectTransform = {
                        AnchorMin = anchorMin, AnchorMax = anchorMax
                    }
                }
                , panelName);
            }
            public static void CreateImage(ref CuiElementContainer container, string panelName, string image, string anchorMin, string anchorMax, string color = "1 1 1 1") {
                container.Add(new CuiElement {
                    Name = CuiHelper.GetGuid(), Parent = panelName, Components = {
                        new CuiRawImageComponent {
                            Sprite = "assets/content/textures/generic/fulltransparent.tga", Color = color, Png = image
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchorMin, AnchorMax = anchorMax
                        }
                    }
                }
                );
            }
        }
        [Flags]
        private enum UiEntry {
            None = 0, Entity = 1, Price = 1 << 1, Refund = 1 << 2, Auth = 1 << 3,
        }
        private const string UINAME_MAIN = "RemoverToolUI_Main";
        private const string UINAME_TIMELEFT = "RemoverToolUI_TimeLeft";
        private const string UINAME_ENTITY = "RemoverToolUI_Entity";
        private const string UINAME_PRICE = "RemoverToolUI_Price";
        private const string UINAME_REFUND = "RemoverToolUI_Refund";
        private const string UINAME_AUTH = "RemoverToolUI_Auth";
        private const string UINAME_CROSSHAIR = "RemoverToolUI_Crosshair";
        private static void CreateCrosshairUI(BasePlayer player) {
            if (_rt.ImageLibrary == null) return;
            var image = GetImageFromLibrary(UINAME_CROSSHAIR);
            if (string.IsNullOrEmpty(image)) return;
            var container = UI.CreateElementContainer("Hud", UINAME_CROSSHAIR, "0 0 0 0", configData.uiS.crosshairAnchorMin, configData.uiS.crosshairAnchorMax, configData.uiS.crosshairOffsetMin, configData.uiS.crosshairOffsetMax);
            UI.CreateImage(ref container, UINAME_CROSSHAIR, image, "0 0", "1 1", configData.uiS.crosshairColor);
            CuiHelper.DestroyUi(player, UINAME_CROSSHAIR);
            CuiHelper.AddUi(player, container);
        }
        private static void CreateMainUI(BasePlayer player, RemoveType removeType) {
            var container = UI.CreateElementContainer("Hud", UINAME_MAIN, configData.uiS.removerToolBackgroundColor, configData.uiS.removerToolAnchorMin, configData.uiS.removerToolAnchorMax, configData.uiS.removerToolOffsetMin, configData.uiS.removerToolOffsetMax);
            UI.CreatePanel(ref container, UINAME_MAIN, configData.uiS.removeBackgroundColor, configData.uiS.removeAnchorMin, configData.uiS.removeAnchorMax);
            UI.CreateLabel(ref container, UINAME_MAIN, configData.uiS.removeTextColor, _rt.Lang("RemoverToolType", player.UserIDString, GetRemoveTypeName(removeType)), configData.uiS.removeTextSize, configData.uiS.removeTextAnchorMin, configData.uiS.removeTextAnchorMax, TextAnchor.MiddleLeft);
            CuiHelper.DestroyUi(player, UINAME_MAIN);
            CuiHelper.AddUi(player, container);
        }
        private static void UpdateTimeLeftUI(BasePlayer player, RemoveType removeType, int timeLeft, int currentRemoved, int maxRemovable) {
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_TIMELEFT, configData.uiS.timeLeftBackgroundColor, configData.uiS.timeLeftAnchorMin, configData.uiS.timeLeftAnchorMax);
            UI.CreateLabel(ref container, UINAME_TIMELEFT, configData.uiS.timeLeftTextColor, _rt.Lang("TimeLeft", player.UserIDString, timeLeft, removeType == RemoveType.Normal || removeType == RemoveType.Admin ? maxRemovable == 0 ? $"{currentRemoved} / {_rt.Lang("Unlimit", player.UserIDString)}" : $"{currentRemoved} / {maxRemovable}" : currentRemoved.ToString()), configData.uiS.timeLeftTextSize, configData.uiS.timeLeftTextAnchorMin, configData.uiS.timeLeftTextAnchorMax, TextAnchor.MiddleLeft);
            CuiHelper.DestroyUi(player, UINAME_TIMELEFT);
            CuiHelper.AddUi(player, container);
        }
        private static void UpdateEntityUI(BasePlayer player, BaseEntity targetEntity, RemovableEntityInfo? info) {
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_ENTITY, configData.uiS.entityBackgroundColor, configData.uiS.entityAnchorMin, configData.uiS.entityAnchorMax);
            string displayName, imageName;
            TryFindEntityName(player, targetEntity, out displayName, out imageName);
            if (info.HasValue && !string.IsNullOrEmpty(info.Value.DisplayName.Value)) {
                displayName = info.Value.DisplayName.Value;
            }
            UI.CreateLabel(ref container, UINAME_ENTITY, configData.uiS.entityTextColor, displayName, configData.uiS.entityTextSize, configData.uiS.entityTextAnchorMin, configData.uiS.entityTextAnchorMax, TextAnchor.MiddleLeft);
            if (configData.uiS.entityImageEnabled && !string.IsNullOrEmpty(imageName) && _rt.ImageLibrary != null) {
                var imageId = info.HasValue && !string.IsNullOrEmpty(info.Value.ImageId.Value) ? info.Value.ImageId.Value : GetEntityImage(imageName);
                if (!string.IsNullOrEmpty(imageId)) {
                    UI.CreateImage(ref container, UINAME_ENTITY, imageId, configData.uiS.entityImageAnchorMin, configData.uiS.entityImageAnchorMax);
                }
            }
            CuiHelper.DestroyUi(player, UINAME_ENTITY);
            CuiHelper.AddUi(player, container);
        }
        private static void UpdatePriceUI(BasePlayer player, BaseEntity targetEntity, RemovableEntityInfo? info, bool usePrice) {
            Dictionary<string, int> price = null;
            if (usePrice) {
                price = _rt.GetPrice(targetEntity, info);
            }
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_PRICE, configData.uiS.priceBackgroundColor, configData.uiS.priceAnchorMin, configData.uiS.priceAnchorMax);
            UI.CreateLabel(ref container, UINAME_PRICE, configData.uiS.priceTextColor, _rt.Lang("Price", player.UserIDString), configData.uiS.priceTextSize, configData.uiS.priceTextAnchorMin, configData.uiS.priceTextAnchorMax, TextAnchor.MiddleLeft);
            if (price == null || price.Count == 0) {
                UI.CreateLabel(ref container, UINAME_PRICE, configData.uiS.price2TextColor, _rt.Lang("Free", player.UserIDString), configData.uiS.price2TextSize, configData.uiS.price2TextAnchorMin, configData.uiS.price2TextAnchorMax, TextAnchor.MiddleLeft);
            }
            else {
                var anchorMin = configData.uiS.Price2TextAnchorMin;
                var anchorMax = configData.uiS.Price2TextAnchorMax;
                float x = (anchorMax.y - anchorMin.y) / price.Count;
                int textSize = configData.uiS.price2TextSize - price.Count;
                string language = _rt.lang.GetLanguage(player.UserIDString);
                int i = 0;
                foreach (var entry in price) {
                    var itemInfo = info?.Price[entry.Key];
                    string displayText = !itemInfo.HasValue || string.IsNullOrEmpty(itemInfo.Value.DisplayName.Value) ? $"{GetDisplayNameByPriceName(language, entry.Key)} x{entry.Value}" : $"{itemInfo.Value.DisplayName.Value} x{itemInfo.Value.Amount.Value}";
                    UI.CreateLabel(ref container, UINAME_PRICE, configData.uiS.price2TextColor, displayText, textSize, $"{anchorMin.x} {anchorMin.y + i * x}", $"{anchorMax.x} {anchorMin.y + (i + 1) * x}", TextAnchor.MiddleLeft);
                    if (configData.uiS.imageEnabled && _rt.ImageLibrary != null) {
                        var image = itemInfo.HasValue && !string.IsNullOrEmpty(itemInfo.Value.ImageId.Value) ? itemInfo.Value.ImageId.Value : GetItemImage(entry.Key);
                        if (!string.IsNullOrEmpty(image)) {
                            UI.CreateImage(ref container, UINAME_PRICE, image, $"{anchorMax.x - configData.uiS.rightDistance - x * configData.uiS.imageScale} {anchorMin.y + i * x}", $"{anchorMax.x - configData.uiS.rightDistance} {anchorMin.y + (i + 1) * x}");
                        }
                    }
                    i++;
                }
            }
            CuiHelper.DestroyUi(player, UINAME_PRICE);
            CuiHelper.AddUi(player, container);
        }
        private static void UpdateRefundUI(BasePlayer player, BaseEntity targetEntity, RemovableEntityInfo? info, bool useRefund) {
            Dictionary<string, int> refund = null;
            if (useRefund) {
                refund = _rt.GetRefund(targetEntity, info);
            }
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_REFUND, configData.uiS.refundBackgroundColor, configData.uiS.refundAnchorMin, configData.uiS.refundAnchorMax);
            UI.CreateLabel(ref container, UINAME_REFUND, configData.uiS.refundTextColor, _rt.Lang("Refund", player.UserIDString), configData.uiS.refundTextSize, configData.uiS.refundTextAnchorMin, configData.uiS.refundTextAnchorMax, TextAnchor.MiddleLeft);
            if (refund == null || refund.Count == 0) {
                UI.CreateLabel(ref container, UINAME_REFUND, configData.uiS.refund2TextColor, _rt.Lang("Nothing", player.UserIDString), configData.uiS.refund2TextSize, configData.uiS.refund2TextAnchorMin, configData.uiS.refund2TextAnchorMax, TextAnchor.MiddleLeft);
            }
            else {
                var anchorMin = configData.uiS.Refund2TextAnchorMin;
                var anchorMax = configData.uiS.Refund2TextAnchorMax;
                float x = (anchorMax.y - anchorMin.y) / refund.Count;
                int textSize = configData.uiS.refund2TextSize - refund.Count;
                string language = _rt.lang.GetLanguage(player.UserIDString);
                int i = 0;
                foreach (var entry in refund) {
                    var itemInfo = info?.Refund[entry.Key];
                    string displayText = !itemInfo.HasValue || string.IsNullOrEmpty(itemInfo.Value.DisplayName.Value) ? $"{GetDisplayNameByPriceName(language, entry.Key)} x{entry.Value}" : $"{itemInfo.Value.DisplayName.Value} x{itemInfo.Value.Amount.Value}";
                    UI.CreateLabel(ref container, UINAME_REFUND, configData.uiS.refund2TextColor, displayText, textSize, $"{anchorMin.x} {anchorMin.y + i * x}", $"{anchorMax.x} {anchorMin.y + (i + 1) * x}", TextAnchor.MiddleLeft);
                    if (configData.uiS.imageEnabled && _rt.ImageLibrary != null) {
                        var image = itemInfo.HasValue && !string.IsNullOrEmpty(itemInfo.Value.ImageId.Value) ? itemInfo.Value.ImageId.Value : GetItemImage(entry.Key);
                        if (!string.IsNullOrEmpty(image)) {
                            UI.CreateImage(ref container, UINAME_REFUND, image, $"{anchorMax.x - configData.uiS.rightDistance - x * configData.uiS.imageScale} {anchorMin.y + i * x}", $"{anchorMax.x - configData.uiS.rightDistance} {anchorMin.y + (i + 1) * x}");
                        }
                    }
                    i++;
                }
            }
            CuiHelper.DestroyUi(player, UINAME_REFUND);
            CuiHelper.AddUi(player, container);
        }
        private static void UpdateAuthorizationUI(BasePlayer player, RemoveType removeType, BaseEntity targetEntity, RemovableEntityInfo? info, bool shouldPay) {
            string reason;
            string color = _rt.CanRemoveEntity(player, removeType, targetEntity, info, shouldPay, out reason) ? configData.uiS.allowedBackgroundColor : configData.uiS.refusedBackgroundColor;
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_AUTH, color, configData.uiS.authorizationsAnchorMin, configData.uiS.authorizationsAnchorMax);
            UI.CreateLabel(ref container, UINAME_AUTH, configData.uiS.authorizationsTextColor, reason, configData.uiS.authorizationsTextSize, configData.uiS.authorizationsTextAnchorMin, configData.uiS.authorizationsTextAnchorMax, TextAnchor.MiddleLeft);
            CuiHelper.DestroyUi(player, UINAME_AUTH);
            CuiHelper.AddUi(player, container);
        }
        private static void DestroyAllUI(BasePlayer player) {
            CuiHelper.DestroyUi(player, UINAME_CROSSHAIR);
            CuiHelper.DestroyUi(player, UINAME_MAIN);
        }
        private static void DestroyUiEntry(BasePlayer player, UiEntry uiEntry) {
            switch (uiEntry) {
                case UiEntry.Entity : CuiHelper.DestroyUi(player, UINAME_ENTITY);
                return;
                case UiEntry.Price : CuiHelper.DestroyUi(player, UINAME_PRICE);
                return;
                case UiEntry.Refund : CuiHelper.DestroyUi(player, UINAME_REFUND);
                return;
                case UiEntry.Auth : CuiHelper.DestroyUi(player, UINAME_AUTH);
                return;
            }
        }
#endregion UI
#region ToolRemover Component
#region Tool Helpers
        private static bool IsSpecificTool(BasePlayer player) {
            var heldItem = player.GetActiveItem();
            return IsSpecificTool(heldItem);
        }
        private static bool IsSpecificTool(Item heldItem) {
            if (heldItem != null && heldItem.info.shortname == configData.removerModeS.specificToolShortname) {
                if (configData.removerModeS.specificToolSkin < 0) return true;
                return heldItem.skin == (ulong)configData.removerModeS.specificToolSkin;
            }
            return false;
        }
        private static bool IsMeleeTool(BasePlayer player) {
            var heldItem = player.GetActiveItem();
            return IsMeleeTool(heldItem);
        }
        private static bool IsMeleeTool(Item heldItem) {
            if (heldItem != null && heldItem.info.shortname == configData.removerModeS.meleeHitItemShortname) {
                if (configData.removerModeS.meleeHitModeSkin < 0) return true;
                return heldItem.skin == (ulong)configData.removerModeS.meleeHitModeSkin;
            }
            return false;
        }
#endregion Tool Helpers
        private class ToolRemover : FacepunchBehaviour {
            private const float MinInterval = 0.2f;
            public int currentRemoved {
                get;
                set;
            }
            public BaseEntity hitEntity {
                get;
                set;
            }
            public bool canOverride {
                get;
                private set;
            }
            public BasePlayer player {
                get;
                private set;
            }
            public RemoveType removeType {
                get;
                private set;
            }
            private bool _resetTime;
            private bool _shouldPay;
            private bool _shouldRefund;
            private int _removeTime;
            private int _maxRemovable;
            private float _distance;
            private float _removeInterval;
            private int _timeLeft;
            private float _lastRemove;
            private uint _currentItemId;
            private bool _disableInHand;
            private UiEntry _activeUiEntries;
            private Item _lastHeldItem;
            private BaseEntity _targetEntity;
            private void Awake() {
                player = GetComponent<BasePlayer>();
                _currentItemId = player.svActiveItemID;
                _disableInHand = _removeMode == RemoveMode.MeleeHit && configData.removerModeS.meleeHitDisableInHand || _removeMode == RemoveMode.SpecificTool && configData.removerModeS.specificToolDisableInHand;
                if (_disableInHand) {
                    _lastHeldItem = player.GetActiveItem();
                }
                if (_removeMode == RemoveMode.NoHeld) {
                    UnEquip();
                }
            }
            public void Init(RemoveType removeType, int removeTime, int maxRemovable, float distance, float removeInterval, bool shouldPay, bool shouldRefund, bool resetTime, bool canOverride) {
                this.removeType = removeType;
                this.canOverride = canOverride;
                _distance = distance;
                _resetTime = resetTime;
                _removeTime = _timeLeft = removeTime;
                _removeInterval = Mathf.Max(MinInterval, removeInterval);
                if (this.removeType == RemoveType.Normal) {
                    _maxRemovable = maxRemovable;
                    _shouldPay = shouldPay && configData.removeS.priceEnabled;
                    _shouldRefund = shouldRefund && configData.removeS.refundEnabled;
                    _rt.PrintDebug($"{player.displayName}({player.userID}) have Enabled the remover tool.");
                    Interface.CallHook("OnRemoverToolActivated", player);
                }
                else {
                    _maxRemovable = currentRemoved = 0;
                    _shouldPay = _shouldRefund = false;
                }
                DestroyAllUI(player);
                if (configData.uiS.showCrosshair) {
                    CreateCrosshairUI(player);
                }
                if (configData.uiS.enabled) {
                    CreateMainUI(player, this.removeType);
                }
                CancelInvoke(RemoveUpdate);
                InvokeRepeating(RemoveUpdate, 0f, 1f);
            }
            private void RemoveUpdate() {
                if (configData.uiS.enabled) {
                    _targetEntity = GetTargetEntity();
                    UpdateTimeLeftUI(player, removeType, _timeLeft, currentRemoved, _maxRemovable);
                    var info = removeType == RemoveType.Normal ? GetRemovableEntityInfo(_targetEntity, player) : null;
                    bool canShow = (info.HasValue || _targetEntity != null) && CanEntityBeDisplayed(_targetEntity, player);
                    if (HandleUiEntry(UiEntry.Entity, canShow)) {
                        UpdateEntityUI(player, _targetEntity, info);
                    }
                    if (removeType == RemoveType.Normal) {
                        if (configData.uiS.authorizationEnabled) {
                            if (HandleUiEntry(UiEntry.Auth, canShow)) {
                                UpdateAuthorizationUI(player, removeType, _targetEntity, info, _shouldPay);
                            }
                        }
                        if (configData.uiS.priceEnabled || configData.uiS.refundEnabled) {
                            canShow = canShow && (info.HasValue || HasEntityEnabled(_targetEntity));
                            if (configData.uiS.priceEnabled) {
                                if (HandleUiEntry(UiEntry.Price, canShow)) {
                                    UpdatePriceUI(player, _targetEntity, info, _shouldPay);
                                }
                            }
                            if (configData.uiS.refundEnabled) {
                                if (HandleUiEntry(UiEntry.Refund, canShow)) {
                                    UpdateRefundUI(player, _targetEntity, info, _shouldRefund);
                                }
                            }
                        }
                    }
                }
                if (_timeLeft-- <= 0) {
                    DisableTool();
                }
            }
            private BaseEntity GetTargetEntity() {
                RaycastHit hitInfo;
                return Physics.Raycast(player.eyes.HeadRay(), out hitInfo, _distance, LAYER_TARGET) ? hitInfo.GetEntity() : null;
            }
            private void Update() {
                if (player == null || !player.IsConnected || !player.CanInteract()) {
                    DisableTool();
                    return;
                }
                if (player.svActiveItemID != _currentItemId) {
                    if (_disableInHand) {
                        var heldItem = player.GetActiveItem();
                        if (_removeMode == RemoveMode.MeleeHit && IsMeleeTool(_lastHeldItem) && !IsMeleeTool(heldItem) || _removeMode == RemoveMode.SpecificTool && IsSpecificTool(_lastHeldItem) && !IsSpecificTool(heldItem)) {
                            DisableTool();
                            return;
                        }
                        _lastHeldItem = heldItem;
                    }
                    if (_removeMode == RemoveMode.NoHeld) {
                        if (player.svActiveItemID != 0) {
                            if (configData.removerModeS.noHeldDisableInHand) {
                                DisableTool();
                                return;
                            }
                            UnEquip();
                        }
                    }
                    _currentItemId = player.svActiveItemID;
                }
                if (Time.realtimeSinceStartup - _lastRemove >= _removeInterval) {
                    if (_removeMode == RemoveMode.MeleeHit) {
                        if (hitEntity == null) return;
                        _targetEntity = hitEntity;
                        hitEntity = null;
                    }
                    else {
                        if (!player.serverInput.IsDown(_removeButton)) {
                            return;
                        }
                        if (_removeMode == RemoveMode.SpecificTool && !IsSpecificTool(player)) {
                            //rt.Print(player,rt.Lang("UsageOfRemove",player.UserIDString));
                            return;
                        }
                        _targetEntity = GetTargetEntity();
                    }
                    if (_rt.TryRemove(player, _targetEntity, removeType, _shouldPay, _shouldRefund)) {
                        if (_resetTime) {
                            _timeLeft = _removeTime;
                        }
                        if (removeType == RemoveType.Normal || removeType == RemoveType.Admin) {
                            currentRemoved++;
                        }
                        if (configData.globalS.startCooldownOnRemoved && removeType == RemoveType.Normal) {
                            _rt._cooldownTimes[player.userID] = Time.realtimeSinceStartup;
                        }
                    }
                    _lastRemove = Time.realtimeSinceStartup;
                }
                if (removeType == RemoveType.Normal && _maxRemovable > 0 && currentRemoved >= _maxRemovable) {
                    _rt.Print(player, _rt.Lang("EntityLimit", player.UserIDString, _maxRemovable));
                    DisableTool(false);
                }
                ;
            }
            private void UnEquip() {
                //player.lastReceivedTick.activeItem = 0;
                var activeItem = player.GetActiveItem();
                if (activeItem?.GetHeldEntity() is HeldEntity) {
                    var slot = activeItem.position;
                    activeItem.SetParent(null);
                    player.Invoke(() => {
                        if (activeItem == null || !activeItem.IsValid()) return;
                        if (player.inventory.containerBelt.GetSlot(slot) == null) {
                            activeItem.position = slot;
                            activeItem.SetParent(player.inventory.containerBelt);
                        }
                        else player.GiveItem(activeItem);
                    }
                    , 0.2f);
                }
            }
            private bool HandleUiEntry(UiEntry uiEntry, bool canShow) {
                if (canShow) {
                    _activeUiEntries |= uiEntry;
                    return true;
                }
                if (_activeUiEntries.HasFlag(uiEntry)) {
                    _activeUiEntries &= ~uiEntry;
                    DestroyUiEntry(player, uiEntry);
                }
                return false;
            }
            public void DisableTool(bool showMessage = true) {
                if (showMessage) {
                    if (_rt != null && player != null && player.IsConnected) {
                        _rt.Print(player, _rt.Lang("ToolDisabled", player.UserIDString));
                    }
                }
                if (removeType == RemoveType.Normal) {
                    if (_rt != null && player != null) {
                        _rt.PrintDebug($"{player.displayName}({player.userID}) have Disabled the remover tool.");
                    }
                    Interface.CallHook("OnRemoverToolDeactivated", player);
                }
                DestroyAllUI(player);
                Destroy(this);
            }
            private void OnDestroy() {
                if (_rt != null && removeType == RemoveType.Normal) {
                    if (configData != null && !configData.globalS.startCooldownOnRemoved) {
                        _rt._cooldownTimes[player.userID] = Time.realtimeSinceStartup;
                    }
                }
            }
        }
#endregion ToolRemover Component
#region TryRemove
        private bool TryRemove(BasePlayer player, BaseEntity targetEntity, RemoveType removeType, bool shouldPay, bool shouldRefund) {
            if (targetEntity == null) {
                Print(player, Lang("NotFoundOrFar", player.UserIDString));
                return false;
            }
            if (targetEntity.IsDestroyed) {
                Print(player, Lang("InvalidEntity", player.UserIDString));
// ... [Code preview truncated due to length. Full source in attached file] ...

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