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

FREE RemoverTool : 4.3.15 4.3.15

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust;
using Oxide.Game.Rust.Cui;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Remover Tool", "Reneb/Fuji/Arainrr", "4.3.15", ResourceId = 651)]
    [Description("Building and entity removal tool")]
    public class RemoverTool : RustPlugin {
#region Fields
        [PluginReference]
        private readonly Plugin Friends, ServerRewards, Clans, Economics, ImageLibrary;
        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 readonly static int LAYER_ALL = LayerMask.GetMask("Construction", "Deployed", "Default");
        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 readonly Hash<uint, float> entitySpawnedTimes = new Hash<uint, float>();
        private readonly Hash<ulong, float> cooldownTimes = new Hash<ulong, float>();
        private enum RemoveMode {
            None, NoHeld, HammerHit, SpecificTool
        }
        private enum RemoveType {
            All, Admin, Normal, External, Structure
        }
#endregion Fields
#region Oxide Hooks
        private void Init() {
            rt = 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);
            cmd.AddChatCommand(configData.chatS.command, this, nameof(CmdRemove));
            foreach (var perm in configData.permS.Keys) {
                if (!permission.PermissionExists(perm, this)) permission.RegisterPermission(perm, this);
            }
            Unsubscribe(nameof(OnEntityDeath));
            Unsubscribe(nameof(OnHammerHit));
            Unsubscribe(nameof(OnEntitySpawned));
            Unsubscribe(nameof(OnEntityKill));
        }
        private void OnServerInitialized() {
            Initialize();
            UpdateConfig();
            removeMode = RemoveMode.None;
            if (configData.removerModeS.noHeldMode) removeMode = RemoveMode.NoHeld;
            if (configData.removerModeS.hammerHitMode) removeMode = RemoveMode.HammerHit;
            if (configData.removerModeS.specificTool) removeMode = RemoveMode.SpecificTool;
            if (removeMode == RemoveMode.HammerHit) Subscribe(nameof(OnHammerHit));
            if (configData.raidS.enabled) Subscribe(nameof(OnEntityDeath));
            if (configData.globalS.entityTimeLimit) {
                Subscribe(nameof(OnEntitySpawned));
                Subscribe(nameof(OnEntityKill));
            }
            if (!Enum.TryParse(configData.globalS.removeButton, true, out 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);
            }
        }
        private void Unload() {
            if (removeAllCoroutine != null) ServerMgr.Instance.StopCoroutine(removeAllCoroutine);
            if (removeStructureCoroutine != null) ServerMgr.Instance.StopCoroutine(removeStructureCoroutine);
            if (removeExternalCoroutine != null) ServerMgr.Instance.StopCoroutine(removeExternalCoroutine);
            foreach (var player in BasePlayer.activePlayerList) {
                var toolRemover = player.GetComponent<ToolRemover>();
                if (toolRemover != null) UnityEngine.Object.Destroy(toolRemover);
                DestroyUI(player);
            }
            rt = null;
            configData = null;
        }
        private void OnEntityDeath(BuildingBlock buildingBlock, HitInfo info) {
            if (buildingBlock == null || info == null) return;
            var attacker = info.InitiatorPlayer;
            if (attacker != null && attacker.userID.IsSteamId() && HasAccess(attacker, buildingBlock)) return;
            BlockRemove(buildingBlock);
        }
        private void OnEntitySpawned(BaseEntity entity) {
            if (entity == null || entity.net == null) return;
            if (!EntityCanBeSaved(entity)) return;
            entitySpawnedTimes[entity.net.ID] = Time.realtimeSinceStartup;
        }
        private void OnEntityKill(BaseEntity entity) {
            if (entity == null || entity.net == null) return;
            if (!EntityCanBeSaved(entity)) return;
            entitySpawnedTimes.Remove(entity.net.ID);
        }
        private object OnHammerHit(BasePlayer player, HitInfo info) {
            var toolRemover = player.GetComponent<ToolRemover>();
            if (toolRemover == null) return null;
            toolRemover.hitEntity = info.HitEntity;
            return false;
        }
