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

FREE IQWipeBlock : 2.2.3 2.2.3

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using System.Text;
using ConVar;
using Facepunch.Math;
using HarmonyLib;
using UnityEngine.Networking;
using Oxide.Core;
using UnityEngine.UI;
using Object = System.Object;
using Pool = Facepunch.Pool;
namespace Oxide.Plugins {
    [Info("IQWipeBlock", "Mercury", "2.2.3")]
    [Description("Готов к вайпу?")]
    public class IQWipeBlock : RustPlugin {
        /// <summary>
        /// - Исправлена анимация
        /// - Добавлен детект контейнера дрона
        /// </summary>
#region Reference
        [PluginReference]
        Plugin IQChat, Battles, Duel, Duelist, ArenaTournament, AimTraining, XFarmRoom, OneVSOne, EventHelper;
#region IQChat
        private void SendChat(String Message, BasePlayer player, Chat.ChatChannel channel = Chat.ChatChannel.Global) {
            Configuration.ReferencePlugins.IQChat chatPreset = config.referencePlugins.presetReferenceChat;
            if (IQChat) IQChat?.Call("API_ALERT_PLAYER", player, Message, chatPreset.CustomPrefix, chatPreset.CustomAvatar);
            else player.SendConsoleCommand("chat.add", channel, 0, Message);
        }
#endregion
#region IsDuel
        public Boolean IsDuel(BasePlayer player) {
            if (!player) return false;
            UInt64 userID = player.userID.Get();
            Object obj = Interface.Oxide.RootPluginManager.GetPlugin("AimTraining")?.CallHook("IsArenaPlayer", userID);
            if (obj is Boolean) return (Boolean)obj;
            if (EventHelper) {
                if ((Boolean)EventHelper.CallHook("EMAtEvent", userID)) return true;
            }
            if (OneVSOne) if ((Boolean)OneVSOne.Call("IsEventPlayer", player)) return true;
            if (Battles) if ((Boolean)Battles.Call("IsPlayerOnBattle", userID)) return true;
            if (Duel) if ((Boolean)Duel.Call("IsPlayerOnActiveDuel", player)) return true;
            if (Duelist) if ((Boolean)Duelist.Call("inEvent", player)) return true;
            if (ArenaTournament) if (ArenaTournament.Call<Boolean>("IsOnTournament", userID)) return true;
            if (XFarmRoom) if (XFarmRoom.Call<Boolean>("API_PlayerInRoom", userID)) return true;
            return false;
        }
#endregion
#endregion
#region Vars
        private const String permissionIgnore = "iqwipeblock.ignore";
        private Boolean isFullUnblocked = false;
        private const String colorText = "0.8941177 0.854902 0.8196079 1";
        private const String colorProgressBar = "0.894 0.855 0.82 0.5";
        private const Boolean LanguageEn = true;
        private static IQWipeBlock _;
        private static ImageUI _imageUI;
        private const UInt32 mlrs_rocket_storage = 1219574627;
        private const UInt32 submarineTorpedoStorage = 2609093601;
        private const UInt32 catapultAmmoStorage = 2705489675;
        private const UInt32 droneAmmoStorage = 1397446101;
        private const UInt32 droneAmmoStorageCooldown = 1397447202;
        private const String actionDrop = "drop";
        private const GameTip.Styles GameTipStylesRed = GameTip.Styles.Red_Normal;
        private const Item.Flag BlockedFlag = global : : Item.Flag.OnFire;
        private const String fastButtonLayer = "IQWIPEBLOCK_FAST_BUTTON";
        private const String layerWipeBlock = "IQWIPEBLOCK_MAIN";
        private const String mainLayer = "IQWIPEBLOCK_BACKGROUND";
        private const String firstConnectedLayer = "IQWIPEBLOCK_FIRST_CONNECTED_ALERT";
        private Timer timerChecker;
        private Single scrollHeight = 0f;
        private Dictionary<String, ElementPosition> elementPositionsBlock = new();
        private readonly List<ElementPosition> positionItems = new();
        private Dictionary<UInt64, Timer> timerAlertConnection = new Dictionary<UInt64, Timer>();
        public List<UInt64> drawedAlertButton = new List<UInt64>();
        private static readonly DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
        private static Double CurrentTime() => DateTime.UtcNow.Subtract(epoch).TotalSeconds;
        private class ElementPosition {
            public String OffsetMin {
                get;
            }
            public String OffsetMax {
                get;
            }
            public ElementPosition(String offsetMin, String offsetMax) {
                OffsetMin = offsetMin;
                OffsetMax = offsetMax;
            }
        }
#endregion
#region Data
        private Int32 timeCorrectedWipe = 0;
        private void ReadData() => timeCorrectedWipe = Oxide.Core.Interface.Oxide.DataFileSystem.ReadObject<Int32>("IQSystem/IQWipeBlock/TimeCorrectedWipe");
        private void WriteData() => Oxide.Core.Interface.Oxide.DataFileSystem.WriteObject("IQSystem/IQWipeBlock/TimeCorrectedWipe", timeCorrectedWipe);
#endregion
#region Configuration
        private static Configuration config = new Configuration();
        private class Configuration {
            [JsonProperty(LanguageEn ? "Command to open the block menu [Do not use slash `/`]" : "Команда для открытия меню блокировки [Не используйте слэш `/`]")]
            public String commandOpen;
            [JsonProperty(LanguageEn ? "Block settings [UniqueKey] = Setting" : "Настройка блокировок [УникальныйКлюч] = Настройка")]
            public Dictionary<String, CategoryBlocked> categoriesBlockeds = new Dictionary<String, CategoryBlocked>();
            [JsonProperty(LanguageEn ? "Supported plugins configuration" : "Настройка поддерживаемых плагинов")]
            public ReferencePlugins referencePlugins = new ReferencePlugins();
            [JsonProperty(LanguageEn ? "Use notification that wipe-block is active when connecting to the server [true - yes / false - no]" : "Использовать уведомление о том, что вайпблок активен при подключении на сервер [true - да/false - нет]")]
            public Boolean useFirstAlert;
            [JsonProperty(LanguageEn ? "Use quick access button to open the main interface [true - yes / false - no]" : "Использовать кнопку быстрого доступа для открытия основного интерфейса [true - да/false - нет]")]
            public Boolean useFastButton;
            [JsonProperty(LanguageEn ? "Item synonyms. Example: rifle.ak.divier -> rifle.ak [Specify the shortname]" : "Синонимы предметов. Например : rifle.ak.divier -> rifle.ak [Указывайте shortname]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<String, String> weaponAlias = new Dictionary<String, String>();
            [JsonIgnore]
            public Dictionary<Int32, Double> blockedItemsItemdIds = new Dictionary<Int32, Double>();
            [JsonIgnore]
            public Dictionary<Int32, Int32> blockItemNormalizeList = new();
            internal class ReferencePlugins {
                [JsonProperty(LanguageEn ? "Setting up IQChat" : "Настройка IQChat'a")]
                public IQChat presetReferenceChat = new IQChat();
                internal class IQChat {
                    [JsonProperty(LanguageEn ? "IQChat : Custom chat prefix" : "IQChat : Кастомный префикс в чате")]
                    public String CustomPrefix;
                    [JsonProperty(LanguageEn ? "IQChat : Custom chat avatar (If required)" : "IQChat : Кастомный аватар в чате(Если требуется)")]
                    public String CustomAvatar;
                }
            }
            internal class CategoryBlocked {
                [JsonProperty(LanguageEn ? "Category title in different languages [LanguageKey] = Text" : "Навзание категории на разных языках [КлючЯзыка] = Текст")]
                public Dictionary<String, String> titleCategory = new Dictionary<String, String>();
                [JsonProperty(LanguageEn ? "Blocked items [shortname] = seconds [Use whole numbers]" : "Заблокированные предметы [shortname] = секунды [Используйте целые числа]")]
                public Dictionary<String, Int32> blockedsItems = new Dictionary<String, Int32>();
                [JsonIgnore]
                public List<Int32> blockedItemsItemdIds = new List<Int32>();
                public String GetLangTextInConfig(BasePlayer player) {
                    String langPlayer = _.lang.GetLanguage(player.UserIDString);
                    if(titleCategory.TryGetValue(langPlayer, out String day)) return day;
                    if (titleCategory.TryGetValue("en", out String dayEnglish)) return dayEnglish;
                    KeyValuePair<String, String> defautlName = titleCategory.FirstOrDefault();
                    return defautlName.Value ?? String.Empty;
                }
            }
            public Int32 NormalizeItem(Int32 itemId) => blockItemNormalizeList.GetValueOrDefault(itemId, itemId);
            public void ParseItemIdsNormalized() {
                foreach (KeyValuePair<String, String> alias in weaponAlias) {
                    ItemDefinition itemDefFirst = ItemManager.FindItemDefinition(alias.Key);
                    if (!itemDefFirst) {
                        _.PrintError(LanguageEn ? "" : $"Не найден предмет с названием : {alias.Key}, проверьте корректность введенного shortname в списке синонимов");
                        continue;
                    }
                    ItemDefinition itemDefTwo = ItemManager.FindItemDefinition(alias.Value);
                    if (!itemDefTwo) {
                        _.PrintError(LanguageEn ? "" : $"Не найден предмет с названием : {alias.Key}, проверьте корректность введенного shortname в списке синонимов");
                        continue;
                    }
                    blockItemNormalizeList.TryAdd(itemDefFirst.itemid, itemDefTwo.itemid);
                }
            }
            public void GetItemsIDsInConfig(CategoryBlocked categoryBlocked) {
                Int32 wipeTime = (Int32) SaveRestore.SaveCreatedTime.ToUniversalTime().Subtract(epoch).TotalSeconds;
                config.ParseItemIdsNormalized();
                Boolean isError = false;
                List<String> errorListShortnames = Pool.Get<List<String>>();
                foreach (KeyValuePair<String, Int32> itemsInConfig in categoryBlocked.blockedsItems) {
                    ItemDefinition itemDef = ItemManager.FindItemDefinition(itemsInConfig.Key);
                    if (!itemDef) {
                        isError = true;
                        errorListShortnames.Add(itemsInConfig.Key);
                        continue;
                    }
                    if (blockedItemsItemdIds.TryAdd(itemDef.itemid, wipeTime + itemsInConfig.Value + _.timeCorrectedWipe)) {
                        categoryBlocked.blockedItemsItemdIds.Add(itemDef.itemid);
                        continue;
                    }
                    _.PrintWarning(LanguageEn ? $"Attempt to add item (shortname) `{itemsInConfig.Key}` again — duplicate entries are not allowed, please remove duplicates from the configuration!" : $"Попытка добавить предмет (shortname) `{itemsInConfig.Key}` повторно, нельзя добавить один предмет несколько раз, удалите дубликаты в конфигурации!");
                }
                if (isError) {
                    String shortnames = String.Join(", ", errorListShortnames);
                    _.PrintError(LanguageEn ? $"Warning! An error was found in the item name(s) (shortname), incorrect name(s): {shortnames}" : $"Внимание! Допущена ошибка в название(/ях) предмета(/ов) (shortname), название(/я) с ошибкой : {shortnames}");
                    Pool.FreeUnmanaged(ref errorListShortnames);
                    Interface.Oxide.UnloadPlugin(_.Name);
                }
            }
            public Double GetLeftTimeBlocked(Int32 itemID) {
                Int32 normalizeItemID = NormalizeItem(itemID);
                if (!blockedItemsItemdIds.TryGetValue(normalizeItemID, out Double blockedItemTime)) return 0;
                Double elapsed = blockedItemTime - CurrentTime();
                return elapsed < 0 ? 0f : elapsed;
            }
            public Boolean IsBlocked(Int32 itemID) => GetLeftTimeBlocked(itemID) > 0;
            public Boolean IsBlocked(Int32 itemID, out String leftTime) {
                Int32 normalizeItemID = NormalizeItem(itemID);
                Double timeBlocked = GetLeftTimeBlocked(normalizeItemID);
                if (timeBlocked > 0) {
                    leftTime = _.FormatTime(timeBlocked);
                    return true;
                }
                leftTime = String.Empty;
                return false;
            }
            public Boolean IsFullUnBlocked() {
                foreach (Int32 itemId in blockedItemsItemdIds.Keys) {
                    if (IsBlocked(itemId)) return false;
                }
                return true;
            }
            public void InitializeCategory() {
                foreach (KeyValuePair<String, CategoryBlocked> categoryBlocked in categoriesBlockeds) GetItemsIDsInConfig(categoryBlocked.Value);
                _.GeneratePositionsCategoriesPanel();
                _.GeneratePositionsItems();
            }
            public static Configuration GetNewConfiguration() {
                return new Configuration {
                    commandOpen = "block", useFastButton = true, useFirstAlert = true, referencePlugins = new ReferencePlugins {
                        presetReferenceChat = new ReferencePlugins.IQChat {
                            CustomPrefix = "<color=#8EAD57>IQWipeBlock</color> |", CustomAvatar = "0"
                        }
                    }
                    , weaponAlias = new Dictionary<String, String>() {
                        ["rifle.ak.ice"]
                        = "rifle.ak", ["rifle.ak.diver"] = "rifle.ak", ["rifle.ak.med"] = "rifle.ak", ["rifle.ak.jungle"] = "rifle.ak", ["rocket.launcher.dragon"] = "rocket.launcher", ["metal.facemask.hockey"] = "metal.facemask", ["metal.facemask.icemask"] = "metal.facemask", ["metal.plate.torso.icevest"] = "metal.plate.torso", ["blunderbuss"] = "shotgun.double",
                    }
                    , categoriesBlockeds = new Dictionary<String, CategoryBlocked>() {
                        ["start"]
                        = new CategoryBlocked() {
                            titleCategory = new Dictionary<String, String>() {
                                ["ru"]
                                = "ИСКРА", ["en"] = "SPARK",
                            }
                            , blockedsItems = new Dictionary<String, Int32>() {
                                ["shotgun.double"]
                                = 3600, ["shotgun.waterpipe"] = 3600, ["flamethrower"] = 3600, ["military flamethrower"] = 3600, ["pistol.revolver"] = 3600, ["grenade.molotov"] = 3600,
                            }
                        }
                        , ["warmup"] = new CategoryBlocked() {
                            titleCategory = new Dictionary<String, String>() {
                                ["ru"]
                                = "РАЗОГРЕВ", ["en"] = "WARM UP",
                            }
                            , blockedsItems = new Dictionary<String, Int32>() {
                                ["t1_smg"]
                                = 7200, ["pistol.semiauto"] = 7200, ["pistol.python"] = 7200, ["pistol.m92"] = 7200, ["pistol.prototype17"] = 7200, ["shotgun.pump"] = 7200, ["shotgun.spas12"] = 7200, ["shotgun.m4"] = 7200, ["revolver.hc"] = 7200, ["roadsign.kilt"] = 7200, ["roadsign.jacket"] = 7200, ["coffeecan.helmet"] = 7200, ["knightsarmour.helmet"] = 7200, ["knightsarmour.skirt"] = 7200, ["knighttorso.armour"] = 7200,
                            }
                        }
                        , ["escalation"] = new CategoryBlocked() {
                            titleCategory = new Dictionary<String, String>() {
                                ["ru"]
                                = "НАПРЯЖЕНИЕ", ["en"] = "ESCALATION",
                            }
                            , blockedsItems = new Dictionary<String, Int32>() {
                                ["smg.2"]
                                = 18000, ["rifle.semiauto"] = 18000, ["smg.thompson"] = 18000, ["smg.mp5"] = 18000, ["rifle.m39"] = 18000, ["rifle.sks"] = 18000,
                            }
                        }
                        , ["pressure"] = new CategoryBlocked() {
                            titleCategory = new Dictionary<String, String>() {
                                ["ru"]
                                = "ДАВЛЕНИЕ", ["en"] = "PRESSURE",
                            }
                            , blockedsItems = new Dictionary<String, Int32>() {
                                ["metal.facemask"]
                                = 28800, ["metal.plate.torso"] = 28800, ["surveycharge"] = 28800, ["grenade.f1"] = 28800, ["grenade.beancan"] = 28800,
                            }
                        }
                        , ["overdrive"] = new CategoryBlocked() {
                            titleCategory = new Dictionary<String, String>() {
                                ["ru"]
                                = "ПЕРЕГРЕВ", ["en"] = "OVERDRIVE",
                            }
                            , blockedsItems = new Dictionary<String, Int32>() {
                                ["rocket.launcher"]
                                = 36000, ["ammo.rocket.hv"] = 36000,
                            }
                        }
                        , ["ignition"] = new CategoryBlocked() {
                            titleCategory = new Dictionary<String, String>() {
                                ["ru"]
                                = "ВОЗГОРАНИЕ", ["en"] = "IGNITION",
                            }
                            , blockedsItems = new Dictionary<String, Int32>() {
                                ["hmlmg"]
                                = 72000, ["rifle.ak"] = 72000, ["multiplegrenadelauncher"] = 72000, ["rifle.lr300"] = 72000, ["rifle.bolt"] = 72000, ["rifle.l96"] = 72000, ["explosive.satchel"] = 72000, ["ammo.rifle.explosive"] = 72000, ["catapult"] = 72000, ["ballista.mounted"] = 72000, ["ballista.static"] = 72000, ["batteringram"] = 72000,
                            }
                        }
                        , ["breakthrough"] = new CategoryBlocked() {
                            titleCategory = new Dictionary<String, String>() {
                                ["ru"]
                                = "ПРОРЫВ", ["en"] = "BREAKTHROUGH",
                            }
                            , blockedsItems = new Dictionary<String, Int32>() {
                                ["lmg.m249"]
                                = 93600, ["minigun"] = 93600, ["ammo.rocket.basic"] = 93600, ["ammo.rocket.fire"] = 93600, ["ammo.rocket.mlrs"] = 93600, ["explosive.timed"] = 93600,
                            }
                        }
                        ,
                    }
                }
                ;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) LoadDefaultConfig();
                if (config.weaponAlias == null || config.weaponAlias.Count == 0) {
                    config.weaponAlias = new Dictionary<String, String>() {
                        ["rifle.ak.ice"]
                        = "rifle.ak", ["rifle.ak.diver"] = "rifle.ak", ["rifle.ak.med"] = "rifle.ak", ["rifle.ak.jungle"] = "rifle.ak", ["rocket.launcher.dragon"] = "rocket.launcher", ["metal.facemask.hockey"] = "metal.facemask", ["metal.facemask.icemask"] = "metal.facemask", ["metal.plate.torso.icevest"] = "metal.plate.torso", ["blunderbuss"] = "shotgun.double",
                    }
                    ;
                }
            }
            catch {
                PrintWarning(LanguageEn ? $"Error #54588528 reading configuration 'oxide/config/{Name}', creating a new configuration!!" : $"Ошибка #54588528 чтения конфигурации 'oxide/config/{Name}', создаём новую конфигурацию!!");
                LoadDefaultConfig();
            }
            NextTick(SaveConfig);
        }
        protected override void LoadDefaultConfig() => config = Configuration.GetNewConfiguration();
        protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Hooks
#region Action Hooks
#region Hooks Blocked
#region Flag Controller
        private void OnItemAction(Item? item, String action, BasePlayer player) {
            if (item == null || !player || !player.userID.IsSteamId() || String.IsNullOrWhiteSpace(action)) return;
            if (!action.Equals(actionDrop)) return;
            if (IsDuel(player) || IsIgnoreWipeBlock(player)) {
                SetOrRemoveFlag(item, false);
                return;
            }
            SetOrRemoveFlag(item, config.IsBlocked(item.info.itemid));
        }
        private void OnItemAddedToContainer(ItemContainer container, Item item) {
            BasePlayer player = container.playerOwner;
            if (!player || !player.userID.IsSteamId()) return;
            if (IsDuel(player) || IsIgnoreWipeBlock(player)) {
                SetOrRemoveFlag(item, false);
                return;
            }
            Boolean isBlocked = config.IsBlocked(item.info.itemid);
            if (isBlocked) {
                ItemContainer mainContainer = player.inventory.containerMain;
                Boolean isMainContainerFull = mainContainer.itemList.Count > 24;
                if (container == player.inventory.containerWear || container == player.inventory.containerBelt) {
                    if (isMainContainerFull) item.DropAndTossUpwards(player.transform.position);
                    else item.MoveToContainer(mainContainer);
                }
                else if (isMainContainerFull) {
                    item.DropAndTossUpwards(player.transform.position);
                }
            }
            SetOrRemoveFlag(item, isBlocked);
        }
#endregion
        private Object? OnWeaponReload(BaseProjectile weapon, BasePlayer player) => OnMagazineReload(weapon, player.inventory, player);
        private Object? OnMagazineReload(BaseProjectile weapon, IAmmoContainer desiredAmount, BasePlayer player) {
            if (!player || !player.userID.IsSteamId() || !weapon) return null;
            if (IsDuel(player) || IsIgnoreWipeBlock(player)) return null;
            if (weapon.primaryMagazine == null || !weapon.primaryMagazine.ammoType) return null;
            if (weapon.primaryMagazine.ammoType.itemid is 550753330 or -363689972) return null;
            weapon.SwitchAmmoTypesIfNeeded(player.inventory);
            weapon.SendNetworkUpdate();
            Boolean isActiveItemBlocked = false;
            Boolean isWeaponAmmoBlocked = config.IsBlocked(weapon.primaryMagazine.ammoType.itemid, out String timeToUnblock);
            String timeToUnblockActiveItem = String.Empty;
            Item? activeItem = player.GetActiveItem();
            if (activeItem != null && activeItem.info) isActiveItemBlocked = config.IsBlocked(activeItem.info.itemid, out timeToUnblockActiveItem);
            if (!isWeaponAmmoBlocked && !isActiveItemBlocked) return null;
            ItemDefinition? blockedItem = isWeaponAmmoBlocked ? weapon.primaryMagazine.ammoType : activeItem?.info;
            String unblockTime = isWeaponAmmoBlocked ? timeToUnblock : timeToUnblockActiveItem;
            if (blockedItem) SendPlayerNotify(player, blockedItem, unblockTime);
            return false;
        }
        private Object? OnRackedWeaponLoad(Item weapon, ItemDefinition itemDefinition, BasePlayer player, WeaponRack instance) {
            if (!player || !player.userID.IsSteamId()) return null;
            if (IsDuel(player) || IsIgnoreWipeBlock(player)) return null;
            if (!config.IsBlocked(itemDefinition.itemid, out String timeToUnblock)) return null;
            SendPlayerNotify(player, itemDefinition, timeToUnblock);
            return false;
        }
#endregion
#region [Harmony]Patch AutoTurret
        [HarmonyPatch(typeof(AutoTurret), "CanAcceptItem")]
        public class Patch_AutoTurret_CanAcceptItem {
            [HarmonyPostfix]
            public static void CanAcceptItem_Postfix(ref Boolean __result, Item item, Int32 targetSlot) {
                BasePlayer player = item.GetOwnerPlayer();
                if (!player) return;
                if (!__result || !config.IsBlocked(item.info.itemid, out String timeToUnblock) || _.IsDuel(player) || _.IsIgnoreWipeBlock(player)) return;
                SendPlayerNotify(player, item.info, timeToUnblock);
                __result = false;
            }
        }
#endregion
#region [Harmony]Patch AttackHelicopterTurret and AttackHelicopterRockets
        [HarmonyPatch(typeof(AttackHelicopterTurret), "CanAcceptItem")]
        public class Patch_AttackHelicopterTurret_CanAcceptItem {
            [HarmonyPostfix]
            public static void CanAcceptItem_Postfix(ref Boolean __result, Item item, Int32 targetSlot) {
                BasePlayer player = item.GetOwnerPlayer();
                if (!__result || !config.IsBlocked(item.info.itemid, out String timeToUnblock) || _.IsDuel(player) || _.IsIgnoreWipeBlock(player)) return;
                SendPlayerNotify(player, item.info, timeToUnblock);
                __result = false;
            }
        }
        [HarmonyPatch(typeof(AttackHelicopterRockets), "ItemFilter")]
        public class Patch_AttackHelicopterRockets_ItemFilter {
            [HarmonyPostfix]
            public static void ItemFilter_Postfix(ref Boolean __result, Item item, Int32 targetSlot) {
                BasePlayer player = item.GetOwnerPlayer();
                if (!__result || !config.IsBlocked(item.info.itemid, out String timeToUnblock) || _.IsDuel(player) || _.IsIgnoreWipeBlock(player)) return;
                SendPlayerNotify(player, item.info, timeToUnblock);
                __result = false;
            }
        }
#endregion
#region [Harmony]Patch MLRS AND SUBMARINE AND DRONE
        [HarmonyPatch(typeof(StorageContainer), "ItemFilter")]
        public class Patch_StorageContainer_ItemFilter {
            [HarmonyPostfix]
            public static void ItemFilter_Postfix(ref bool __result, Item item, int targetSlot, StorageContainer __instance) {
                if (__instance.prefabID is mlrs_rocket_storage or submarineTorpedoStorage or catapultAmmoStorage or droneAmmoStorage or droneAmmoStorageCooldown) {
                    BasePlayer player = item.GetOwnerPlayer();
                    if (!__result || !config.IsBlocked(item.info.itemid, out String timeToUnblock) || _.IsDuel(player) || _.IsIgnoreWipeBlock(player)) return;
                    SendPlayerNotify(player, item.info, timeToUnblock);
                    __result = false;
                }
            }
        }
#endregion
#region [Harmony]Patch CanEquipItem AND CanWearItem
        [HarmonyPatch]
        public class Patch_PlayerInventory {
            [HarmonyPatch(typeof(PlayerInventory), "CanEquipItem", typeof(Item), typeof(Int32))]
            [HarmonyPostfix]
            public static void CanEquipItem_Postfix(ref Boolean __result, Item item, Int32 targetSlot, PlayerInventory __instance) {
                if (!__result || !config.IsBlocked(item.info.itemid, out String timeToUnblock)) return;
                BasePlayer player = __instance.baseEntity;
                if (!player || !player.userID.IsSteamId()) return;
                if (_.IsDuel(player) || _.IsIgnoreWipeBlock(player)) return;
                SendPlayerNotify(player, item.info, timeToUnblock);
                __result = false;
            }
            [HarmonyPatch(typeof(PlayerInventory), "CanWearItem", typeof(Item), typeof(Int32))]
            [HarmonyPostfix]
            public static void CanWearItem_Postfix(ref Boolean __result, Item item, Int32 targetSlot, PlayerInventory __instance) {
                if (!__result || !config.IsBlocked(item.info.itemid, out String timeToUnblock)) return;
                BasePlayer player = __instance.baseEntity;
                if (!player || !player.userID.IsSteamId()) return;
                if (_.IsDuel(player) || _.IsIgnoreWipeBlock(player)) return;
                SendPlayerNotify(player, item.info, timeToUnblock);
                __result = false;
            }
        }
#endregion
#endregion
#region Server Hooks
        private void OnPlayerDisconnected(BasePlayer player, String reason) => DestroyTimerAlertUI(player, true);
        private void OnPlayerSleepEnded(BasePlayer player) {
            if (!player || !player.userID.IsSteamId() || player.IsDead()) return;
            DrawUI_FirstConnected(player);
        }
        private void Init() {
            _ = this;
            ReadData();
        }
        private void OnServerInitialized() {
            if (!permission.PermissionExists(permissionIgnore, this)) permission.RegisterPermission(permissionIgnore, this);
            config.InitializeCategory();
            UnsubscribeAllHook();
            if (config.IsFullUnBlocked()) {
                isFullUnblocked = true;
                Puts(LanguageEn ? "All items on the server have been unlocked; the plugin’s core functions will be disabled" : "Все предметы на сервере разблокированы, основные функции плагина будут отключены");
                HarmonyInstance.UnpatchAll(HarmonyInstance.Id);
                cmd.AddChatCommand(config.commandOpen, this, nameof(ChatCommandUnblockedAll));
                cmd.AddConsoleCommand(config.commandOpen, this, nameof(ConsoleCommandUnblockedAll));
            }
            else {
                _imageUI = new ImageUI();
                _imageUI.DownloadImage();
                LoadHarmony();
                SubscribeAllHook();
                cmd.AddChatCommand(config.commandOpen, this, nameof(DrawUI));
                cmd.AddConsoleCommand(config.commandOpen, this, nameof(ConsoleCommandOpenWipeBlockFast));
                timerChecker = timer.Every(60f, CheckUnblockedWipeBlock);
                Puts(LanguageEn ? "Item lock on the server is active; the plugin’s functions have started successfully" : "Блокировка предметов на сервере активна, функции плагина запущены успешно");
            }
        }
        private void Unload() {
            if (_ == null) return;
            HarmonyInstance?.UnpatchAll(HarmonyInstance.Id);
            if (elementPositionsBlock != null) {
                elementPositionsBlock.Clear();
                elementPositionsBlock = null;
            }
            if (timerChecker is {
                Destroyed : false
            }
            ) {
                timerChecker.Destroy();
                timerChecker = null;
            }
            if (_imageUI != null) {
                _imageUI.UnloadImages();
                _imageUI = null;
            }
            foreach (BasePlayer player in BasePlayer.activePlayerList) {
                DestroyUI(player, mainLayer);
                DestroyUI(player, fastButtonLayer);
                DestroyTimerAlertUI(player, true);
            }
            timerAlertConnection.Clear();
            timerAlertConnection = null;
            drawedAlertButton.Clear();
            drawedAlertButton = null;
            _ = null;
        }
#endregion
#endregion
#region Commands
        [ConsoleCommand("update.ui.item")]
        private void UI_FuncionalCommands(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (!player) return;
            if (!Int32.TryParse(arg.Args[0], out Int32 itemID)) return;
            String parentLayer = arg.Args[1];
            String layerName = arg.Args[2];
            if (config.IsBlocked(itemID)) return;
            UpdateUnblockBlockItem(player, parentLayer, layerName);
        }
        [ConsoleCommand("open.wipeblock.firts.alert")]
        private void ConsoleCommandOpenWipeBlock(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if(!player) return;
            DestroyTimerAlertUI(player, false);
            DrawUI_WipeBlockFastButton(player);
            DrawUI(player);
        }
        private void ConsoleCommandOpenWipeBlockFast(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if(!player) return;
            DrawUI(player);
        }
        private void ConsoleCommandUnblockedAll(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (!player) return;
            SendChat(GetLang("WIPEBLOCK_DISABLED", player.UserIDString), player);
        }
        private void ChatCommandUnblockedAll(BasePlayer player, String cmd, String[] arg) => SendChat(GetLang("WIPEBLOCK_DISABLED", player.UserIDString), player);
        [ConsoleCommand("a.wipeblock")]
        private void WipeBlockAdminCommands(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if(player) if (!player.IsAdmin) return;
            String action = arg.Args[0];
            switch (action) {
                case "reset" : {
                    timeCorrectedWipe = 0;
                    WriteData();
                    PrintWarning(LanguageEn ? "The wipe time has been reset to default settings; the plugin will be reloaded" : "Время вайпа было вернуто к стандартным настройка, плагин будет перезагружен");
                    Interface.Oxide.ReloadPlugin(this.Name);
                    break;
                }
                case "corrected" : {
                    Int32 wipeCorrectedSeconds = Int32.Parse(arg.Args[1]);
                    timeCorrectedWipe = wipeCorrectedSeconds;
                    WriteData();
                    PrintWarning(LanguageEn ? $"The wipe time has been adjusted to: {timeCorrectedWipe}; the plugin will be reloaded" : $"Время вайпа было скорректировано, значение : {timeCorrectedWipe}, плагин будет перезагружен");
                    Interface.Oxide.ReloadPlugin(this.Name);
                    break;
                }
            }
        }
#endregion
#region UI
        private static void DestroyUI(BasePlayer player, String elementName) => CommunityEntity.ServerInstance.ClientRPC<String>(RpcTarget.Player("DestroyUI", player.net.connection), elementName);
        private static void AddUI(BasePlayer player, String json) => CommunityEntity.ServerInstance.ClientRPC<String>(RpcTarget.Player("AddUI", player.net.connection), json);
#region First Connected Alert
        private void DrawUI_FirstConnected(BasePlayer player) {
            if (isFullUnblocked) return;
            if (!player) return;
            if (!config.useFirstAlert) {
                DrawUI_WipeBlockFastButton(player);
                return;
            }
            if (timerAlertConnection.ContainsKey(player.userID)) {
                if (timerAlertConnection[player.userID] != null && !timerAlertConnection[player.userID].Destroyed) return;
                DrawUI_WipeBlockFastButton(player);
                return;
            }
            CuiElementContainer container = new();
            container.Add(new CuiElement {
                Parent = "Overlay", Name = firstConnectedLayer, DestroyUi = firstConnectedLayer, Components = {
                    new CuiScrollViewComponent {
                        MovementType = ScrollRect.MovementType.Elastic, Horizontal = true, Elasticity = 0.5f, Inertia = true, ScrollSensitivity = 5f, ContentTransform = new CuiRectTransform {
                            AnchorMin = "-80 1", AnchorMax = "-80 1", OffsetMax = "222.335 0", Pivot = "0.5 1"
                        }
                        ,
                    }
                    , new CuiRawImageComponent {
                        Color = "0 0 0 0"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-225.3 -83.4", OffsetMax = "0 -20.4"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = firstConnectedLayer, Name = "PANEL_CONNECTED_ALERT_WIPEBLOCK", DestroyUi = "PANEL_CONNECTED_ALERT_WIPEBLOCK", Components = {
                    new CuiRawImageComponent {
                        Color = "1 1 1 1", Png = _imageUI.GetImage("UI_CONNECTED_ALERT")
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-225.3 -63", OffsetMax = "-31.3 0"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "PANEL_CONNECTED_ALERT_WIPEBLOCK", Name = "PROGRESS_BAR_ALERT_WIPEBLOCK", DestroyUi = "PROGRESS_BAR_ALERT_WIPEBLOCK", Components = {
                    new CuiImageComponent {
                        Color = colorProgressBar
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-93.511 3.482", OffsetMax = "93.321 6.458"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "PANEL_CONNECTED_ALERT_WIPEBLOCK", Name = "TITLE_WIPEBLOCK_ALERT", DestroyUi = "TITLE_WIPEBLOCK_ALERT", Components = {
                    new CuiTextComponent {
                        Text = GetLang("TITLE_ALERT_FIRST_CONNECTED", player.UserIDString), Align = TextAnchor.MiddleRight, FontSize = 14, Font = "robotocondensed-regular.ttf", Color = colorText
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-147.941 -3.199", OffsetMax = "-12.471 22.339"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "PANEL_CONNECTED_ALERT_WIPEBLOCK", Name = "DESCRIPTION_WIPEBLOCK_ALERT", DestroyUi = "DESCRIPTION_WIPEBLOCK_ALERT", Components = {
                    new CuiTextComponent {
                        Text = GetLang("TITLE_ALERT_FIRST_CONNECTED_BUTTON", player.UserIDString), Align = TextAnchor.MiddleRight, FontSize = 16, Font = "robotocondensed-bold.ttf", Color = colorText
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-147.941 -19.499", OffsetMax = "-12.471 6.039"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "PANEL_CONNECTED_ALERT_WIPEBLOCK", Name = "OPEN_WIPEBLOCK_IN_ALERT", DestroyUi = "OPEN_WIPEBLOCK_IN_ALERT", Components = {
                    new CuiButtonComponent {
                        Color = "0 0 0 0", Command = "open.wipeblock.firts.alert"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            AddUI(player, container.ToJson());
            Int32 secondAlert = 60;
            Timer timerUpdateBar = timer.Every(1f, () => {
                secondAlert--;
                Update_ProgressBarFirstConnceted(player, secondAlert);
            }
            );
            timerAlertConnection.Add(player.userID, timerUpdateBar);
        }
        private void Update_ProgressBarFirstConnceted(BasePlayer player, Int32 secondLeft) {
            if (secondLeft <= 0) {
                DestroyTimerAlertUI(player, false);
                DrawUI_WipeBlockFastButton(player);
                return;
            }
            CuiElementContainer container = new();
            container.Add(new CuiElement {
                Parent = firstConnectedLayer, Name = "PROGRESS_BAR_ALERT_WIPEBLOCK", Update = true, Components = {
                    new CuiRectTransformComponent {
                        OffsetMax = $"{CalculateOffsetMaxX()} 6.458"
                    }
                }
            }
            );
            AddUI(player, container.ToJson());
            return;
            Single CalculateOffsetMaxX() {
                const Single min = -93.321f;
                const Single max = 93.321f;
                const Single range = max - min;
                return min + ((secondLeft / 60.0f) * range);
            }
        }
#endregion
#region WipeBlock Fast Button
        private void DrawUI_WipeBlockFastButton(BasePlayer player) {
            if (isFullUnblocked) return;
            if (!config.useFastButton) return;
            if (drawedAlertButton.Contains(player.userID)) return;
            drawedAlertButton.Add(player.userID);
            CuiElementContainer container = new();
            container.Add(new CuiElement {
                Parent = "Overlay", Name = fastButtonLayer, DestroyUi = fastButtonLayer, Components = {
                    new CuiScrollViewComponent {
                        MovementType = ScrollRect.MovementType.Elastic, Horizontal = true, Elasticity = 0.5f, Inertia = true, ScrollSensitivity = 5f, ContentTransform = new CuiRectTransform {
                            AnchorMin = "-80 1", AnchorMax = "-80 1", OffsetMax = "275.335 0", Pivot = "0.5 1"
                        }
                        ,
                    }
                    , new CuiRawImageComponent {
                        Color = "0 0 0 0"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-275.3 -101.4", OffsetMax = "0 -20.4"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = fastButtonLayer, Name = "FAST_BUTTON_PANEL_BACKGORUND", DestroyUi = "FAST_BUTTON_PANEL_BACKGORUND", Components = {
                    new CuiRawImageComponent {
                        Color = "1 1 1 1", Png = _imageUI.GetImage("UI_FAST_BUTTON_PANEL")
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-275.3 -81", OffsetMax = "-31.3 0"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "FAST_BUTTON_PANEL_BACKGORUND", Name = "TITLE_WIPEBLOCK_FAST_BUTTON", DestroyUi = "TITLE_WIPEBLOCK_FAST_BUTTON", Components = {
                    new CuiTextComponent {
                        Text = GetLang("TITLE_FAST_BUTTON", player.UserIDString), Align = TextAnchor.UpperLeft, FontSize = 16, Font = "robotocondensed-bold.ttf", Color = colorText
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "13.41 8.493", OffsetMax = "205.27 32.307"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "FAST_BUTTON_PANEL_BACKGORUND", Name = "DESCRIPTION_WIPEBLOCK_FAST_BUTTON", DestroyUi = "DESCRIPTION_WIPEBLOCK_FAST_BUTTON", Components = {
                    new CuiTextComponent {
                        Text = GetLang("DESCRIPTION_FAST_BUTTON", player.UserIDString, config.commandOpen), Align = TextAnchor.UpperLeft, FontSize = 12, Font = "robotocondensed-regular.ttf", Color = colorText
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "13.41 -35.542", OffsetMax = "231.53 5.542"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "FAST_BUTTON_PANEL_BACKGORUND", Name = "OPEN_WIPEBLOCK_IN_ALERT", DestroyUi = "OPEN_WIPEBLOCK_IN_ALERT", Components = {
                    new CuiButtonComponent {
                        Color = "0 0 0 0", Command = config.commandOpen
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "FAST_BUTTON_PANEL_BACKGORUND", Name = "CLOSE_PNG_FAST_BUTTON", DestroyUi = "CLOSE_PNG_FAST_BUTTON", Components = {
                    new CuiRawImageComponent {
                        Color = "1 1 1 1", Png = _imageUI.GetImage("UI_CLOSE_BUTTON")
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-26.47 -23.2", OffsetMax = "-12.47 -9.2"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = "CLOSE_PNG_FAST_BUTTON", Name = "CLOSE_BUTTON_WIPEBLOCK_BTN_FAST_BUTTON", DestroyUi = "CLOSE_BUTTON_WIPEBLOCK_BTN_FAST_BUTTON", Components = {
                    new CuiButtonComponent {
                        Color = "0 0 0 0", Close = fastButtonLayer
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            AddUI(player, container.ToJson());
        }
#endregion
        private void DrawUI(BasePlayer player) {
            CuiElementContainer container = new();
            container.Add(new CuiElement {
                Parent = "Overlay", Name = mainLayer, DestroyUi = mainLayer, Components = {
                    new CuiImageComponent {
                        Color = "0.271 0.271 0.271 0.3", Material = "assets/content/ui/uibackgroundblur.mat", Sprite = "assets/content/ui/UI.Background.TileTex.psd"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = mainLayer, Name = "CLOSE_BUTTON_WIPEBLOCK", DestroyUi = "CLOSE_BUTTON_WIPEBLOCK", Components = {
                    new CuiButtonComponent {
                        Color = "0 0 0 0", Close = mainLayer
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            container.Add(new CuiElement {
                Parent = mainLayer, Name = layerWipeBlock, DestroyUi = layerWipeBlock, Components = {
                    new CuiNeedsCursorComponent() {
                    }
                    , new CuiImageComponent {
                        Color = "0 0 0 0"
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-385 -266.5", OffsetMax = "385 266.5"
// ... [Code preview truncated due to length. Full source in attached file] ...

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