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

FREE RemoverTool : 4.3.40 4.3.40

Нет прав для скачивания
C#:
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 ProtoBuf;
using Rust;
using UnityEngine;
using VLB;
using Random = UnityEngine.Random;
namespace Oxide.Plugins {
    [Info("Remover Tool", "Reneb/Fuji/Arainrr/Tryhard", "4.3.40", 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 RemoverTool _instance;
        private static BUTTON _removeButton;
        private static RemoveMode _removeMode;
        private readonly object _false = false;
        private bool _configChanged;
        private bool _removeOverride;
        private Coroutine _removeAllCoroutine;
        private Coroutine _removeStructureCoroutine;
        private Coroutine _removeExternalCoroutine;
        private Coroutine _removePlayerEntityCoroutine;
        private StringBuilder _debugStringBuilder;
        private Hash<ulong, 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() {
            _instance = this;
            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(OnRaidBlock));
            Unsubscribe(nameof(OnCombatBlock));
            foreach (var perm in _configData.permission.Keys) {
                if (!permission.PermissionExists(perm, this)) {
                    permission.RegisterPermission(perm, this);
                }
            }
            cmd.AddChatCommand(_configData.chat.command, this, nameof(CmdRemove));
        }
        private void OnServerInitialized() {
            Initialize();
            UpdateConfig();
            LoadConfig();
            _removeMode = RemoveMode.None;
            if (_configData.removerMode.noHeldMode) {
                _removeMode = RemoveMode.NoHeld;
            }
            if (_configData.removerMode.meleeHitMode) {
                _removeMode = RemoveMode.MeleeHit;
            }
            if (_configData.removerMode.specificToolMode) {
                _removeMode = RemoveMode.SpecificTool;
            }
            if (_removeMode == RemoveMode.MeleeHit) {
                BaseMelee baseMelee;
                ItemDefinition itemDefinition;
                if (string.IsNullOrEmpty(_configData.removerMode.meleeHitItemShortname) || (itemDefinition = ItemManager.FindItemDefinition(_configData.removerMode.meleeHitItemShortname)) == null || (baseMelee = itemDefinition.GetComponent<ItemModEntity>()?.entityPrefab.Get()?.GetComponent<BaseMelee>()) == null) {
                    PrintError($"{_configData.removerMode.meleeHitItemShortname} is not an item shortname for a melee tool");
                    _removeMode = RemoveMode.None;
                }
                else {
                    Subscribe(baseMelee is Hammer ? nameof(OnHammerHit) : nameof(OnPlayerAttack));
                }
            }
            if (_configData.noEscape.useRaidBlocker) {
                Subscribe(nameof(OnRaidBlock));
            }
            if (_configData.noEscape.useCombatBlocker) {
                Subscribe(nameof(OnCombatBlock));
            }
            if (_configData.global.entityTimeLimit) {
                _entitySpawnedTimes = new Hash<ulong, float>();
                Subscribe(nameof(OnEntitySpawned));
                Subscribe(nameof(OnEntityKill));
            }
            if (_configData.global.logToFile) {
                _debugStringBuilder = new StringBuilder();
            }
            if (_removeMode == RemoveMode.MeleeHit && _configData.removerMode.meleeHitEnableInHand || _removeMode == RemoveMode.SpecificTool && _configData.removerMode.specificToolEnableInHand) {
                Subscribe(nameof(OnActiveItemChanged));
            }
            if (!Enum.TryParse(_configData.global.removeButton, true, out _removeButton) || !Enum.IsDefined(typeof(BUTTON), _removeButton)) {
                PrintError($"{_configData.global.removeButton} is an invalid button. The remove button has been changed to 'FIRE_PRIMARY'.");
                _removeButton = BUTTON.FIRE_PRIMARY;
                _configData.global.removeButton = _removeButton.ToString();
                SaveConfig();
            }
            if (ImageLibrary != null) {
                foreach (var image in _configData.imageUrls) {
                    AddImageToLibrary(image.Value, image.Key);
                }
                if (_configData.ui.showCrosshair) {
                    AddImageToLibrary(_configData.ui.crosshairImageUrl, UINAME_CROSSHAIR);
                }
            }
        }
        private void Unload() {
            // if (_configChanged)
            // {
            //     SaveConfig();
            // }
            SaveDebug();
            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();
            }
            _configData = null;
            _instance = null;
        }
        private void OnServerSave() {
            if (_configChanged) {
                _configChanged = false;
                timer.Once(Random.Range(0f, 60f), SaveConfig);
            }
            if (_configData.global.logToFile) {
                timer.Once(Random.Range(0f, 60f), SaveDebug);
            }
            if (_configData.global.entityTimeLimit && _entitySpawnedTimes != null) {
                var currentTime = Time.realtimeSinceStartup;
                foreach (var entry in _entitySpawnedTimes.ToArray()) {
                    if (currentTime - entry.Value > _configData.global.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.Value] = Time.realtimeSinceStartup;
        }
        private void OnEntityKill(BaseEntity entity) {
            if (entity == null || entity.net == null) {
                return;
            }
            _entitySpawnedTimes.Remove(entity.net.ID.Value);
        }
        private object OnPlayerAttack(BasePlayer player, HitInfo info) {
            return 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);
            }
        }
#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) {
            return _configData.removeType[removeType].displayName;
        }
        private static void DropItemContainer(ItemContainer itemContainer, Vector3 position, Quaternion rotation) {
            itemContainer?.Drop(PREFAB_ITEM_DROP, position, rotation, 0);
        }
        private static bool IsExternalWall(StabilityEntity stabilityEntity) {
            return 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.remove.entity.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.remove.validConstruction.TryGetValue(buildingBlock.grade, out valid) && valid) {
                    return true;
                }
            }
            EntitySettings entitySettings;
            if (_configData.remove.entity.TryGetValue(entity.ShortPrefabName, out entitySettings) && entitySettings.enabled) {
                return true;
            }
            return false;
        }
        private static bool IsRemovableEntity(BaseEntity entity) {
            if (_instance._shortPrefabNameToDeployable.ContainsKey(entity.ShortPrefabName) || _instance._prefabNameToStructure.ContainsKey(entity.PrefabName) || _configData.remove.entity.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 (_instance.ImageLibrary == null) {
                return null;
            }
            if (_configData.imageUrls.ContainsKey(name)) {
                return GetImageFromLibrary(name);
            }
            if (_instance._itemShortNameToItemId.ContainsKey(name)) {
                return GetImageFromLibrary(name);
            }
            return null;
        }
        private static string GetItemImage(string shortname) {
            if (_instance.ImageLibrary == null) {
                return null;
            }
            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} ({target.ShortPrefabName})";
                return;
            }
            EntitySettings entitySettings;
            if (_configData.remove.entity.TryGetValue(entity.ShortPrefabName, out entitySettings)) {
                imageName = entity.ShortPrefabName;
                displayName = _instance.GetDeployableDisplayName(player, entity.ShortPrefabName, entitySettings.displayName);
                return;
            }
            string structureName;
            if (_instance._prefabNameToStructure.TryGetValue(entity.PrefabName, out structureName)) {
                BuildingBlocksSettings buildingBlockSettings;
                if (_configData.remove.buildingBlock.TryGetValue(structureName, out buildingBlockSettings)) {
                    imageName = structureName;
                    displayName = _instance.GetConstructionDisplayName(player, entity.PrefabName, buildingBlockSettings.displayName);
                    return;
                }
            }
            imageName = entity.ShortPrefabName;
            displayName = entity.ShortPrefabName;
        }
        private static string GetDisplayNameByCurrencyName(string language, string currencyName, long skinId) {
            var itemDefinition = ItemManager.FindItemDefinition(currencyName);
            if (itemDefinition != null) {
                var translationKey = $"{itemDefinition.shortname}_{skinId}";
                var translationValue = GetCurrencyDisplayName(translationKey, itemDefinition.displayName.english, true);
                if (skinId <= 0 || string.IsNullOrEmpty(translationValue)) {
                    var displayName = _instance.GetItemDisplayName(language, itemDefinition.shortname);
                    if (!string.IsNullOrEmpty(displayName)) {
                        return displayName;
                    }
                    return itemDefinition.displayName.english;
                }
                return GetCurrencyDisplayName(translationKey, itemDefinition.displayName.english);
            }
            return GetCurrencyDisplayName(currencyName, currencyName);
        }
        private static string GetCurrencyDisplayName(string currencyName, string defaultName = null, bool readOnly = false) {
            string displayName;
            if (_configData.remove.displayNames.TryGetValue(currencyName, out displayName)) {
                return displayName;
            }
            if (!readOnly) {
                _configData.remove.displayNames.Add(currencyName, defaultName);
                _instance._configChanged = true;
            }
            return defaultName;
        }
        private static PermissionSettings GetPermissionSettings(BasePlayer player) {
            var priority = 0;
            PermissionSettings permissionSettings = null;
            foreach (var entry in _configData.permission) {
                if (entry.Value.priority >= priority && _instance.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) {
            return (bool)_instance.ImageLibrary.Call("AddImage", url, shortname.ToLower(), skin);
        }
        private static string GetImageFromLibrary(string shortname, ulong skin = 0, bool returnUrl = false) {
            return string.IsNullOrEmpty(shortname) ? null : (string)_instance.ImageLibrary.Call("GetImage", shortname.ToLower(), skin, returnUrl);
        }
#endregion Methods
#region NoEscape
        private void OnRaidBlock(BasePlayer player) {
            if (_configData.noEscape.useRaidBlocker) {
                // Print(player, Lang("RaidBlocked", player.UserIDString));
                player.GetComponent<ToolRemover>()?.DisableTool(false);
            }
        }
        private void OnCombatBlock(BasePlayer player) {
            if (_configData.noEscape.useCombatBlocker) {
                // Print(player, Lang("CombatBlocked", player.UserIDString));
                player.GetComponent<ToolRemover>()?.DisableTool(false);
            }
        }
        private bool IsPlayerBlocked(BasePlayer player, out string reason) {
            if (NoEscape != null) {
                if (_configData.noEscape.useRaidBlocker && IsRaidBlocked(player.UserIDString)) {
                    reason = Lang("RaidBlocked", player.UserIDString);
                    return true;
                }
                if (_configData.noEscape.useCombatBlocker && IsCombatBlocked(player.UserIDString)) {
                    reason = Lang("CombatBlocked", player.UserIDString);
                    return true;
                }
            }
            reason = null;
            return false;
        }
        private bool IsRaidBlocked(string playerID) {
            return (bool)NoEscape.Call("IsRaidBlocked", playerID);
        }
        private bool IsCombatBlocked(string playerID) {
            return (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 {
                            Color = color, Png = image
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = anchorMin, AnchorMax = anchorMax
                        }
                    }
                }
                );
            }
            public static void CreateImage(ref CuiElementContainer container, string panelName, int itemId, ulong skinId, string anchorMin, string anchorMax) {
                container.Add(new CuiPanel {
                    Image = {
                        ItemId = itemId, SkinId = skinId
                    }
                    , RectTransform = {
                        AnchorMin = anchorMin, AnchorMax = anchorMax
                    }
                    , CursorEnabled = false
                }
                , panelName);
            }
        }
        [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 (_instance.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.ui.crosshairAnchorMin, _configData.ui.crosshairAnchorMax, _configData.ui.crosshairOffsetMin, _configData.ui.crosshairOffsetMax);
            UI.CreateImage(ref container, UINAME_CROSSHAIR, image, "0 0", "1 1", _configData.ui.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.ui.removerToolBackgroundColor, _configData.ui.removerToolAnchorMin, _configData.ui.removerToolAnchorMax, _configData.ui.removerToolOffsetMin, _configData.ui.removerToolOffsetMax);
            UI.CreatePanel(ref container, UINAME_MAIN, _configData.ui.removeBackgroundColor, _configData.ui.removeAnchorMin, _configData.ui.removeAnchorMax);
            UI.CreateLabel(ref container, UINAME_MAIN, _configData.ui.removeTextColor, _instance.Lang("RemoverToolType", player.UserIDString, GetRemoveTypeName(removeType)), _configData.ui.removeTextSize, _configData.ui.removeTextAnchorMin, _configData.ui.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.ui.timeLeftBackgroundColor, _configData.ui.timeLeftAnchorMin, _configData.ui.timeLeftAnchorMax);
            UI.CreateLabel(ref container, UINAME_TIMELEFT, _configData.ui.timeLeftTextColor, _instance.Lang("TimeLeft", player.UserIDString, timeLeft, removeType == RemoveType.Normal || removeType == RemoveType.Admin ? maxRemovable == 0 ? $"{currentRemoved} / {_instance.Lang("Unlimit", player.UserIDString)}" : $"{currentRemoved} / {maxRemovable}" : currentRemoved.ToString()), _configData.ui.timeLeftTextSize, _configData.ui.timeLeftTextAnchorMin, _configData.ui.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.ui.entityBackgroundColor, _configData.ui.entityAnchorMin, _configData.ui.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.ui.entityTextColor, displayName, _configData.ui.entityTextSize, _configData.ui.entityTextAnchorMin, _configData.ui.entityTextAnchorMax, TextAnchor.MiddleLeft);
            if (_configData.ui.entityImageEnabled) {
                var imageAnchorMin = _configData.ui.entityImageAnchorMin;
                var imageAnchorMax = _configData.ui.entityImageAnchorMax;
                if (info.HasValue && !string.IsNullOrEmpty(info.Value.ImageId.Value)) {
                    var image = info.Value.ImageId.Value;
                    if (!string.IsNullOrEmpty(image)) {
                        UI.CreateImage(ref container, UINAME_ENTITY, image, imageAnchorMin, imageAnchorMax);
                    }
                }
                else if (!string.IsNullOrEmpty(imageName)) {
                    string shortname;
                    int itemId;
                    if (_instance._shortPrefabNameToDeployable.TryGetValue(imageName, out shortname) && _instance._itemShortNameToItemId.TryGetValue(shortname, out itemId)) {
                        UI.CreateImage(ref container, UINAME_ENTITY, itemId, targetEntity.skinID, imageAnchorMin, imageAnchorMax);
                    }
                    else {
                        var image = GetEntityImage(imageName);
                        if (!string.IsNullOrEmpty(image)) {
                            UI.CreateImage(ref container, UINAME_ENTITY, image, imageAnchorMin, imageAnchorMax);
                        }
                    }
                }
            }
            CuiHelper.DestroyUi(player, UINAME_ENTITY);
            CuiHelper.AddUi(player, container);
        }
        private static void UpdatePriceUI(BasePlayer player, BaseEntity targetEntity, RemovableEntityInfo? info, bool usePrice) {
            Dictionary<string, CurrencyInfo> price = null;
            if (usePrice) {
                price = _instance.GetPrice(targetEntity, info);
            }
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_PRICE, _configData.ui.priceBackgroundColor, _configData.ui.priceAnchorMin, _configData.ui.priceAnchorMax);
            UI.CreateLabel(ref container, UINAME_PRICE, _configData.ui.priceTextColor, _instance.Lang("Price", player.UserIDString), _configData.ui.priceTextSize, _configData.ui.priceTextAnchorMin, _configData.ui.priceTextAnchorMax, TextAnchor.MiddleLeft);
            if (price == null || price.Count == 0) {
                UI.CreateLabel(ref container, UINAME_PRICE, _configData.ui.price2TextColor, _instance.Lang("Free", player.UserIDString), _configData.ui.price2TextSize, _configData.ui.price2TextAnchorMin, _configData.ui.price2TextAnchorMax, TextAnchor.MiddleLeft);
            }
            else {
                var anchorMin = _configData.ui.Price2TextAnchorMin;
                var anchorMax = _configData.ui.Price2TextAnchorMax;
                var x = (anchorMax.y - anchorMin.y) / price.Count;
                var textSize = _configData.ui.price2TextSize - price.Count;
                var language = _instance.lang.GetLanguage(player.UserIDString);
                var i = 0;
                foreach (var entry in price) {
                    var externalItemInfo = info?.Price[entry.Key];
                    var displayText = !externalItemInfo.HasValue || string.IsNullOrEmpty(externalItemInfo.Value.DisplayName.Value) ? $"{GetDisplayNameByCurrencyName(language, entry.Key, entry.Value.SkinId)}  <color=#00B5FF>x{entry.Value.Amount}</color>" : $"{externalItemInfo.Value.DisplayName.Value} x{externalItemInfo.Value.Amount.Value}";
                    UI.CreateLabel(ref container, UINAME_PRICE, _configData.ui.price2TextColor, displayText, textSize, $"{anchorMin.x} {anchorMin.y + i * x}", $"{anchorMax.x} {anchorMin.y + (i + 1) * x}", TextAnchor.MiddleLeft);
                    if (_configData.ui.imageEnabled) {
                        var imageAnchorMin = $"{anchorMax.x - _configData.ui.rightDistance - x * _configData.ui.imageScale} {anchorMin.y + i * x}";
                        var imageAnchorMax = $"{anchorMax.x - _configData.ui.rightDistance} {anchorMin.y + (i + 1) * x}";
                        if (externalItemInfo.HasValue && !string.IsNullOrEmpty(externalItemInfo.Value.ImageId.Value)) {
                            var image = externalItemInfo.Value.ImageId.Value;
                            if (!string.IsNullOrEmpty(image)) {
                                UI.CreateImage(ref container, UINAME_PRICE, image, imageAnchorMin, imageAnchorMax);
                            }
                        }
                        else {
                            int itemId;
                            if (_instance._itemShortNameToItemId.TryGetValue(entry.Key, out itemId)) {
                                UI.CreateImage(ref container, UINAME_PRICE, itemId, entry.Value.SkinId >= 0 ? (ulong)entry.Value.SkinId : 0, imageAnchorMin, imageAnchorMax);
                            }
                            else {
                                var image = GetItemImage(entry.Key);
                                if (!string.IsNullOrEmpty(image)) {
                                    UI.CreateImage(ref container, UINAME_PRICE, image, imageAnchorMin, imageAnchorMax);
                                }
                            }
                        }
                    }
                    i++;
                }
            }
            CuiHelper.DestroyUi(player, UINAME_PRICE);
            CuiHelper.AddUi(player, container);
        }
        private static void UpdateRefundUI(BasePlayer player, BaseEntity targetEntity, RemovableEntityInfo? info, bool useRefund) {
            Dictionary<string, CurrencyInfo> refund = null;
            if (useRefund) {
                refund = _instance.GetRefund(targetEntity, info);
            }
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_REFUND, _configData.ui.refundBackgroundColor, _configData.ui.refundAnchorMin, _configData.ui.refundAnchorMax);
            UI.CreateLabel(ref container, UINAME_REFUND, _configData.ui.refundTextColor, _instance.Lang("Refund", player.UserIDString), _configData.ui.refundTextSize, _configData.ui.refundTextAnchorMin, _configData.ui.refundTextAnchorMax, TextAnchor.MiddleLeft);
            if (refund == null || refund.Count == 0) {
                UI.CreateLabel(ref container, UINAME_REFUND, _configData.ui.refund2TextColor, _instance.Lang("Nothing", player.UserIDString), _configData.ui.refund2TextSize, _configData.ui.refund2TextAnchorMin, _configData.ui.refund2TextAnchorMax, TextAnchor.MiddleLeft);
            }
            else {
                var anchorMin = _configData.ui.Refund2TextAnchorMin;
                var anchorMax = _configData.ui.Refund2TextAnchorMax;
                var x = (anchorMax.y - anchorMin.y) / refund.Count;
                var textSize = _configData.ui.refund2TextSize - refund.Count;
                var language = _instance.lang.GetLanguage(player.UserIDString);
                var i = 0;
                foreach (var entry in refund) {
                    var externalItemInfo = info?.Refund[entry.Key];
                    var displayText = !externalItemInfo.HasValue || string.IsNullOrEmpty(externalItemInfo.Value.DisplayName.Value) ? $"{GetDisplayNameByCurrencyName(language, entry.Key, entry.Value.SkinId)}  <color=#00B5FF>x{entry.Value.Amount}</color>" : $"{externalItemInfo.Value.DisplayName.Value} x{externalItemInfo.Value.Amount.Value}";
                    UI.CreateLabel(ref container, UINAME_REFUND, _configData.ui.refund2TextColor, displayText, textSize, $"{anchorMin.x} {anchorMin.y + i * x}", $"{anchorMax.x} {anchorMin.y + (i + 1) * x}", TextAnchor.MiddleLeft);
                    if (_configData.ui.imageEnabled) {
                        var imageAnchorMin = $"{anchorMax.x - _configData.ui.rightDistance - x * _configData.ui.imageScale} {anchorMin.y + i * x}";
                        var imageAnchorMax = $"{anchorMax.x - _configData.ui.rightDistance} {anchorMin.y + (i + 1) * x}";
                        if (externalItemInfo.HasValue && !string.IsNullOrEmpty(externalItemInfo.Value.ImageId.Value)) {
                            var image = externalItemInfo.Value.ImageId.Value;
                            if (!string.IsNullOrEmpty(image)) {
                                UI.CreateImage(ref container, UINAME_REFUND, image, imageAnchorMin, imageAnchorMax);
                            }
                        }
                        else {
                            int itemId;
                            if (_instance._itemShortNameToItemId.TryGetValue(entry.Key, out itemId)) {
                                UI.CreateImage(ref container, UINAME_REFUND, itemId, entry.Value.SkinId >= 0 ? (ulong)entry.Value.SkinId : 0, imageAnchorMin, imageAnchorMax);
                            }
                            else {
                                var image = GetItemImage(entry.Key);
                                if (!string.IsNullOrEmpty(image)) {
                                    UI.CreateImage(ref container, UINAME_REFUND, image, imageAnchorMin, imageAnchorMax);
                                }
                            }
                        }
                    }
                    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;
            var color = _instance.CanRemoveEntity(player, removeType, targetEntity, info, shouldPay, out reason) ? _configData.ui.allowedBackgroundColor : _configData.ui.refusedBackgroundColor;
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_AUTH, color, _configData.ui.authorizationsAnchorMin, _configData.ui.authorizationsAnchorMax);
            UI.CreateLabel(ref container, UINAME_AUTH, _configData.ui.authorizationsTextColor, reason, _configData.ui.authorizationsTextSize, _configData.ui.authorizationsTextAnchorMin, _configData.ui.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.removerMode.specificToolShortName) {
                if (_configData.removerMode.specificToolSkin < 0) {
                    return true;
                }
                return heldItem.skin == (ulong)_configData.removerMode.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.removerMode.meleeHitItemShortname) {
                if (_configData.removerMode.meleeHitModeSkin < 0) {
                    return true;
                }
                return heldItem.skin == (ulong)_configData.removerMode.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 ItemId _currentItemId;
            private bool _disableInHand;
            private Item _lastHeldItem;
            private BaseEntity _targetEntity;
            private UiEntry _activeUiEntries;
            private void Awake() {
                Player = GetComponent<BasePlayer>();
                _currentItemId = Player.svActiveItemID;
                _disableInHand = _removeMode == RemoveMode.MeleeHit && _configData.removerMode.meleeHitDisableInHand || _removeMode == RemoveMode.SpecificTool && _configData.removerMode.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) {
                RemoveType = removeType;
                CanOverride = canOverride;
                _distance = distance;
                _resetTime = resetTime;
                _removeTime = _timeLeft = removeTime;
                _removeInterval = Mathf.Max(MinInterval, removeInterval);
                if (RemoveType == RemoveType.Normal) {
                    _maxRemovable = maxRemovable;
                    _shouldPay = shouldPay && _configData.remove.priceEnabled;
                    _shouldRefund = shouldRefund && _configData.remove.refundEnabled;
                    _instance.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.ui.showCrosshair) {
                    CreateCrosshairUI(Player);
                }
                if (_configData.ui.enabled) {
                    CreateMainUI(Player, RemoveType);
                }
                CancelInvoke(RemoveUpdate);
                InvokeRepeating(RemoveUpdate, 0f, 1f);
            }
            private void RemoveUpdate() {
                if (_configData.ui.enabled) {
                    _targetEntity = GetTargetEntity();
                    UpdateTimeLeftUI(Player, RemoveType, _timeLeft, CurrentRemoved, _maxRemovable);
                    var info = RemoveType == RemoveType.Normal ? GetRemovableEntityInfo(_targetEntity, Player) : null;
                    var canShow = (info.HasValue || _targetEntity != null) && CanEntityBeDisplayed(_targetEntity, Player);
                    if (HandleUiEntry(UiEntry.Entity, canShow)) {
                        UpdateEntityUI(Player, _targetEntity, info);
                    }
                    if (RemoveType == RemoveType.Normal) {
                        if (_configData.ui.authorizationEnabled) {
                            if (HandleUiEntry(UiEntry.Auth, canShow)) {
                                UpdateAuthorizationUI(Player, RemoveType, _targetEntity, info, _shouldPay);
                            }
                        }
                        if (_configData.ui.priceEnabled || _configData.ui.refundEnabled) {
                            canShow = canShow && (info.HasValue || HasEntityEnabled(_targetEntity));
                            if (_configData.ui.priceEnabled) {
                                if (HandleUiEntry(UiEntry.Price, canShow)) {
                                    UpdatePriceUI(Player, _targetEntity, info, _shouldPay);
                                }
                            }
                            if (_configData.ui.refundEnabled) {
                                if (HandleUiEntry(UiEntry.Refund, canShow)) {
                                    UpdateRefundUI(Player, _targetEntity, info, _shouldRefund);
                                }
                            }
                        }
                    }
                }
                if (_timeLeft-- <= 0) {
                    DisableTool();
                }
            }
            private BaseEntity GetTargetEntity() {
                BaseEntity target = null;
                List<RaycastHit> hitInfos = Pool.GetList<RaycastHit>();
                GamePhysics.TraceAll(Player.eyes.HeadRay(), 0f, hitInfos, _distance, LAYER_TARGET);
                foreach (var hitInfo in hitInfos) {
                    var hitEntity = hitInfo.GetEntity();
                    if (hitEntity != null) {
                        if (target == null) {
                            target = hitEntity;
                        }
                        else if (hitEntity.GetParentEntity() == target) {
                            target = hitEntity;
                            break;
                        }
                    }
                }
            
// ... [Code preview truncated due to length. Full source in attached file] ...

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