#endregion Oxide Hooks
#region Initializing
        private readonly Dictionary<string, string> shorPrefabNameToDeployable = new Dictionary<string, string>();
        private readonly Dictionary<string, string> prefabNameToStructure = new Dictionary<string, string>();
        private readonly Dictionary<string, int> itemShortNameToItemID = new Dictionary<string, int>();
        private readonly HashSet<Construction> constructions = new HashSet<Construction>();
        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 = GameManager.server.FindPrefab(deployablePrefab)?.GetComponent<BaseEntity>()?.ShortPrefabName;
                if (!string.IsNullOrEmpty(shortPrefabName) && !shorPrefabNameToDeployable.ContainsKey(shortPrefabName)) shorPrefabNameToDeployable.Add(shortPrefabName, itemDefinition.shortname);
            }
            foreach (var entityPath in GameManifest.Current.entities) {
                var construction = PrefabAttribute.server.Find<Construction>(StringPool.Get(entityPath));
                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 dropPosition, Quaternion rotation) => itemContainer?.Drop(PREFAB_ITEM_DROP, dropPosition, rotation);
        private static bool IsExternalWall(StabilityEntity stabilityEntity) => stabilityEntity.ShortPrefabName.Contains("external");
        private static bool IsRemovableEntity(BaseEntity entity) => rt.shorPrefabNameToDeployable.ContainsKey(entity.ShortPrefabName) || rt.prefabNameToStructure.ContainsKey(entity.PrefabName) || configData.removeS.entityS.ContainsKey(entity.ShortPrefabName);
        private static bool EntityCanBeSaved(BaseEntity entity) {
            if (entity is BuildingBlock) return true;
            ConfigData.RemoveS.EntityS entityS;
            return configData.removeS.entityS.TryGetValue(entity.ShortPrefabName, out entityS) && entityS.enabled;
        }
        private static bool IsValidEntity(BaseEntity entity) {
            var buildingBlock = entity.GetComponent<BuildingBlock>();
            bool valid;
            if (buildingBlock != null && configData.removeS.validConstruction.TryGetValue(buildingBlock.grade, out valid) && valid) return true;
            ConfigData.RemoveS.EntityS entityS;
            if (configData.removeS.entityS.TryGetValue(entity.ShortPrefabName, out entityS) && entityS.enabled) return true;
            return false;
        }
        private static string GetEntityName(BaseEntity entity) {
            string entityName;
            if (rt.shorPrefabNameToDeployable.TryGetValue(entity.ShortPrefabName, out entityName)) return entityName;
            if (rt.prefabNameToStructure.TryGetValue(entity.PrefabName, out entityName)) return entityName;
            if (configData.removeS.entityS.ContainsKey(entity.ShortPrefabName)) return entity.ShortPrefabName;
            return string.Empty;
        }
        private static string GetEntityImage(string name) {
            if (configData.imageUrls.ContainsKey(name)) return GetImageFromLibrary(name);
            if (rt.itemShortNameToItemID.ContainsKey(name)) return GetImageFromLibrary(name);
            return string.Empty;
        }
        private static string GetItemImage(string shortname) {
            switch (shortname.ToLower()) {
                case "economics" : return GetImageFromLibrary("Economics");
                case "serverrewards" : return GetImageFromLibrary("ServerRewards");
            }
            return GetEntityImage(shortname);
        }
        private static string GetDisplayName(string name) {
            var shorPrefabName = rt.shorPrefabNameToDeployable.FirstOrDefault(x => x.Value == name).Key;
            if (string.IsNullOrEmpty(shorPrefabName)) shorPrefabName = name;
            ConfigData.RemoveS.EntityS entityS;
            if (configData.removeS.entityS.TryGetValue(shorPrefabName, out entityS)) return entityS.displayName;
            ConfigData.RemoveS.BuildingBlocksS buildingBlockS;
            if (configData.removeS.buildingBlockS.TryGetValue(name, out buildingBlockS)) return buildingBlockS.displayName;
            if (configData.displayNames.TryGetValue(name, out shorPrefabName)) return shorPrefabName;
            var itemDefinition = ItemManager.FindItemDefinition(name);
            if (itemDefinition != null) {
                configData.displayNames.Add(name, itemDefinition.displayName.english);
                name = itemDefinition.displayName.english;
            }
            else configData.displayNames.Add(name, name);
            rt.SaveConfig();
            return name;
        }
        private static Vector2 GetAnchor(string anchor) {
            string[] 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) ? string.Empty : (string)rt.ImageLibrary.Call("GetImage", shortname.ToLower(), skin, returnUrl);
