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

FREE ServerPanel : 1.1.1 1.1.1

Нет прав для скачивания
C#:
// #define TESTING
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.ServerPanelExtensionMethods;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;
#if CARBON
using Carbon.Base;
using Carbon.Modules;
#endif
namespace Oxide.Plugins {
    [Info("ServerPanel", "Mevent", "1.1.1")]
    public class ServerPanel : RustPlugin {
#region Fields
        [PluginReference]
        private Plugin ImageLibrary = null, NoEscape = null, Notify = null, UINotify = null, KillRecords = null, Statistics = null;
        private static ServerPanel Instance;
#if CARBON
        private ImageDatabaseModule imageDatabase;
#endif
        private bool _enabledImageLibrary;
        private Dictionary<int, int> _categoriesByID = new();
        private Dictionary<string, int> _categoriesByCommand = new();
        private Dictionary<int, Coroutine> _categoriesActiveCoroutines = new();
        private Dictionary<string, Func<BasePlayer, string>> _headerUpdateFields = new();
        private const string Perm_Edit = "serverpanel.edit", CmdMainConsole = "UI_ServerPanel", Layer = "UI.Server.Panel", LayerHeader = "UI.Server.Panel.Header", LayerContent = "UI.Server.Panel.Content", LayerCategories = "UI.Server.Panel.Categories", EditingLayerPageEditor = "UI.Server.Panel.Editor.Page", EditingLayerElementEditor = "UI.Server.Panel.Editor.Element", EditingLayerModal = "UI.Server.Panel.Editor.Modal", EditingLayerModalArrayView = EditingLayerModal + ".Content.View", EditingLayerModalAnchorSelector = "UI.Server.Panel.Editor.Modal.Anchor.Selector", EditingLayerModalColorSelector = "UI.Server.Panel.Editor.Modal.Color.Selector", EditingLayerModalTextEditor = "UI.Server.Panel.Editor.Modal.Text.Editor", EditingElementOutline = "UI.Server.Panel.Editor.EditingElement.Outline";
        private Dictionary<(float AnchorMinX, float AnchorMinY, float AnchorMaxX, float AnchorMaxY), string> rectToImage = new() {
            [(0, 1, 0, 1)]
            = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/top-left.png", [(0.5f, 1, 0.5f, 1)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/top-center.png", [(1, 1, 1, 1)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/top-right.png", [(0, 0.5f, 0, 0.5f)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/middle-left.png", [(0.5f, 0.5f, 0.5f, 0.5f)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/middle-center.png", [(1, 0.5f, 1, 0.5f)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/middle-right.png", [(0, 0, 0, 0)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/bottom-left.png", [(0.5f, 0, 0.5f, 0)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/bottom-center.png", [(1, 0, 1, 0)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/bottom-right.png", [(0, 1, 1, 1)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/top-stretch.png", [(0, 0, 0, 1)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/stretch-left.png", [(0.5f, 0, 0.5f, 1)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/stretch-center.png", [(1, 0, 1, 1)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/stretch-right.png", [(0, 0, 1, 1)] = "https://gitlab.com/TheMevent/PluginsStorage/raw/main/Images/Anchors/stretch-stretch.png",
        }
        ;
#endregion
#region Config
        private static Configuration _config;
        private class Configuration {
#region Fields
            [JsonProperty(PropertyName = "Work with Notify?")]
            public bool UseNotify = true;
            [JsonProperty(PropertyName = "Economy Header Fields", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<EconomyHeadField> EconomyFields = new() {
                EconomyHeadField.Create(true, EconomyEntry.CreateEconomics(), "{economy_economics}"), EconomyHeadField.Create(true, EconomyEntry.CreateServerRewards(), "{economy_server_rewards}"), EconomyHeadField.Create(true, EconomyEntry.CreateBankSystem(), "{economy_bank_system}"),
            }
            ;
            [JsonProperty(PropertyName = "Block Settings")]
            public BlockSettings Block = new() {
                BlockWhenBuildingBlock = false, BlockWhenRaidBlock = false, BlockWhenCombatBlock = false
            }
            ;
            [JsonProperty(PropertyName = "Auto-Open Settings")]
            public AutoOpenSettings AutoOpen = new() {
                ShowMenuEveryTime = true
            }
            ;
#endregion Fields
#region Classes
            public class AutoOpenSettings {
                [JsonProperty(PropertyName = "Show menu every time player connects to server?")]
                public bool ShowMenuEveryTime = true;
            }
            public class BlockSettings {
                [JsonProperty(PropertyName = "Block the opening during a building block?")]
                public bool BlockWhenBuildingBlock;
                [JsonProperty(PropertyName = "Block the opening during a raid block?")]
                public bool BlockWhenRaidBlock;
                [JsonProperty(PropertyName = "Block the opening during a combat block?")]
                public bool BlockWhenCombatBlock;
            }
            public class EconomyHeadField {
#region Fields
                [JsonProperty(PropertyName = "Enabled")]
                public bool Enabled;
                [JsonProperty(PropertyName = "Economy Settings")]
                public EconomyEntry Economy = new();
                [JsonProperty(PropertyName = "Update key (MUST BE UNIQUE)")]
                public string UpdateKey;
#endregion
#region Constructors
                public static EconomyHeadField Create(bool enabled, EconomyEntry economy, string updateKey) {
                    return new EconomyHeadField {
                        Enabled = enabled, Economy = economy, UpdateKey = updateKey
                    }
                    ;
                }
#endregion
            }
            public enum EconomyType {
                Plugin, Item
            }
            public class EconomyEntry {
#region Fields
                [JsonProperty(PropertyName = "Type (Plugin/Item)")]
                [JsonConverter(typeof(StringEnumConverter))]
                public EconomyType Type;
                [JsonProperty(PropertyName = "Plugin name")]
                public string Plug;
                [JsonProperty(PropertyName = "Balance add hook")]
                public string AddHook;
                [JsonProperty(PropertyName = "Balance remove hook")]
                public string RemoveHook;
                [JsonProperty(PropertyName = "Balance show hook")]
                public string BalanceHook;
                [JsonProperty(PropertyName = "ShortName")]
                public string ShortName;
                [JsonProperty(PropertyName = "Display Name (empty - default)")]
                public string DisplayName;
                [JsonProperty(PropertyName = "Skin")]
                public ulong Skin;
                [JsonProperty(PropertyName = "Lang Key (for Title)")]
                public string TitleLangKey;
                [JsonProperty(PropertyName = "Lang Key (for Balance)")]
                public string BalanceLangKey;
#endregion Fields
#region Public Methods
#region Titles
                public string GetTitle(BasePlayer player) {
                    return Instance.Msg(player, TitleLangKey);
                }
                public string GetBalanceTitle(BasePlayer player) {
                    return Instance.Msg(player, BalanceLangKey, ShowBalance(player).ToString());
                }
#endregion Titles
#region Economy
                public double ShowBalance(BasePlayer player) {
                    switch (Type) {
                        case EconomyType.Plugin : {
                            var plugin = Instance?.plugins?.Find(Plug);
                            if (plugin == null) return 0;
                            return Convert.ToDouble(plugin.Call(BalanceHook, player.UserIDString));
                        }
                        case EconomyType.Item : {
                            return PlayerItemsCount(player, ShortName, Skin);
                        }
                        default : return 0;
                    }
                }
                public void AddBalance(BasePlayer player, double amount) {
                    switch (Type) {
                        case EconomyType.Plugin : {
                            var plugin = Instance?.plugins?.Find(Plug);
                            if (plugin == null) return;
                            switch (Plug) {
                                case "BankSystem" : case "ServerRewards" : case "IQEconomic" : plugin.Call(AddHook, player.UserIDString, (int) amount);
                                break;
                                default : plugin.Call(AddHook, player.UserIDString, amount);
                                break;
                            }
                            break;
                        }
                        case EconomyType.Item : {
                            var am = (int) amount;
                            var item = ToItem(am);
                            if (item == null) return;
                            player.GiveItem(item);
                            break;
                        }
                    }
                }
                public bool RemoveBalance(BasePlayer player, double amount) {
                    switch (Type) {
                        case EconomyType.Plugin : {
                            if (ShowBalance(player) < amount) return false;
                            var plugin = Instance?.plugins.Find(Plug);
                            if (plugin == null) return false;
                            switch (Plug) {
                                case "BankSystem" : case "ServerRewards" : case "IQEconomic" : plugin.Call(RemoveHook, player.UserIDString, (int) amount);
                                break;
                                default : plugin.Call(RemoveHook, player.UserIDString, amount);
                                break;
                            }
                            return true;
                        }
                        case EconomyType.Item : {
                            var playerItems = Pool.Get<List<Item>>();
                            player.inventory.GetAllItems(playerItems);
                            var am = (int) amount;
                            if (ItemCount(playerItems, ShortName, Skin) < am) {
                                Pool.Free(ref playerItems);
                                return false;
                            }
                            Take(playerItems, ShortName, Skin, am);
                            Pool.Free(ref playerItems);
                            return true;
                        }
                        default : return false;
                    }
                }
#endregion Economy
#endregion
#region Private Methods
                private Item ToItem(int amount) {
                    var item = ItemManager.CreateByName(ShortName, amount, Skin);
                    if (item == null) {
                        Debug.LogError($"Error creating item with ShortName: '{ShortName}'");
                        return null;
                    }
                    if (!string.IsNullOrEmpty(DisplayName)) item.name = DisplayName;
                    return item;
                }
                private static int PlayerItemsCount(BasePlayer player, string shortname, ulong skin) {
                    var items = Pool.Get<List<Item>>();
                    player.inventory.GetAllItems(items);
                    var result = ItemCount(items, shortname, skin);
                    Pool.Free(ref items);
                    return result;
                }
                private static int ItemCount(List<Item> items, string shortname, ulong skin) {
                    return items.FindAll(item => item.info.shortname == shortname && !item.isBroken && (skin == 0 || item.skin == skin)).Sum(item => item.amount);
                }
                private static void Take(List<Item> itemList, string shortname, ulong skinId, int amountToTake) {
                    if (amountToTake == 0) return;
                    var takenAmount = 0;
                    var itemsToTake = Pool.Get<List<Item>>();
                    foreach (var item in itemList) {
                        if (item.info.shortname != shortname || (skinId != 0 && item.skin != skinId) || item.isBroken) continue;
                        var remainingAmount = amountToTake - takenAmount;
                        if (remainingAmount <= 0) break;
                        if (item.amount > remainingAmount) {
                            item.MarkDirty();
                            item.amount -= remainingAmount;
                            break;
                        }
                        if (item.amount <= remainingAmount) {
                            takenAmount += item.amount;
                            itemsToTake.Add(item);
                        }
                        if (takenAmount == amountToTake) break;
                    }
                    foreach (var itemToTake in itemsToTake) itemToTake.RemoveFromContainer();
                    Pool.FreeUnmanaged(ref itemsToTake);
                }
#endregion Private Methods
#region Constructors
                public static EconomyEntry CreateEconomics() {
                    return new EconomyEntry {
                        Type = EconomyType.Plugin, Plug = "Economics", TitleLangKey = "Economy.Economics.Title", BalanceLangKey = "Economy.Economics.Balance", AddHook = "Deposit", BalanceHook = "Balance", RemoveHook = "Withdraw", ShortName = string.Empty, DisplayName = string.Empty, Skin = 0,
                    }
                    ;
                }
                public static EconomyEntry CreateServerRewards() {
                    return new EconomyEntry {
                        Type = EconomyType.Plugin, Plug = "ServerRewards", TitleLangKey = "Economy.ServerRewards.Title", BalanceLangKey = "Economy.ServerRewards.Balance", AddHook = "AddPoints", BalanceHook = "CheckPoints", RemoveHook = "TakePoints", ShortName = string.Empty, DisplayName = string.Empty, Skin = 0,
                    }
                    ;
                }
                public static EconomyEntry CreateBankSystem() {
                    return new EconomyEntry {
                        Type = EconomyType.Plugin, Plug = "BankSystem", TitleLangKey = "Economy.BankSystem.Title", BalanceLangKey = "Economy.BankSystem.Balance", AddHook = "API_BankSystemDeposit", BalanceHook = "API_BankSystemBalance", RemoveHook = "API_BankSystemWithdraw", ShortName = string.Empty, DisplayName = string.Empty, Skin = 0,
                    }
                    ;
                }
                public static EconomyEntry CreateIQEconomic() {
                    return new EconomyEntry {
                        Type = EconomyType.Plugin, Plug = "IQEconomic", TitleLangKey = "Economy.IQEconomic.Title", BalanceLangKey = "Economy.IQEconomic.Balance", AddHook = "API_SET_BALANCE", BalanceHook = "API_GET_BALANCE", RemoveHook = "API_REMOVE_BALANCE", ShortName = string.Empty, DisplayName = string.Empty, Skin = 0,
                    }
                    ;
                }
                public static EconomyEntry CreateScrap() {
                    return new EconomyEntry {
                        Type = EconomyType.Item, Plug = string.Empty, TitleLangKey = "Economy.Scrap.Title", BalanceLangKey = "Economy.Scrap.Balance", AddHook = string.Empty, BalanceHook = string.Empty, RemoveHook = string.Empty, ShortName = "scrap", DisplayName = string.Empty, Skin = 0,
                    }
                    ;
                }
#endregion Constructors
            }
#endregion
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) throw new Exception();
                SaveConfig();
            }
            catch {
                PrintError("Your configuration file contains an error.Using default configuration values.");
                LoadDefaultConfig();
            }
        }
        protected override void SaveConfig() {
            Config.WriteObject(_config);
        }
        protected override void LoadDefaultConfig() {
            _config = new Configuration();
        }
#endregion Config
#region Data
#region Data.General
        public void SaveData() {
            SaveCategoriesData();
            SaveTemplateData();
            SaveLocalizationData();
            SaveHeaderFieldsData();
            SavePlayersData();
        }
        private void LoadData() {
            LoadCategoriesData();
            LoadTemplateData();
            LoadLocalizationData();
            LoadHeaderFieldsData();
            LoadPlayersData();
        }
        private void LoadDataFromFile<T>(ref T data, string filePath) {
            try {
                data = Interface.Oxide.DataFileSystem.ReadObject<T>(filePath);
            }
            catch (Exception e) {
                PrintError(e.ToString());
            }
            data ??= Activator.CreateInstance<T>();
        }
        private void SaveDataToFile<T>(T data, string filePath) {
            Interface.Oxide.DataFileSystem.WriteObject(filePath, data);
        }
#endregion Data.General
#region Data.Categories
        private static CategoriesData _categoriesData;
        private class CategoriesData {
            [JsonProperty(PropertyName = "Categories", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<MenuCategory> Categories = new();
        }
        private void LoadCategoriesData() => LoadDataFromFile(ref _categoriesData, $"{Name}/Categories");
        private void SaveCategoriesData() => SaveDataToFile(_categoriesData, $"{Name}/Categories");
#endregion Data.Categories
#region Data.Template
        private static TemplateData _templateData;
        private void SaveTemplateData() => SaveDataToFile(_templateData, $"{Name}/Template");
        private void LoadTemplateData() => LoadDataFromFile(ref _templateData, $"{Name}/Template");
        private class TemplateData {
#region Fields
            [JsonProperty(PropertyName = "Use an expert mod?")]
            public bool UseExpertMod = false;
            [JsonProperty(PropertyName = "UI Settings")]
            public UISettings UI = default;
#endregion
#region Public Methods
            public void ShowEditPageButtonsUI(BasePlayer player, CuiElementContainer container, string parent, string cmdAddPage = "", string cmdRemovePage = "") {
#region Add Page
                container.Add(new CuiButton {
                    Button = {
                        Color = "0 0.372549 0.7176471 1", Command = cmdAddPage
                    }
                    , Text = {
                        Text = "+ NEW PAGE", Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8862745 0.8588235 0.827451 1"
                    }
                    , RectTransform = {
                        AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "22 10", OffsetMax = "148 40"
                    }
                }
                , parent);
#endregion
#region Remove Page
                container.Add(new CuiButton {
                    Button = {
                        Color = "0.8117647 0.2627451 0.1764706 1", Command = cmdRemovePage
                    }
                    , Text = {
                        Text = "DELETE PAGE", Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter, Color = "0.8862745 0.8588235 0.827451 1"
                    }
                    , RectTransform = {
                        AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "158 10", OffsetMax = "284 40"
                    }
                }
                , parent);
#endregion
            }
            public void ShowContentUI(BasePlayer player, CuiElementContainer container, string cmdPage = "", Action<string> callback = null) {
                if (!TryGetOpenedMenu(player.userID, out var openedMenu)) return;
                var menuCategory = Instance.GetCategoryById(openedMenu.SelectedCategory);
                var page = openedMenu.PageIndex;
                var maxPages = menuCategory.Pages.Count;
                UI.Content.Background.Get(ref container, player, Layer, LayerContent, destroy : LayerContent);
                var categoryPage = menuCategory?.Pages[page];
                if (categoryPage != null) {
                    switch (categoryPage.Type) {
                        case CategoryPage.PageType.Plugin : {
                            var elements = categoryPage.Plugin?.Call<CuiElementContainer>(categoryPage.PluginHook, player);
                            if (elements != null) {
                                container.AddRange(elements);
                            }
                            break;
                        }
                        case CategoryPage.PageType.UI : {
                            categoryPage.Elements?.ForEach(element => element?.Get(ref container, player, LayerContent, element.Name, textFormatter : text => Instance.FormatUpdateField(player, text)));
                            // categoryPage.Elements?.ForEach(element => element?.Get(ref container, player, LayerContent, element.Name));
                            if (menuCategory.ShowPages) UI.Content.Pagination.ShowPagination(player, container, LayerContent, page, maxPages, LayerContent + ".Navigation", cmdPage);
                            if (CanPlayerEdit(player)) {
                                UI.Content.EditButton.ShowEditButtonUI(player, container, LayerContent, cmdEdit : $"{CmdMainConsole} edit_page start {menuCategory.ID} {page}");
                                ShowEditPageButtonsUI(player, container, LayerContent, cmdAddPage : $"{CmdMainConsole} edit_page add {menuCategory.ID} {page}", cmdRemovePage : $"{CmdMainConsole} edit_page remove {menuCategory.ID} {page}");
                            }
                            break;
                        }
                    }
                }
                callback?.Invoke(LayerContent);
            }
            public void ShowCloseButtonUI(BasePlayer player, CuiElementContainer container, string parent, string closeLayer = "", string command = "") {
                UI.CloseButton.ShowButtonUI(player, container, parent, parent + ".CloseButton", closeLayer : closeLayer, command : command);
            }
            public void ShowBackgroundUI(BasePlayer player, CuiElementContainer container, string cmdOnClick = "") {
                UI.Background.Background.Get(ref container, player, UI.Background.ParentLayer, Layer, destroy : Layer);
                if (UI.Background.CloseAfterClick) {
                    container.Add(new CuiElement() {
                        Parent = Layer, Components = {
                            new CuiButtonComponent() {
                                Color = "0 0 0 0", Close = Layer, Command = cmdOnClick
                            }
                            , new CuiRectTransformComponent()
                        }
                    }
                    );
                }
            }
            public void ShowHeaderUI(BasePlayer player, CuiElementContainer container) {
                UI.Header.Background.Get(ref container, player, Layer, LayerHeader, destroy : LayerHeader);
                foreach (var headerField in _headerFieldsData.Fields) headerField.Get(ref container, player, LayerHeader, headerField.Name, destroy : headerField.Name, textFormatter : text => Instance.FormatUpdateField(player, text));
            }
            public void UpdateGlobalHeaderUI(BasePlayer player, CuiElementContainer container) {
                foreach (var headerField in _headerFieldsData.Fields) headerField.Get(ref container, player, LayerHeader, headerField.Name, textFormatter : text => Instance.FormatUpdateField(player, text), needUpdate : true);
            }
            public void UpdateHeaderUI(BasePlayer player, CuiElementContainer container) {
                foreach (var headerField in _headerFieldsData.elementsToUpdate) headerField.Get(ref container, player, LayerHeader, headerField.Name, destroy : headerField.Name, textFormatter : text => Instance.FormatUpdateField(player, text));
            }
            public void ShowUpdateHeaderUI(BasePlayer player) {
                UpdateUI(player, container => {
                    UpdateHeaderUI(player, container);
                }
                );
            }
            public void ShowCategories(BasePlayer player, CuiElementContainer container) {
                UI.Categories.Background.Get(ref container, player, Layer, LayerCategories, destroy : LayerCategories);
                container.Add(new CuiElement() {
                    Name = Layer + ".Scroll.Panel", DestroyUi = Layer + ".Scroll.Panel", Parent = LayerCategories, Components = {
                        new CuiImageComponent() {
                            Color = "0 0 0 0"
                        }
                        , UI.Categories.CategoriesScroll.GetRectTransform()
                    }
                }
                );
                ShowCategoriesScrollUI(player, container);
            }
            public void ShowCategoriesScrollUI(BasePlayer player, CuiElementContainer container, bool needUpdate = false) {
                var targetCategoriesCount = _categoriesData.Categories.Count;
                if (CanPlayerEdit(player)) targetCategoriesCount += 2;
                var totalWidth = targetCategoriesCount * UI.Categories.CategoryWidth + (targetCategoriesCount - 1) * UI.Categories.CategoriesMargin;
                if (UI.Categories.UseScrolling) {
                    container.Add(new CuiElement {
                        Name = Layer + ".Scroll.View", DestroyUi = Layer + ".Scroll.View", Parent = Layer + ".Scroll.Panel", Update = needUpdate, Components = {
                            UI.Categories.CategoriesScroll.GetScrollView(CalculateContentRectTransform(totalWidth)),
                        }
                    }
                    );
                }
                else {
                    container.Add(new CuiElement {
                        Name = Layer + ".Scroll.View", DestroyUi = Layer + ".Scroll.View", Parent = Layer + ".Scroll.Panel", Update = needUpdate, Components = {
                            new CuiImageComponent() {
                                Color = "0 0 0 0"
                            }
                            , new CuiRectTransformComponent()
                        }
                    }
                    );
                }
                ShowCategoriesLoopUI(player, container);
            }
            public void ShowCategoriesLoopUI(BasePlayer player, CuiElementContainer container) {
                if (!TryGetOpenedMenu(player.userID, out var openedMenu)) return;
                var selectedCategory = openedMenu.SelectedCategory;
                var mainOffset = UI.Categories.CategoriesIndent;
                foreach (var menuCategory in _categoriesData.Categories) {
                    var isSelected = selectedCategory == menuCategory.ID;
                    var categoryButton = Layer + ".Scroll.View" + $".Category.{menuCategory.ID}";
                    container.Add(new CuiElement() {
                        Name = categoryButton, DestroyUi = categoryButton, Parent = Layer + ".Scroll.View", Components = {
                            GetCategoriesButtonComponent(isSelected, menuCategory), CalculateCategoriesPosition(mainOffset, UI.Categories.CategoryWidth, UI.Categories.CategoryHeight)
                        }
                    }
                    );
                    UI.Categories.CategoryTitle.Get(player, container, categoryButton, text : Instance.Msg(player, menuCategory.Title), isSelected : isSelected);
                    if (UI.Categories.ShowSelectedElement && isSelected) UI.Categories.SelectedElement.Get(ref container, player, categoryButton);
                    if (UI.Categories.CategoryTitle.UseIcon && !string.IsNullOrEmpty(menuCategory.Icon)) UI.Categories.CategoryTitle.Icon.Get(ref container, player, categoryButton, textFormatter : menuIcon => menuCategory.Icon);
                    if (UI.Categories.CategoryTitle.UseOutline) (isSelected ? UI.Categories.CategoryTitle.SelectedOutline : UI.Categories.CategoryTitle.Outline).ShowOutlineUI(player, container, categoryButton);
                    if (openedMenu.isEditMode) UI.Categories.CategoryEditPanel.GetCategoriesEditPanel(player, ref container, categoryButton, categoryButton + ".Panel.Settings", $"{CmdMainConsole} edit_menu category up {menuCategory.ID}", $"{CmdMainConsole} edit_menu category down {menuCategory.ID}", $"{CmdMainConsole} edit_category start {menuCategory.ID}");
                    CategoriesLoopPosition(ref mainOffset);
                }
                if (CanPlayerEdit(player)) {
                    container.Add(new CuiElement() {
                        Name = Layer + ".Scroll.View.Category.Create", DestroyUi = Layer + ".Scroll.View.Category.Create", Parent = Layer + ".Scroll.View", Components = {
                            new CuiImageComponent() {
                                Color = "0 0 0 0"
                            }
                            , CalculateCategoriesPosition(mainOffset, UI.Categories.CategoryWidth, UI.Categories.CategoryHeight)
                        }
                    }
                    );
                    UI.Categories.AdminCategory.AdminCheckbox.GetCheckbox(player, container, Layer + ".Scroll.View.Category.Create", Layer + ".Scroll.View.Category.Create.CheckBox.AdminMode", $"{CmdMainConsole} edit_menu change_mode", openedMenu.isEditMode);
                    UI.Categories.AdminCategory.ButtonAddCategory.Get(ref container, player, Layer + ".Scroll.View.Category.Create", cmdFormatter : text => $"{CmdMainConsole} edit_category create");
                    CategoriesLoopPosition(ref mainOffset);
                    container.Add(new CuiElement() {
                        Name = Layer + ".Scroll.View.Category.Admin.Settings", DestroyUi = Layer + ".Scroll.View.Category.Admin.Settings", Parent = Layer + ".Scroll.View", Components = {
                            new CuiButtonComponent() {
                                Command = $"{CmdMainConsole} edit_header_fields start", Color = "0 0 0 0"
                            }
                            , CalculateCategoriesPosition(mainOffset, UI.Categories.CategoryWidth, UI.Categories.CategoryHeight)
                        }
                    }
                    );
                    UI.Categories.AdminCategory.ButtonAdminSettings.Get(ref container, player, Layer + ".Scroll.View.Category.Admin.Settings", cmdFormatter : text => $"{CmdMainConsole} edit_header_fields start");
                }
            }
            private void CategoriesLoopPosition(ref float mainOffset) {
                if (UI.Categories.CategoriesScroll.ScrollType == ScrollType.Horizontal) mainOffset += UI.Categories.CategoriesMargin + UI.Categories.CategoryWidth;
                else mainOffset = mainOffset - UI.Categories.CategoriesMargin - UI.Categories.CategoryHeight;
            }
            private CuiButtonComponent GetCategoriesButtonComponent(bool isSelected, MenuCategory menuCategory) {
                var btnComponent = new CuiButtonComponent {
                    Color = isSelected ? UI.Categories.CategoryTitle.SelectedBackgroundColor.Get() : UI.Categories.CategoryTitle.BackgroundColor.Get(), Command = menuCategory.ChatBtn && menuCategory.Commands.Length > 0 ? $"UI_ServerPanel_Send_Command UI_ServerPanel_Close|{menuCategory.Commands[0]}" : $"{CmdMainConsole} menu category {menuCategory.ID}",
                }
                ;
                if (!string.IsNullOrEmpty(UI.Categories.CategoryTitle.BackgroundSprite)) btnComponent.Sprite = UI.Categories.CategoryTitle.BackgroundSprite;
                if (!string.IsNullOrEmpty(UI.Categories.CategoryTitle.BackgroundMaterial)) btnComponent.Material = UI.Categories.CategoryTitle.BackgroundMaterial;
                return btnComponent;
            }
            private CuiRectTransform CalculateContentRectTransform(float totalWidth) {
                CuiRectTransform contentRect;
                if (UI.Categories.CategoriesScroll.ScrollType == ScrollType.Horizontal) {
                    contentRect = new CuiRectTransform() {
                        AnchorMin = "0 0", AnchorMax = "0 1", OffsetMin = "0 0", OffsetMax = $"{totalWidth} 0"
                    }
                    ;
                }
                else {
                    contentRect = new CuiRectTransform() {
                        AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = $"0 -{totalWidth}", OffsetMax = "0 0"
                    }
                    ;
                }
                return contentRect;
            }
            private CuiRectTransformComponent CalculateCategoriesPosition(float offsetVal, float categoryWidth, float categoryHeight) {
                CuiRectTransformComponent cuiRect;
                if (UI.Categories.CategoriesScroll.ScrollType == ScrollType.Horizontal) {
                    cuiRect = new CuiRectTransformComponent() {
                        AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"{offsetVal} -{categoryHeight}", OffsetMax = $"{offsetVal + categoryWidth} 0"
                    }
                    ;
                }
                else {
                    cuiRect = new CuiRectTransformComponent() {
                        AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"0 {offsetVal - categoryHeight}", OffsetMax = $"{categoryWidth} {offsetVal}"
                    }
                    ;
                }
                return cuiRect;
            }
#endregion
        }
#endregion Data.Template
#region Data.Localization
        private static LocalizationData _localizationData;
        private void SaveLocalizationData() => SaveDataToFile(_localizationData, $"{Name}/Localization");
        private void LoadLocalizationData() => LoadDataFromFile(ref _localizationData, $"{Name}/Localization");
        private class LocalizationData {
            [JsonProperty(PropertyName = "Localization Settings")]
            public LocalizationSettings Localization = new();
        }
#endregion Data.Localization
#region Data.Header
        private static HeaderFieldsData _headerFieldsData;
        private void SaveHeaderFieldsData() => SaveDataToFile(_headerFieldsData, $"{Name}/HeaderFields");
        private void LoadHeaderFieldsData() {
            LoadDataFromFile(ref _headerFieldsData, $"{Name}/HeaderFields");
            LoadHeaderFieldsDataCache();
        }
        private void LoadHeaderFieldsDataCache() {
            _headerFieldsData?.Load();
        }
        private class HeaderFieldsData {
#region Fields
            [JsonProperty(PropertyName = "Fields", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<HeaderFieldUI> Fields = new();
#endregion
#region Cache
            [JsonIgnore]
            public bool needToUpdate;
            [JsonIgnore]
            public List<HeaderFieldUI> elementsToUpdate;
            public void Load() {
                elementsToUpdate?.Clear();
                elementsToUpdate = Fields.FindAll(x => x.NeedToUpdate);
                if (elementsToUpdate.Count > 0) needToUpdate = true;
            }
#endregion
        }
        public class HeaderFieldUI : UiElement {
#region Fields
            [JsonProperty(PropertyName = "Need to update?")]
            public bool NeedToUpdate;
#endregion
#region Constructors
            public HeaderFieldUI() {
            }
            public HeaderFieldUI(UiElement other) : base(other) {
                NeedToUpdate = false;
            }
            public HeaderFieldUI(UiElement other, bool needToUpdate) : base(other) {
                NeedToUpdate = needToUpdate;
            }
#endregion
        }
#endregion Data.Localization
#region Data.Players
        private static PlayersData _playersData;
        private void SavePlayersData() => SaveDataToFile(_playersData, $"{Name}/Players");
        private void LoadPlayersData() {
            LoadDataFromFile(ref _playersData, $"{Name}/Players");
        }
        private class PlayersData {
#region Fields
            [JsonProperty(PropertyName = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, PlayerData> Players = new();
#endregion
        }
        public class PlayerData {
#region Fields
            [JsonProperty(PropertyName = "Selected Editor Position")]
            public EditorPosition SelectedEditorPosition = EditorPosition.Left;
#endregion
#region Public Methods
            public static PlayerData GetOrCreate(string userID) {
                if (!_playersData.Players.TryGetValue(userID, out var data)) _playersData.Players.TryAdd(userID, data = new PlayerData());
                return data;
            }
            public CuiRectTransformComponent GetEditorPosition() {
                switch (SelectedEditorPosition) {
                    case EditorPosition.Center : {
                        return new CuiRectTransformComponent() {
                            AnchorMin = "0.5 0", AnchorMax = "0.5 1", OffsetMin = "-130 0", OffsetMax = "130 0"
                        }
                        ;
                    }
                    case EditorPosition.Right : {
                        return new CuiRectTransformComponent() {
                            AnchorMin = "1 0", AnchorMax = "1 1", OffsetMin = "-260 0", OffsetMax = "0 0"
                        }
                        ;
                    }
                    default : {
                        return new CuiRectTransformComponent() {
                            AnchorMin = "0 0", AnchorMax = "0 1", OffsetMin = "0 0", OffsetMax = "260 0"
                        }
                        ;
                    }
                }
            }
#endregion
        }
        public enum EditorPosition {
            Left, Center, Right
        }
#endregion Data.Players
#region Classes
#region Categories
        public class MenuCategory {
#region Fields
            [JsonProperty(PropertyName = "ID")]
            public int ID;
            [JsonProperty(PropertyName = "Enabled")]
            public bool Enabled;
            [JsonProperty(PropertyName = "Permission")]
            public string Permission = string.Empty;
            [JsonProperty(PropertyName = "Title")]
            public string Title = string.Empty;
            [JsonProperty(PropertyName = "Chat Button")]
            public bool ChatBtn;
            [JsonProperty(PropertyName = "Show Pages?")]
            public bool ShowPages;
            [JsonProperty(PropertyName = "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public string[] Commands;
            [JsonProperty(PropertyName = "Icon")]
            public string Icon = string.Empty;
            [JsonProperty(PropertyName = "Pages", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<CategoryPage> Pages = new();
#endregion
#region Public Methods
            public void MoveUp() {
                var index = _categoriesData.Categories.IndexOf(this);
                if (index > 0 && index < _categoriesData.Categories.Count) {
                    (_categoriesData.Categories[index], _categoriesData.Categories[index - 1]) = (_categoriesData.Categories[index - 1], _categoriesData.Categories[index]);
                    // Swap
                }
            }
            public void MoveDown() {
                var index = _categoriesData.Categories.IndexOf(this);
                if (index >= 0 && index < _categoriesData.Categories.Count - 1) (_categoriesData.Categories[index], _categoriesData.Categories[index + 1]) = (_categoriesData.Categories[index + 1], _categoriesData.Categories[index]);
                // Swap
            }
            public void ProcessCategory(string pluginName = null) {
                if (Pages is not {
                    Count : 1
                }
                ) return;
                var page = Pages[0];
                if (page == null || page.Type != CategoryPage.PageType.Plugin || page.PluginName != pluginName) return;
                var plugin = page.Plugin;
                if (plugin == null) return;
                if (plugin.IsLoaded) plugin.Call("OnReceiveCategoryInfo", ID);
                else {
                    var coroutine = ServerMgr.Instance.StartCoroutine(Instance.CheckPluginLoaded(plugin, ID, 5));
                    Instance._categoriesActiveCoroutines[ID] = coroutine;
                }
            }
#endregion
#region Constructors
            public static MenuCategory GetDefault() {
                return new MenuCategory {
                    ID = Instance.GetUniqueCategoryID(), Enabled = true, Permission = string.Empty, Title = "New Category", ChatBtn = false, ShowPages = false, Commands = new[] {
                        "test_command_123"
                    }
                    , Icon = string.Empty, Pages = new List<CategoryPage> {
                        new() {
                            Title = string.Empty, Command = string.Empty, Type = CategoryPage.PageType.UI, PluginName = string.Empty, PluginHook = string.Empty, Elements = new List<UiElement> {
                                UiElement.CreatePanel(InterfacePosition.CreatePosition(0.5f, 0.5f, 0.5f, 0.5f, -50, -50, 50, 50), IColor.CreateWhite())
                            }
                        }
                    }
                }
                ;
            }
            public JObject ToJson() {
                var obj = new JObject() {
                    ["ID"]
                    = ID, ["Enabled"] = Enabled, ["Permission"] = Permission, ["Title"] = Title, ["ChatBtn"] = ChatBtn, ["ShowPages"] = ShowPages, ["Commands"] = JArray.FromObject(Commands), ["Icon"] = Icon, ["Pages"] = JArray.FromObject(Pages.Select(p => p.ToJson()).ToArray()),
                }
                ;
                return obj;
            }
            public static MenuCategory FromJson(JObject obj) {
                var menuCategory = GetDefault();
                if (obj.TryGetValue("ID", out var id)) menuCategory.ID = Convert.ToInt32(id);
                if (obj.TryGetValue("Enabled", out var enabled)) menuCategory.Enabled = Convert.ToBoolean(enabled);
                if (obj.TryGetValue("Permission", out var permission)) menuCategory.Permission = Convert.ToString(permission);
                if (obj.TryGetValue("Title", out var title)) menuCategory.Title = Convert.ToString(title);
                if (obj.TryGetValue("ChatBtn", out var chatBtn)) menuCategory.ChatBtn = Convert.ToBoolean(chatBtn);
                if (obj.TryGetValue("ShowPages", out var showPages)) menuCategory.ShowPages = Convert.ToBoolean(showPages);
                if (obj.TryGetValue("Icon", out var icon)) menuCategory.Icon = Convert.ToString(icon);
                if (obj.TryGetValue("Commands", out var arrCommands)) {
                    var list = new List<string>();
                    foreach (var targetCommand in (JArray) arrCommands) {
                        list.Add(targetCommand?.ToString());
                    }
                    if (list.Count > 0) menuCategory.Commands = list.ToArray();
                }
                if (obj.TryGetValue("Pages", out var arrPages)) {
                    var list = new List<CategoryPage>();
                    foreach (var jPage in (JArray) arrPages) {
                        var targetPage = CategoryPage.FromJson((JObject) jPage);
                        if (targetPage != null) list.Add(targetPage);
                    }
                    if (list.Count > 0) menuCategory.Pages = list;
                }
                return menuCategory;
            }
#endregion
        }
        public class MenuCategoryBuilder {
            private bool _enabled;
            private string _permission = string.Empty;
            private string _title = string.Empty;
            private bool _chatButton;
            private bool _showPages = true;
            private List<string> _commands = new();
            private List<CategoryPage> _pages;
            public MenuCategory Build() {
                var menuCategory = new MenuCategory {
                    ID = Instance.GetUniqueCategoryID(), Enabled = _enabled, Permission = _permission, Title = _title, ChatBtn = _chatButton, ShowPages = _showPages, Commands = _commands?.ToArray(), Pages = _pages
                }
                ;
                return menuCategory;
            }
            public MenuCategoryBuilder WithEnabled(bool enabled) {
                _enabled = enabled;
                return this;
            }
            public MenuCategoryBuilder WithTitle(string title) {
                _title = title;
                return this;
            }
            public MenuCategoryBuilder WithPermission(string permission) {
                _permission = permission;
                return this;
            }
            public MenuCategoryBuilder WithChatButton(bool chatButton) {
                _chatButton = chatButton;
                return this;
            }
            public MenuCategoryBuilder WithShowPages(bool showPages) {
                _showPages = showPages;
                return this;
            }
            public MenuCategoryBuilder WithCommand(string command) {
                _commands.Add(command);
                return this;
            }
            public MenuCategoryBuilder WithPages(List<CategoryPage> pages) {
                _pages = pages;
                return this;
            }
        }
        public class CategoryPage {
#region Fields
            [JsonProperty(PropertyName = "Title")]
            public string Title;
            [JsonProperty(PropertyName = "Command")]
            public string Command;
            [JsonProperty(PropertyName = "Type (Plugin/UI)")]
            [JsonConverter(typeof(StringEnumConverter))]
            public PageType Ty
// ... [Code preview truncated due to length. Full source in attached file] ...

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