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

FREE NoEscape : 0.1.71 0.1.71

Нет прав для скачивания
C#:
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Rust;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("NoEscape", "whiteplugins.ru / RustPlugins.ru", "0.1.71")]
    public class NoEscape : RustPlugin
    {
        private static string Layer = "UI_NoEscapeLayer";
        private static List<Blocker> BlockerList = new List<Blocker>();

        #region Class

        private class PlayerBlocked : MonoBehaviour
        {
            private BasePlayer Player;
            public Blocker CurrentBlocker;

            private void Awake()
            {
                Player = GetComponent<BasePlayer>();
                if (!instance.permission.UserHasPermission(Player.UserIDString, Settings.NotificationSettings.PermissionToIgnore))
                    InvokeRepeating(nameof(ControllerUpdate), 1f, 1f);
            }

            private void ControllerUpdate()
            {
                if (CurrentBlocker == null)
                {
                    UnblockPlayer();
                    if (Settings.BlockSettings.ShouldBlockEnter)
                    {
                        var blocker = BlockerList.FirstOrDefault(p => p.IsInBlocker(Player));
                        if (!blocker) return;

                        BlockPlayer(blocker);
                    }
                }
                else
                {
                    UpdateUI();
                }
            }

            private void BlockPlayer(Blocker blocker, bool justCreated = false)
            {
                CurrentBlocker = blocker;

                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel
                {
                    CursorEnabled = false,
                    RectTransform = { AnchorMin = "0.3447913 0.112037", AnchorMax = "0.640625 0.1398148", OffsetMax = "0 0" },
                    Image = { Color = "0.968627453 0.921568632 0.882352948 0.03529412" }
                }, "Hud", Layer);

                CuiHelper.AddUi(Player, container);
                UpdateUI();
            }

            private const string UpdateLayer = "UI_MagicLayerUpdate";

            public void UpdateUI()
            {
                CuiHelper.DestroyUi(Player, UpdateLayer);
                CuiHelper.DestroyUi(Player, Layer + ".Info");

                CuiElementContainer container = new CuiElementContainer();

                container.Add(new CuiElement
                {
                    Parent = Layer,
                    Name = UpdateLayer,
                    Components =
                    {//0.441568628 0.609607848 0.327451 1
                        new CuiImageComponent { Color = Settings.NotificationSettings.InterfaceColor },
                        new CuiRectTransformComponent {AnchorMin = $"0 0", AnchorMax = $"{(float) (CurrentBlocker.CurrentTime / CurrentBlocker.TotalTime)} 1", OffsetMin = "1 1", OffsetMax = "-2 -1"},
                    }
                });
                container.Add(new CuiLabel
                {
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
                    Text = { Text = $"БЛОКИРОВКА: {(CurrentBlocker.TotalTime - CurrentBlocker.CurrentTime + 1):F0} СЕК", Font = "robotocondensed-regular.ttf", Color = "0.8 0.8 0.8 0.9", FontSize = 16, Align = TextAnchor.MiddleCenter }
                }, Layer, Layer + ".Info");

                CuiHelper.AddUi(Player, container);
            }

            private void UnblockPlayer()
            {
                CuiHelper.DestroyUi(Player, Layer);
            }

            private void OnDestroy() => UnblockPlayer();
        }

        private class Blocker : MonoBehaviour
        {
            public double CurrentTime = 0;
            public double TotalTime = Settings.BlockSettings.BlockLength;

            public BuildingPrivlidge Cupboard;
            public BaseEntity Alarm;
            public BaseEntity Light;

            public void Awake()
            {
                Cupboard = GetComponent<BuildingPrivlidge>();
                if (Cupboard == null)
                {
                    Cupboard = GetComponent<BaseEntity>().GetBuildingPrivilege();
                }
                else
                {
                    if (Settings.BlockSettings.CreateAlarm)
                    {
                        Alarm = GameManager.server.CreateEntity("assets/prefabs/deployable/playerioents/alarms/audioalarm.prefab", Cupboard.transform.position, default(Quaternion), true);

                        Alarm.Spawn();

                        Alarm.SetFlag(BaseEntity.Flags.Reserved8, true);
                    }
                    if (Settings.BlockSettings.CreateLighter)
                    {
                        Light = GameManager.server.CreateEntity("assets/prefabs/deployable/playerioents/lights/sirenlight/electric.sirenlight.deployed.prefab", Cupboard.transform.position, Quaternion.identity, false);


                        Light.enableSaving = true;
                        Light.Spawn();
                        Light.SetParent(Cupboard);
                        Light.transform.localPosition = new Vector3(0, 1.7f, 0);
                        Light.transform.hasChanged = true;
                        Light.SendNetworkUpdate();

                        Light.SetFlag(BaseEntity.Flags.Reserved8, true);
                    }

                    NotifyOwners(Cupboard);
                }
            }

            public void Update()
            {
                CurrentTime += Time.deltaTime;
                if (CurrentTime > TotalTime)
                {
                    if (BlockerList.Contains(this))
                        BlockerList.Remove(this);

                    UnityEngine.Object.Destroy(this);
                }
            }

            public void OnDestroy()
            {
                if (Settings.BlockSettings.CreateAlarm)
                {
                    Alarm?.Kill();
                }
                if (Settings.BlockSettings.CreateLighter)
                {
                    Light?.Kill();
                }

                if (BlockerList.Contains(this))
                    BlockerList.Remove(this);
            }

            public bool IsOwner(ulong userId) => Cupboard?.authorizedPlayers.FirstOrDefault(p => p.userid == userId) != null;
            public bool IsInBlocker(BaseEntity player) => Vector3.Distance(player.transform.position, transform.position) < Settings.BlockSettings.BlockerDistance;
        }

        #endregion


        private void OnPlayerInit(BasePlayer player)
        {
            if (player.IsReceivingSnapshot)
            {
                NextTick(() => OnPlayerInit(player));
                return;
            }

            if (player.GetComponent<PlayerBlocked>() == null)
                player.gameObject.AddComponent<PlayerBlocked>();

            if (player.GetComponent<PlayerBlocked>().CurrentBlocker != null)
            {
                CuiElementContainer container = new CuiElementContainer();
                container.Add(new CuiPanel
                {
                    CursorEnabled = false,
                    RectTransform = { AnchorMin = "0.3447913 0.112037", AnchorMax = "0.640625 0.1398148", OffsetMax = "0 0" },
                    Image = { Color = "0.968627453 0.921568632 0.882352948 0.03529412" }
                }, "Hud", Layer);

                CuiHelper.AddUi(player, container);
            }
        }

        private void Unload()
        {
            UnityEngine.Object.FindObjectsOfType<PlayerBlocked>().ToList().ForEach(UnityEngine.Object.Destroy);
            UnityEngine.Object.FindObjectsOfType<Blocker>().ToList().ForEach(UnityEngine.Object.Destroy);
        }

        private class Configuration
        {
            internal class BlockSetting
            {
                internal class BlockLimit
                {
                    [JsonProperty("Можно ли строить? (фундаменты, стены (из соломы))")]
                    public bool CanBuild = true;
                    [JsonProperty("Можно ли размещать объекты? (спальники, двери и т.д.)")]
                    public bool CanPlaceObjects = true;
                    [JsonProperty("Можно ли чинить объекты (фундаменты, двери и т.д.)")]
                    public bool CanRepair = false;
                    [JsonProperty("Можно ли улучшать объекты (фундаменты, стены и т.д.)")]
                    public bool CanUpgrade = false;
                    [JsonProperty("Список запрещенных для использования команд")]
                    public List<string> BlockedCommands = new List<string>();
                }

                [JsonProperty("Дистанция действия блокировки (в метрах)")]
                public float BlockerDistance = 150;
                [JsonProperty("Время блокировки в секундах")]
                public float BlockLength = 150;
                [JsonProperty("Создавать сигнальный фонарь при рейде")]
                public bool CreateLighter = true;
                [JsonProperty("Создавать звуковое оповещение при рейде (колонка)")]
                public bool CreateAlarm = true;
                [JsonProperty("Блокировать хозяев построек, даже если они вне зоны рейда")]
                public bool BlockOwnersIfNotInZone = false;
                [JsonProperty("Блокировать игрока, который вошёл в активную зону блокировки")]
                public bool ShouldBlockEnter = true;
                [JsonProperty("Пускать игроков без очереди, если игрока рейдят")]
                public bool ShouldByPassQueue = true;
                [JsonProperty("Разрешить игрокам ломать шкаф (сразу после разрушения шкафа рейд-блок спадёт)")]
                public bool CanDestroyCupBoard = false;

                [JsonProperty("ЭКСПЕРИМЕНТАЛЬНО.Отвязать РБ от шкафа (сохранив звуки и мигалку)")]
                public bool ExperimentalFoundation;

                [JsonProperty("Настройки ограничений игроков в рейд-блоке")]
                public BlockLimit BlockLimits = new BlockLimit();
            }

            internal class NotificationSetting
            {
                [JsonProperty("Цвет полосы в интерфейсе у РБ игроков")]
                public string InterfaceColor = "0.121568628 0.419607848 0.627451 0.784313738";
                [JsonProperty("Привилегия, игроки с которой могут установить оповещение о рейде")]
                public string PermissionToInstall = "NoEscape.Install";
                [JsonProperty("Привилегия, игроки с которой игнорируются РБ (на них он не действует")]
                public string PermissionToIgnore = "NoEscape.Ignore";
                [JsonProperty("Текст уведомления о рейде для отправки")]
                public string NotificationText = "Ваша постройка подверглась нападению!\n" +
                                                 "Скорее заходите и защитесь!";
            }

            [JsonProperty("Настройка работы блокировки")]
            public BlockSetting BlockSettings = new BlockSetting();
            [JsonProperty("Настройка оповещения о рейде")]
            public NotificationSetting NotificationSettings = new NotificationSetting();

            public static Configuration GetNewConfiguration()
            {
                return new Configuration
                {
                    BlockSettings = new BlockSetting
                    {
                        BlockLimits = new BlockSetting.BlockLimit
                        {
                            BlockedCommands = new List<string>
                            {
                                "/shop",
                                "/s",
                                "/chat",
                                "god",
                                "backpack.open"
                            }
                        }
                    }
                };
            }
        }

        #region Variables

        private static Configuration Settings = new Configuration();

        #endregion

        #region Hooks


        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                Settings = Config.ReadObject<Configuration>();
                if (Settings?.BlockSettings == null) LoadDefaultConfig();
            }
            catch
            {
                PrintWarning($"Ошибка чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
                LoadDefaultConfig();
            }

            NextTick(SaveConfig);
        }

        protected override void LoadDefaultConfig() => Settings = Configuration.GetNewConfiguration();
        protected override void SaveConfig() => Config.WriteObject(Settings);

        private bool? OnServerCommand(ConsoleSystem.Arg args)
        {
            var player = args.Player();
            if (player == null) return null;
            if (!args.HasArgs(1)) return null;

            if (!IsBlocked(player)) return null;

            foreach (var check in Settings.BlockSettings.BlockLimits.BlockedCommands)
            {
                if (args.Args[0].ToLower().Contains(check.ToLower()))
                {
                    player.ChatMessage("Вам запрещено использовать эту команду во время РБ!");
                    return false;
                }
            }

            return null;
        }

        private bool? OnPlayerCommand(ConsoleSystem.Arg args, BasePlayer player)
        {
            if (!args.HasArgs(1)) return null;

            BasePlayer initiator = args.Player();
            if (initiator == null) return null;

            if (!IsBlocked(initiator)) return null;
            string cmd = args.Args[0];

            if (Settings.BlockSettings.BlockLimits.BlockedCommands.Contains(cmd.ToLower()))
            {
                initiator.ChatMessage("Вам запрещено использовать эту команду во время РБ!");
                return false;
            }

            return null;
        }

        private string CupLayer = "UI_CupLayer";
        private void OnLootEntity(BasePlayer player, BaseEntity entity)
        {
            if (!(entity is BuildingPrivlidge)) return;
            if (!VKBot) return;

            CuiHelper.DestroyUi(player, CupLayer);
            CuiElementContainer container = new CuiElementContainer();

            container.Add(new CuiPanel
            {
                CursorEnabled = false,
                RectTransform = { AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "192 491", OffsetMax = "573 556" },
                Image = { Color = "0 0 0 0" }
            }, "Overlay", CupLayer);

            bool isOn = entity.HasFlag(BaseEntity.Flags.Reserved4);
            string text = isOn ? "ОПОВЕЩЕНИЯ АКТИВИРОВНЫ" : "ОПОВЕЩЕНИЯ ОТКЛЮЧЕНЫ";

            container.Add(new CuiButton
            {
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
                Button = { Color = isOn ? "0.5 0.6 0.5 1" : "0.7 0.5 0.5 1", Command = "UI_NoEscape switch" },
                Text = { Text = "", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 24 }
            }, CupLayer);

            if (!permission.UserHasPermission(player.UserIDString, Settings.NotificationSettings.PermissionToInstall) && !isOn)
            {
                container.Add(new CuiButton
                {
                    RectTransform = { AnchorMin = "0 0.15", AnchorMax = "1 1", OffsetMax = "0 0" },
                    Button = { Color = isOn ? "0.501486 0.60850789 0.504524 0" : "0.70465 0.50488 0.50655 0", Command = "UI_NoEscape switch" },
                    Text = { Text = isOn ? "ОПОВЕЩЕНИЯ АКТИВИРОВНЫ" : "ОПОВЕЩЕНИЯ ОТКЛЮЧЕНЫ", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 24 }
                }, CupLayer);

                container.Add(new CuiButton
                {
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.55", OffsetMax = "0 0" },
                    Button = { Color = isOn ? "0.501486 0.60850789 0.504524 0" : "0.70465 0.50488 0.50655 0", Command = "UI_NoEscape switch" },
                    Text = { Text = "У вас нет доступа к активации оповещений о рейде", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 12 }
                }, CupLayer);
            }
            else
            {
                container.Add(new CuiButton
                {
                    RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
                    Button = { Color = isOn ? "0.501486 0.60850789 0.504524 0" : "0.70465 0.50488 0.50655 0", Command = "UI_NoEscape switch" },
                    Text = { Text = isOn ? "ОПОВЕЩЕНИЯ АКТИВИРОВНЫ" : "ОПОВЕЩЕНИЯ ОТКЛЮЧЕНЫ", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 24 }
                }, CupLayer);
            }

            CuiHelper.AddUi(player, container);
        }

        [ConsoleCommand("UI_NoEscape")]
        private void CmdConsoleHandler(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Player();
            if (!args.HasArgs(1) || player == null) return;
            switch (args.Args[0].ToLower())
            {
                case "switch":
                    {
                        if (!permission.UserHasPermission(player.UserIDString, Settings.NotificationSettings.PermissionToInstall)) return;
                        string receiver = (string)instance.VKBot.Call("GetUserVKId", player.userID);
                        if (string.IsNullOrEmpty(receiver))
                        {
                            player.ChatMessage($"У вас не подтвержден профиль ВК! Используйте VKBot чтобы сделать это!");
                            return;
                        }

                        var loot = player.inventory.loot.entitySource;
                        if (loot != null && loot is BuildingPrivlidge)
                            loot.SetFlag(BaseEntity.Flags.Reserved4, !loot.HasFlag(BaseEntity.Flags.Reserved4));

                        OnLootEntity(player, loot);
                        break;
                    }
            }
        }

        private void OnLootEntityEnd(BasePlayer player, BaseCombatEntity entity) => CuiHelper.DestroyUi(player, CupLayer);

        private bool? OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if (entity is BuildingPrivlidge && entity.GetComponent<Blocker>())
            {
                if (info?.InitiatorPlayer != null) info?.InitiatorPlayer.ChatMessage($"Вы не можете разрушить шкаф во время блокировки!");
                info?.damageTypes.ScaleAll(0);
                return false;
            }
            return null;
        }

        private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
        {
            if (!(entity is StabilityEntity)) return;
            if (entity.GetBuildingPrivilege() == null) return;
            if (entity is BuildingBlock && (entity as BuildingBlock).currentGrade.gradeBase.type == BuildingGrade.Enum.Twigs) return;
            var owner = info?.InitiatorPlayer;
            if (owner != null && owner.IsBuildingAuthed()) return;
            if (info?.damageTypes.GetMajorityDamageType() == DamageType.Decay) return;

            var buildingPrivlidge = entity.GetBuildingPrivilege();

            var alreadyBlock = BlockerList.FirstOrDefault(p => p.Cupboard == buildingPrivlidge);
            if (alreadyBlock)
            {
                BlockerList.ForEach(p =>
                {
                    if (p.IsInBlocker(entity)) p.CurrentTime = 0;
                });
            }
            else
            {
                if (Settings.BlockSettings.ExperimentalFoundation)
                {
                    var newBlock = buildingPrivlidge.GetBuilding()?.buildingBlocks.ToList().GetRandom();
                    if (newBlock != null)
                    {
                        var obj = newBlock.gameObject.AddComponent<Blocker>();
                        BlockerList.Add(obj);
                    }
                }

                var block = buildingPrivlidge.gameObject.AddComponent<Blocker>();
                BlockerList.Add(block);
            }
        }
        private bool? CanBypassQueue(Network.Connection connection) => BlockerList.FirstOrDefault(p => p.IsOwner(connection.userid));
        private void OnEntityBuilt(Planner plan, GameObject go)
        {
            BasePlayer player = plan.GetOwnerPlayer();
            BaseEntity entity = go.ToBaseEntity();

            if (entity is BuildingPrivlidge && !permission.UserHasPermission(player.UserIDString, Settings.NotificationSettings.PermissionToInstall))
                entity.SetFlag(BaseEntity.Flags.Reserved4, false);

            if (player == null || !IsRaidBlocked(player)) return;

            bool shouldDestroy = false;
            if (!Settings.BlockSettings.BlockLimits.CanBuild && entity is StabilityEntity) shouldDestroy = true;
            else if (!Settings.BlockSettings.BlockLimits.CanPlaceObjects && entity is DecayEntity) shouldDestroy = true;
            else return;

            if (shouldDestroy)
            {
                if (entity is BuildingBlock)
                {
                    (entity as StabilityEntity).BuildCost().ForEach(p =>
                    {
                        var item = ItemManager.Create(p.itemDef, (int)p.amount);
                        if (!player.inventory.GiveItem(item)) item.Drop(player.transform.position, Vector3.down);
                    });
                }
                else if (entity is DecayEntity)
                {
                    var item = ItemManager.GetItemDefinitions().FirstOrDefault(p => p.GetComponent<ItemModDeployable>()?.entityPrefab.resourcePath == entity.PrefabName);
                    if (item == null) return;

                    if (!player.inventory.GiveItem(ItemManager.Create(item)))
                        ItemManager.Create(item).Drop(player.transform.position, Vector3.down);
                }

                player.ChatMessage($"Вам запрещено совершать это действие во время РБ!");
                entity.Kill();
            }
        }

        private bool? CanAffordUpgrade(BasePlayer player, BuildingBlock block, BuildingGrade.Enum grade)
        {
            if (!IsRaidBlocked(player)) return null;

            player.ChatMessage($"Вам запрещено улучшать объекты во время РБ!");
            return false;
        }

        private bool? OnStructureRepair(BaseCombatEntity entity, BasePlayer player)
        {
            if (!IsRaidBlocked(player)) return null;

            player.ChatMessage($"Вам запрещено чинить объекты во время РБ!");
            return false;
        }

        #endregion

        #region Functions

        [PluginReference] private Plugin VKBot;
        private static void NotifyOwners(BuildingPrivlidge building)
        {
            foreach (var check in building.authorizedPlayers)
            {
                string receiver = (string)instance.VKBot?.Call("GetUserVKId", check.userid) ?? "";
                if (string.IsNullOrEmpty(receiver)) continue;

                instance.VKBot?.Call("SendVkMessage", receiver, Settings.NotificationSettings.NotificationText);
            }
        }

        #endregion

        private static NoEscape instance;
        private void OnServerInitialized()
        {
            instance = this;


            permission.RegisterPermission(Settings.NotificationSettings.PermissionToIgnore, this);
            timer.Once(1, () =>
            {
                BasePlayer.activePlayerList.ToList().ForEach(OnPlayerInit);
                PrintError("NoEscape initialized");
            });

            permission.RegisterPermission(Settings.NotificationSettings.PermissionToInstall, this);

            if (Settings.BlockSettings.CanDestroyCupBoard) Unsubscribe(nameof(OnEntityTakeDamage));
            if (Settings.BlockSettings.BlockLimits.CanRepair) Unsubscribe(nameof(OnStructureRepair));
            if (Settings.BlockSettings.BlockLimits.CanUpgrade) Unsubscribe(nameof(CanAffordUpgrade));
            if (!Settings.BlockSettings.ShouldByPassQueue) Unsubscribe(nameof(CanBypassQueue));
        }


        #region API

        private bool IsBlocked(BasePlayer player) => IsRaidBlocked(player);
        private bool IsRaidBlock(ulong userId) => IsRaidBlocked(userId.ToString());
        private bool IsRaidBlocked(BasePlayer player) => player.GetComponent<PlayerBlocked>()?.CurrentBlocker != null;
        private bool IsRaidBlocked(string player)
        {
            BasePlayer target = BasePlayer.Find(player);
            if (!target || !target.IsConnected) return false;

            return IsRaidBlocked(target);
        }
        private int ApiGetTime(ulong userId)
        {
            if (!IsRaidBlocked(userId.ToString())) return 0;
            var targetBlock = BasePlayer.Find(userId.ToString()).GetComponent<PlayerBlocked>();
            return (int)(targetBlock.CurrentBlocker.TotalTime - targetBlock.CurrentBlocker.CurrentTime);
        }

        private string CanTeleport(BasePlayer player)
        {
            if (IsBlocked(player)) return "Вы не можете телепортироваться в зоне рейда!";
            return null;
        }

        private int? CanBGrade(BasePlayer player, int grade, BuildingBlock block, Planner plan)
        {
            if (IsBlocked(player)) return 0;

            return null;
        }

        private string CanTrade(BasePlayer player)
        {
            if (IsBlocked(player)) return "Вы не можете обмениваться ресурсами во время рейда!";
            return null;
        }

        private string canRemove(BasePlayer player)
        {
            if (IsBlocked(player)) return "Вы не можете удалять объекты во время рейда!";
            return null;
        }

        private string canTeleport(BasePlayer player) // ALIAS FOR MagicTeleportation
        {
            if (IsBlocked(player)) return "Вы не можете телепортироваться во время рейда!";
            return null;
        }

        #endregion
    }

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