#endregion Methods
#region UI
        private class UI {
            public static CuiElementContainer CreateElementContainer(string parent, string panelName, string backgroundColor, string anchorMin, string anchorMax, bool cursor = false) {
                return new CuiElementContainer() {
                    {
                        new CuiPanel {
                            Image = {
                                Color = backgroundColor
                            }
                            , RectTransform = {
                                AnchorMin = anchorMin, AnchorMax = anchorMax
                            }
                            , CursorEnabled = cursor
                        }
                        , new CuiElement().Parent = 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, CuiHelper.GetGuid());
            }
            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, CuiHelper.GetGuid());
            }
            public static void CreateImage(ref CuiElementContainer container, string panelName, string image, string anchorMin, string anchorMax) {
                CuiRawImageComponent imageComponent = new CuiRawImageComponent {
                    Sprite = "assets/content/textures/generic/fulltransparent.tga"
                }
                ;
                if (image.StartsWith("http") || image.StartsWith("www")) imageComponent.Url = image;
                else imageComponent.Png = image;
                container.Add(new CuiElement {
                    Name = CuiHelper.GetGuid(), Parent = panelName, Components = {
                        imageComponent, new CuiRectTransformComponent {
                            AnchorMin = anchorMin, AnchorMax = anchorMax
                        }
                    }
                }
                );
            }
        }
        private const string UINAME_MAIN = "RemoverTool";
        private const string UINAME_TIMELEFT = "RemoverToolTimeLeft";
        private const string UINAME_ENTITY = "RemoverToolEntity";
        private const string UINAME_PRICE = "RemoverToolPrice";
        private const string UINAME_REFUND = "RemoverToolRefund";
        private const string UINAME_AUTH = "RemoverToolAuth";
        private static void CreateUI(BasePlayer player, RemoveType removeType) {
            CuiHelper.DestroyUi(player, UINAME_MAIN);
            var container = UI.CreateElementContainer("Hud", UINAME_MAIN, configData.uiS.removerToolBackgroundColor, configData.uiS.removerToolAnchorMin, configData.uiS.removerToolAnchorMax);
            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.AddUi(player, container);
        }
        private static void TimeLeftUpdate(BasePlayer player, RemoveType removeType, int timeLeft, int currentRemoved, int maxRemovable) {
            CuiHelper.DestroyUi(player, UINAME_TIMELEFT);
            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.AddUi(player, container);
        }
        private static void EntityUpdate(BasePlayer player, BaseEntity targetEntity) {
            CuiHelper.DestroyUi(player, UINAME_ENTITY);
            if (targetEntity == null) return;
            var container = UI.CreateElementContainer(UINAME_MAIN, UINAME_ENTITY, configData.uiS.entityBackgroundColor, configData.uiS.entityAnchorMin, configData.uiS.entityAnchorMax);
            string name;
            var entityName = GetEntityName(targetEntity);
            if (string.IsNullOrEmpty(entityName)) {
                if (targetEntity is BasePlayer) name = $"{(targetEntity as BasePlayer).displayName} ({GetDisplayName(targetEntity.ShortPrefabName)})";
                else name = targetEntity.ShortPrefabName;
            }
            else name = GetDisplayName(entityName);
            UI.CreateLabel(ref container, UINAME_ENTITY, configData.uiS.entityTextColor, name, configData.uiS.entityTextSize, configData.uiS.entityTextAnchorMin, configData.uiS.entityTextAnchorMax, TextAnchor.MiddleLeft);
            if (configData.uiS.entityImageEnabled && !string.IsNullOrEmpty(entityName) && rt.ImageLibrary != null) {
                var image = GetEntityImage(entityName);
                if (!string.IsNullOrEmpty(image)) UI.CreateImage(ref container, UINAME_ENTITY, image, configData.uiS.entityImageAnchorMin, configData.uiS.entityImageAnchorMax);
            }
            CuiHelper.AddUi(player, container);
        }
        private static void PricesUpdate(BasePlayer player, bool usePrice, BaseEntity targetEntity) {
            CuiHelper.DestroyUi(player, UINAME_PRICE);
            if (targetEntity == null || !IsValidEntity(targetEntity)) return;
            var price = new Dictionary<string, int>();
            if (usePrice) price = rt.GetPrice(targetEntity);
            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.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 = GetAnchor(configData.uiS.price2TextAnchorMin);
                var anchorMax = GetAnchor(configData.uiS.price2TextAnchorMax);
                float x = (anchorMax.y - anchorMin.y) / price.Count;
                int textSize = configData.uiS.price2TextSize - price.Count;
                int i = 0;
                foreach (var p in price) {
                    UI.CreateLabel(ref container, UINAME_PRICE, configData.uiS.price2TextColor, $"{GetDisplayName(p.Key)} x{p.Value}", 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 = GetItemImage(p.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.AddUi(player, container);
        }
        private static void RefundUpdate(BasePlayer player, bool useRefund, BaseEntity targetEntity) {
            CuiHelper.DestroyUi(player, UINAME_REFUND);
            if (targetEntity == null || !IsValidEntity(targetEntity)) return;
            var refund = new Dictionary<string, int>();
            if (useRefund) refund = rt.GetRefund(targetEntity);
            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.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 = GetAnchor(configData.uiS.refund2TextAnchorMin);
                var anchorMax = GetAnchor(configData.uiS.refund2TextAnchorMax);
                float x = (anchorMax.y - anchorMin.y) / refund.Count;
                int textSize = configData.uiS.refund2TextSize - refund.Count;
                int i = 0;
                foreach (var p in refund) {
                    UI.CreateLabel(ref container, UINAME_REFUND, configData.uiS.refund2TextColor, $"{GetDisplayName(p.Key)} x{p.Value}", 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 = GetItemImage(p.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.AddUi(player, container);
        }
        private static void AuthorizationUpdate(BasePlayer player, RemoveType removeType, BaseEntity targetEntity, bool shouldPay) {
            CuiHelper.DestroyUi(player, UINAME_AUTH);
            if (targetEntity == null) return;
            string reason;
            string color = rt.CanRemoveEntity(player, removeType, targetEntity, 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.AddUi(player, container);
        }
        private static void DestroyUI(BasePlayer player) => CuiHelper.DestroyUi(player, UINAME_MAIN);
#endregion UI
#region ToolRemover Class
        private class ToolRemover : FacepunchBehaviour {
            public BasePlayer player;
            public RemoveType removeType;
            public bool canOverride;
            public BaseEntity hitEntity;
            public int currentRemoved;
            private int timeLeft;
            private float distance;
            private float lastRemove;
            private float removeInterval;
            private bool pay;
            private bool refund;
            private int maxRemovable;
            private RaycastHit raycastHit;
            private BaseEntity targetEntity;
            private uint currentItemID;
            private Item heldItem;
            private int removeTime;
            private bool resetTime;
            private void Awake() {
                player = GetComponent<BasePlayer>();
                if (removeMode == RemoveMode.NoHeld) {
                    currentItemID = player.svActiveItemID;
                    UnEquip();
                }
                if (removeMode == RemoveMode.SpecificTool) heldItem = player.GetActiveItem();
            }
            public void Init(RemoveType type, int time, int max, float dis, float interval, bool p, bool r, bool reset, bool c) {
                canOverride = c;
                removeTime = timeLeft = time;
                removeType = type;
                distance = dis;
                resetTime = reset;
                removeInterval = interval;
                if (removeInterval < 0.2f) removeInterval = 0.2f;
                if (removeType == RemoveType.Normal) {
                    maxRemovable = max;
                    pay = p && configData.removeS.priceEnabled;
                    refund = r && configData.removeS.refundEnabled;
                }
                else {
                    maxRemovable = currentRemoved = 0;
                    pay = refund = false;
                }
                CreateUI(player, removeType);
                CancelInvoke(RemoveUpdate);
                InvokeRepeating(RemoveUpdate, 0f, 1f);
            }
            private void RemoveUpdate() {
                if (configData.uiS.enabled) {
                    TimeLeftUpdate(player, removeType, timeLeft, currentRemoved, maxRemovable);
                    GetTargetEntity();
                    EntityUpdate(player, targetEntity);
                    if (removeType == RemoveType.Normal) {
                        if (configData.uiS.authorizationEnabled) AuthorizationUpdate(player, removeType, targetEntity, pay);
                        if (configData.uiS.priceEnabled) PricesUpdate(player, pay, targetEntity);
                        if (configData.uiS.refundEnabled) RefundUpdate(player, refund, targetEntity);
                    }
                }
                if (timeLeft-- <= 0) Destroy(this);
            }
            private void GetTargetEntity() {
                bool flag = Physics.Raycast(player.eyes.HeadRay(), out raycastHit, distance, Rust.Layers.Solid);
                targetEntity = flag ? raycastHit.GetEntity() : null;
            }
            private bool IsSpecificTool() {
                heldItem = player.GetActiveItem();
                if (heldItem != null && heldItem.info.shortname == configData.removerModeS.shortname) {
                    if (configData.removerModeS.skin < 0) return true;
                    return heldItem.skin == (ulong)configData.removerModeS.skin;
                }
                return false;
            }
            private void FixedUpdate() {
                if (player == null || !player.IsConnected || !player.CanInteract()) {
                    Destroy(this);
                    return;
                }
                if (removeMode == RemoveMode.NoHeld && player.svActiveItemID != currentItemID) {
                    currentItemID = player.svActiveItemID;
                    if (currentItemID != 0) {
                        if (configData.removerModeS.disableInHand) {
                            Destroy(this);
                            return;
                        }
                        UnEquip();
                    }
                }
                if (Time.realtimeSinceStartup - lastRemove >= removeInterval) {
                    if (removeMode != RemoveMode.HammerHit) {
                        if (!player.serverInput.IsDown(removeButton)) return;
                        if (removeMode == RemoveMode.SpecificTool && !IsSpecificTool()) return;
                        GetTargetEntity();
                        if (rt.TryRemove(player, targetEntity, removeType, distance, pay, refund)) {
                            if (resetTime) timeLeft = removeTime;
                            if (removeType == RemoveType.Normal || removeType == RemoveType.Admin) currentRemoved++;
                        }
                    }
                    else {
                        if (hitEntity == null) return;
                        targetEntity = hitEntity;
                        if (rt.TryRemove(player, targetEntity, removeType, distance, pay, refund)) {
                            if (resetTime) timeLeft = removeTime;
                            if (removeType == RemoveType.Normal || removeType == RemoveType.Admin) currentRemoved++;
                        }
                        hitEntity = null;
                    }
                    lastRemove = Time.realtimeSinceStartup;
                }
                if (removeType == RemoveType.Normal && maxRemovable > 0 && currentRemoved >= maxRemovable) {
                    rt.Print(player, rt.Lang("EntityLimit", player.UserIDString, maxRemovable));
                    Destroy(this);
                }
                ;
            }
            private void UnEquip() {
                //player.lastReceivedTick.activeItem = 0;
                var activeItem = player.GetActiveItem();
                if (activeItem == null) return;
                var heldEntity = activeItem.GetHeldEntity() as HeldEntity;
                if (heldEntity == null) return;
                var slot = activeItem.position;
                activeItem.SetParent(null);
                rt.timer.Once(0.2f, () => {
                    if (activeItem == null || player == null) return;
                    if (player.inventory.containerBelt.GetSlot(slot) == null) {
                        activeItem.position = slot;
                        activeItem.SetParent(player.inventory.containerBelt);
                    }
                    else player.GiveItem(activeItem);
                }
                );
            }
            private void OnDestroy() {
                CancelInvoke(RemoveUpdate);
                DestroyUI(player);
                if (removeType == RemoveType.Normal && rt != null) rt.cooldownTimes[player.userID] = Time.realtimeSinceStartup;
            }
        }
#endregion ToolRemover Class
#region Pay
        private bool Pay(BasePlayer player, BaseEntity targetEntity) {
            var price = GetPrice(targetEntity);
            try {
                List<Item> collect = new List<Item>();
                foreach (var p in price) {
                    if (p.Value <= 0) continue;
                    int itemID;
                    if (itemShortNameToItemID.TryGetValue(p.Key, out itemID)) {
                        player.inventory.Take(collect, itemID, p.Value);
                        player.Command("note.inv", itemID, -p.Value);
                    }
                    else if (!CheckOrPay(p.Key, p.Value, player.userID)) return false;
                }
                foreach (Item item in collect) item.Remove();
            }
            catch (Exception e) {
                PrintError($"{player} couldn't pay to remove entity.Error Message: {e.Message}");
                return false;
            }
            return true;
        }
        private Dictionary<string, int> GetPrice(BaseEntity targetEntity) {
            var price = new Dictionary<string, int>();
            var buildingblock = targetEntity.GetComponent<BuildingBlock>();
            if (buildingblock != null) {
                var entityName = prefabNameToStructure[buildingblock.PrefabName];
                ConfigData.RemoveS.BuildingBlocksS buildingBlockS;
                if (configData.removeS.buildingBlockS.TryGetValue(entityName, out buildingBlockS)) {
                    ConfigData.RemoveS.BuildingBlocksS.BuildingGradeS buildingGradeS;
                    if (buildingBlockS.buildingGradeS.TryGetValue(buildingblock.grade, out buildingGradeS)) {
                        float percentage;
                        if (float.TryParse(buildingGradeS.price.ToString(), out percentage)) {
                            var currentGrade = buildingblock.currentGrade;
                            if (currentGrade != null) {
                                foreach (var itemAmount in currentGrade.costToBuild) {
                                    var amount = Mathf.RoundToInt(itemAmount.amount * percentage / 100);
                                    if (amount <= 0) continue;
                                    price.Add(itemAmount.itemDef.shortname, amount);
                                }
                                return price;
                            }
                        }
                        else {
                            if (buildingGradeS.price is Dictionary<string, int>) return buildingGradeS.price as Dictionary<string, int>;
                            try {
                                return JsonConvert.DeserializeObject<Dictionary<string, int>>(buildingGradeS.price.ToString());
                            }
                            catch (Exception e) {
                                PrintError($"Wrong price format for '{buildingblock.grade}' of '{entityName}' in 'Building Blocks Settings'.Error Message: {e.Message}");
                                var currentGrade = buildingblock.currentGrade;
                                if (currentGrade != null) return currentGrade.costToBuild.ToDictionary(x => x.itemDef.shortname, y => Mathf.RoundToInt(y.amount));
                            }
                        }
                    }
                }
            }
            else {
                ConfigData.RemoveS.EntityS entityS;
                if (configData.removeS.entityS.TryGetValue(targetEntity.ShortPrefabName, out entityS)) return entityS.price;
            }
            return price;
        }
        private bool CanPay(BasePlayer player, BaseEntity targetEntity) {
            var price = GetPrice(targetEntity);
            if (price.Count <= 0) return true;
            foreach (var p in price) {
                if (p.Value <= 0) continue;
                int itemID;
                if (itemShortNameToItemID.TryGetValue(p.Key, out itemID)) {
                    int c = player.inventory.GetAmount(itemID);
                    if (c < p.Value) return false;
                }
                else if (!CheckOrPay(p.Key, p.Value, player.userID, true)) return false;
            }
            return true;
        }
        private bool CheckOrPay(string key, int price, ulong playerID, bool check = false) {
            if (price <= 0) return true;
            switch (key.ToLower()) {
                case "economics" : if (Economics == null) return false;
                if (check) {
                    var b = Economics.Call("Balance", playerID);
                    if (b == null) return false;
                    if ((double)b < price) return false;
                }
                else {
                    var w = Economics.Call("Withdraw", playerID, (double)price);
                    if (w == null || !(bool)w) return false;
                }
                return true;
                case "serverrewards" : if (ServerRewards == null) return false;
                if (check) {
                    var c = ServerRewards.Call("CheckPoints", playerID);
                    if (c == null) return false;
                    if ((int)c < price) return false;
                }
                else {
                    var t = ServerRewards.Call("TakePoints", playerID, price);
                    if (t == null || !(bool)t) return false;
                }
                return true;
            }
            return true;
        }
#endregion Pay
#region Refund
        private void GiveRefund(BasePlayer player, BaseEntity targetEntity) {
            var refund = GetRefund(targetEntity);
            foreach (var r in refund) {
                if (r.Value <= 0) continue;
                int itemID;
                string shortname;
                shorPrefabNameToDeployable.TryGetValue(targetEntity.ShortPrefabName, out shortname);
                if (itemShortNameToItemID.TryGetValue(r.Key, out itemID)) {
                    var item = ItemManager.CreateByItemID(itemID, r.Value, r.Key == shortname ? targetEntity.skinID : 0);
                    player.GiveItem(item);
                }
                else {
                    switch (r.Key.ToLower()) {
                        case "economics" : if (Economics == null) continue;
                        Economics.Call("Deposit", player.userID, (double)r.Value);
                        continue;
                        case "serverrewards" : if (ServerRewards == null) continue;
                        ServerRewards.Call("AddPoints", player.userID, r.Value);
                        continue;
                        default : PrintError($"{player} didn't receive refund because {r.Key} doesn't seem to be a valid item name");
                        continue;
                    }
                }
            }
        }
        private Dictionary<string, int> GetRefund(BaseEntity targetEntity) {
            var refund = new Dictionary<string, int>();
            var buildingblock = targetEntity.GetComponent<BuildingBlock>();
            if (buildingblock != null) {
                var entityName = prefabNameToStructure[buildingblock.PrefabName];
                ConfigData.RemoveS.BuildingBlocksS buildingBlockS;
                if (configData.removeS.buildingBlockS.TryGetValue(entityName, out buildingBlockS)) {
                    ConfigData.RemoveS.BuildingBlocksS.BuildingGradeS buildingGradeS;
                    if (buildingBlockS.buildingGradeS.TryGetValue(buildingblock.grade, out buildingGradeS)) {
                        float percentage;
                        if (float.TryParse(buildingGradeS.refund.ToString(), out percentage)) {
                            var currentGrade = buildingblock.currentGrade;
                            if (currentGrade != null) {
                                foreach (var itemAmount in currentGrade.costToBuild) {
                                    var amount = Mathf.RoundToInt(itemAmount.amount * percentage / 100);
                                    if (amount <= 0) continue;
                                    refund.Add(itemAmount.itemDef.shortname, amount);
                                }
                                return refund;
                            }
                        }
                        else {
                            if (buildingGradeS.refund is Dictionary<string, int>) return buildingGradeS.refund as Dictionary<string, int>;
                            try {
                                return JsonConvert.DeserializeObject<Dictionary<string, int>>(buildingGradeS.refund.ToString());
                            }
                            catch (Exception e) {
                                PrintError($"Wrong refund format for '{buildingblock.grade}' of '{entityName}' in 'Building Blocks Settings'.Error Message: {e.Message}");
                                var currentGrade = buildingblock.currentGrade;
                                if (currentGrade != null) return currentGrade.costToBuild.ToDictionary(x => x.itemDef.shortname, y => Mathf.RoundToInt(y.amount));
                            }
                        }
                    }
                }
            }
            else {
                ConfigData.RemoveS.EntityS entityS;
                if (configData.removeS.entityS.TryGetValue(targetEntity.ShortPrefabName, out entityS)) refund = entityS.refund;
                if (configData.removeS.refundSlot) {
                    var slots = GetSlots(targetEntity);
                    if (slots.Count > 0) {
                        int value, amount;
                        var r = new Dictionary<string, int>();
                        var union = refund.Keys.Union(slots.Keys);
                        foreach (var u in union) {
                            value = 0;
                            if (refund.TryGetValue(u, out amount)) value += amount;
                            if (slots.TryGetValue(u, out amount)) value += amount;
                            r.Add(u, value);
                        }
                        return r;
                    }
                }
            }
            return refund;
        }
        private Dictionary<string, int> GetSlots(BaseEntity targetEntity) {
            var slots = new Dictionary<string, int>();
            foreach (BaseEntity.Slot slot in Enum.GetValues(typeof(BaseEntity.Slot))) {
                if (targetEntity.HasSlot(slot)) {
                    var s = targetEntity.GetSlot(slot);
                    if (s != null) {
                        string slotName;
                        if (shorPrefabNameToDeployable.TryGetValue(s.ShortPrefabName, out slotName)) slots.Add(slotName, 1);
                    }
                }
            }
            return slots;
        }
#endregion Refund
#region RaidBlocker
        private readonly Hash<uint, float> lastAttackedBuildings = new Hash<uint, float>();
        private readonly Hash<ulong, float> lastBlockedPlayers = new Hash<ulong, float>();
        private void BlockRemove(BuildingBlock buildingBlock) {
            if (configData.raidS.blockBuildingID) {
                var buildingID = buildingBlock.buildingID;
                lastAttackedBuildings[buildingID] = Time.realtimeSinceStartup;
            }
            if (configData.raidS.blockPlayers) {
                var players = Pool.GetList<BasePlayer>();
                Vis.Entities(buildingBlock.transform.position, configData.raidS.blockRadius, players, Rust.Layers.Mask.Player_Server);
                foreach (var player in players) {
                    if (player.userID.IsSteamId()) lastBlockedPlayers[player.userID] = Time.realtimeSinceStartup;
                }
                Pool.FreeList(ref players);
            }
        }
        private bool IsRaidBlocked(BasePlayer player, BaseEntity targetEntity, out float timeLeft) {
            if (configData.raidS.blockBuildingID) {
                var buildingBlock = targetEntity.GetComponent<BuildingBlock>();
                if (buildingBlock != null) {
                    timeLeft = configData.raidS.blockTime - (Time.realtimeSinceStartup - lastAttackedBuildings[buildingBlock.buildingID]);
                    if (timeLeft > 0) return true;
                }
            }
            if (configData.raidS.blockPlayers) {
                timeLeft = configData.raidS.blockTime - (Time.realtimeSinceStartup - lastBlockedPlayers[player.userID]);
                if (timeLeft > 0) return true;
            }
            timeLeft = 0;
            return false;
        }
#endregion RaidBlocker
#region TryRemove
        private bool TryRemove(BasePlayer player, BaseEntity targetEntity, RemoveType removeType, float distance, bool shouldPay, bool shouldRefund) {
            if (targetEntity == null) {
                Print(player, Lang("NotFoundOrFar", player.UserIDString));
                return false;
            }
            if (removeType == RemoveType.Admin) {
                if (targetEntity is BasePlayer) {
                    var target = targetEntity as BasePlayer;
                    if (target.userID.IsSteamId() && target.IsConnected) {
                        target.Kick("From RemoverTool Plugin");
                        return true;
                    }
                }
                DoRemove(targetEntity, configData.removeTypeS[RemoveType.Admin].gibs);
                return true;
            }
            string reason;
            if (!CanRemoveEntity(player, removeType, targetEntity, shouldPay, out reason)) {
                Print(player, reason);
                return false;
            }
            if (removeType == RemoveType.All) {
                if (removeAllCoroutine != null) {
                    Print(player, Lang("AlreadyRemoveAll", player.UserIDString));
                    return false;
                }
                removeAllCoroutine = ServerMgr.Instance.StartCoroutine(RemoveAll(targetEntity, player));
                Print(player, Lang("StartRemoveAll", player.UserIDString));
                return true;
            }
            if (removeType == RemoveType.External) {
                var stabilityEntity = targetEntity.GetComponent<StabilityEntity>();
                if (stabilityEntity == null || !IsExternalWall(stabilityEntity)) {
                    Print(player, Lang("NotExternalWall", player.UserIDString));
                    return false;
                }
                if (removeExternalCoroutine != null) {
                    Print(player, Lang("AlreadyRemoveExternal", player.UserIDString));
                    return false;
                }
                removeExternalCoroutine = ServerMgr.Instance.StartCoroutine(RemoveExternal(stabilityEntity, player));
                Print(player, Lang("StartRemoveExternal", player.UserIDString));
                return true;
            }
            if (removeType == RemoveType.Structure) {
                var decayEntity = targetEntity.GetComponent<DecayEntity>();
                if (decayEntity == null) {
                    Print(player, Lang("NotStructure", player.UserIDString));
                    return false;
                }
                if (removeStructureCoroutine != null) {
                    Print(player, Lang("AlreadyRemoveStructure", player.UserIDString));
                    return false;
                }
                removeStructureCoroutine = ServerMgr.Instance.StartCoroutine(RemoveStructure(decayEntity, player));
                Print(player, Lang("StartRemoveStructure", player.UserIDString));
                return true;
            }
            if (targetEntity is StorageContainer) {
                var storageContainer = targetEntity as StorageContainer;
                if (storageContainer.inventory?.itemList?.Count > 0) {
                    if (configData.con
// ... [Code preview truncated due to length. Full source in attached file] ...

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