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

FREE XDShop : 1.4.4 1.4.4

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Enumerable = System.Linq.Enumerable;
using System.Collections.Generic;
using System.Collections;
using Oxide.Plugins.XDShopExtensionMethods;
using Oxide.Game.Rust.Cui;
using Facepunch;
using Oxide.Core;
using System;
using UnityEngine.Networking;
using UnityEngine;
using System.Text;
using UnityEngine.UI;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
namespace Oxide.Plugins {
    [Info("XDShop", "Forum: https://topplugin.ru/ Ds: alone_sempai", "1.4.4")]
    [Description("Large easily customizable store")]
    class XDShop : RustPlugin {
        private void Unload() {
            SaveLimits();
            SaveCooldowns();
            SavePlayerData();
            foreach (BasePlayer player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, MainLayer);
            if (_imageUI != null) {
                _imageUI.UnloadImages();
                _imageUI = null;
            }
            StringBuilderInstance = null;
            _instance = null;
        }
        private static XDShop _instance;
        private const string NotificationMain = "NOTIFICATION_MAIN";
        private const string PanelProduct = "MAIN_PANEL_PRODUCTS";
        private void CheckingProducts() {
            foreach (Configuration.CategoryShop category in _config.product) {
                foreach (Configuration.CategoryShop.Product product in category.product) {
                    if (product.ID == 0) product.ID = Core.Random.Range(int.MinValue, int.MaxValue);
                    if (product.Type is ItemType.Item or ItemType.Blueprint or ItemType.CustomItem) {
                        product.Definition = ItemManager.FindItemDefinition(product.ShortName);
                        if (product.Definition == null) {
                            product.ItemsError = true;
                            PrintError(GetLang("XDSHOP_SERVICE_CONFIG_1", args : product.ID));
                            continue;
                        }
                    }
                    if (product.Price <= 0 && product.PriceSales <= 0) {
                        product.ItemsError = true;
                        PrintError(GetLang("XDSHOP_SERVICE_CONFIG_2", args : product.ID));
                    }
                }
            }
        }
        private const string PageProducts = "PAGE_PRODUCTS";
        private void CheckOnDuplicates() {
            HashSet<int> itemsSeen = new();
            foreach (Configuration.CategoryShop item in _config.product) foreach (Configuration.CategoryShop.Product items in item.product) if (!itemsSeen.Add(items.ID)) {
                items.ID = Core.Random.Range(int.MinValue, int.MaxValue);
            }
        }
        private const string ConfirmationsPanelSelling = "CONFIRMATIONS_PANEL_SELLING";
        private void SaveLimits() {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Player_Limits", _playerDataLimits);
        }
        private class CooldownData {
            public DateTime Buy = new(1970, 1, 1, 0, 0, 0);
            public DateTime Sell = new(1970, 1, 1, 0, 0, 0);
        }
        private const string ConfirmationsPanel = "CONFIRMATIONS_PANEL";
        private readonly Dictionary<string, ItemDisplayName> _itemName = new Dictionary<string, ItemDisplayName>();
        private Dictionary<ulong, ThemeType> _playerThemeSelect = new();
        private void Selling(BasePlayer player, int itemId, int category, int amount, ThemeType themetype) {
            Configuration.CategoryShop.Product product = GetCategories(player)[category].product.Find(x => x.ID == itemId);
            if (product == null) return;
            if (IsDuel(player.userID.Get())) {
                NotificationUI(player, NotificationType.Error, GetLang("XDSHOP_UI_NOTIFICATION_SELL_IS_DUEL", player.UserIDString));
                return;
            }
            if (_config.mainSettings.RaidBlock && IsRaid(player)) {
                NotificationUI(player, NotificationType.Error, GetLang("XDSHOP_UI_NOTIFICATION_IS_RAID", player.UserIDString));
                return;
            }
            Item[] playerItems = Enumerable.ToArray(Enumerable.Concat(player.inventory.containerMain?.itemList ?? Enumerable.Empty<Item>(), Enumerable.Concat(player.inventory.containerBelt?.itemList ?? Enumerable.Empty<Item>(), player.inventory.containerWear?.itemList ?? Enumerable.Empty<Item>())));
            int needAmount = product.AmountSales * amount;
            bool blueprint = product.Type == ItemType.Blueprint;
            if (blueprint || product.Type == ItemType.CustomItem || product.Type == ItemType.Item) {
                if (GetItemAmount(playerItems, product.ShortName, product.SkinID, blueprint) < needAmount) {
                    NotificationUI(player, NotificationType.Warning, GetLang("XDSHOP_UI_NOTIFICATION_NOT_ENOUGH_ITEM", player.UserIDString));
                    return;
                }
            }
            float price = product.PriceSales * amount;
            if (product.SellCooldown > 0) {
                int cooldown = GetCooldownTime(player.userID.Get(), product, false);
                if (cooldown > 0) {
                    NotificationUI(player, NotificationType.Warning, GetLang("XDSHOP_UI_NOTIFICATION_SELL_RECHARGE", player.UserIDString, product.GetProductName(player.UserIDString), TimeHelper.FormatTime(TimeSpan.FromSeconds(cooldown), 5, lang.GetLanguage(player.UserIDString))));
                    return;
                }
                SetCooldown(player, product, false);
            }
            int limit = GetLimit(player, product, false);
            if (limit != -1) {
                if (limit == 0) {
                    NotificationUI(player, NotificationType.Warning, GetLang("XDSHOP_UI_NOTIFICATION_SELL_LIMIT", player.UserIDString, product.GetProductName(player.UserIDString)));
                    return;
                }
                else if (amount > limit) {
                    NotificationUI(player, NotificationType.Warning, GetLang("XDSHOP_UI_NOTIFICATION_SELL_LIMIT_1", player.UserIDString, product.GetProductName(player.UserIDString), limit));
                    return;
                }
                AddLimit(player, product, amount, false);
            }
            switch (_config.economicsCustomization.TypeEconomic) {
                case EconomicsType.Economics : if ((bool)Economics?.Call("Deposit", player.userID.Get(), (double)price)) {
                    TakeItem(playerItems, product.ShortName, needAmount, product.SkinID, blueprint);
                    UpdateBalance(player, themetype);
                    NotificationUI(player, NotificationType.Success, GetLang("XDSHOP_UI_NOTIFICATION_SUCCESSFUL_SALE", player.UserIDString, product.GetProductName(player.UserIDString)));
                }
                break;
                case EconomicsType.ServerRewards : if (ServerRewards?.Call<object>("AddPoints", player.userID.Get(), (int)price) != null) {
                    TakeItem(playerItems, product.ShortName, needAmount, product.SkinID, blueprint);
                    UpdateBalance(player, themetype);
                    NotificationUI(player, NotificationType.Success, GetLang("XDSHOP_UI_NOTIFICATION_SUCCESSFUL_SALE", player.UserIDString, product.GetProductName(player.UserIDString)));
                }
                break;
                case EconomicsType.IQEconomic : IQEconomic?.Call("API_SET_BALANCE", player.userID.Get(), (int)price);
                TakeItem(playerItems, product.ShortName, needAmount, product.SkinID, blueprint);
                UpdateBalance(player, themetype);
                NotificationUI(player, NotificationType.Success, GetLang("XDSHOP_UI_NOTIFICATION_SUCCESSFUL_SALE", player.UserIDString, product.GetProductName(player.UserIDString)));
                break;
                case EconomicsType.Item : Item item = ItemManager.CreateByName(_config.economicsCustomization.EconomicShortname, (int)price, _config.economicsCustomization.EconomicSkinId);
                player.GiveItem(item, BaseEntity.GiveItemReason.PickedUp);
                TakeItem(playerItems, product.ShortName, needAmount, product.SkinID, blueprint);
                UpdateBalance(player, themetype);
                NotificationUI(player, NotificationType.Success, GetLang("XDSHOP_UI_NOTIFICATION_SUCCESSFUL_SALE", player.UserIDString, product.GetProductName(player.UserIDString)));
                break;
            }
        }
        private string GetLang(string langKey, string userID = null, params object[] args) {
            StringBuilderInstance.Clear();
            if (args == null) return lang.GetMessage(langKey, this, userID);
            StringBuilderInstance.AppendFormat(lang.GetMessage(langKey, this, userID), args);
            return StringBuilderInstance.ToString();
        }
        private List<int> GetStacks(ItemDefinition items, int amount) {
            List<int> list = new List<int>();
            int maxStack = items.stackable;
            while (amount > maxStack) {
                amount -= maxStack;
                list.Add(maxStack);
            }
            list.Add(amount);
            return list;
        }
        private void LoadData() {
            try {
                _playerDataCooldowns = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerCooldown>>($"{Name}/Player_Cooldowns");
                _playerDataLimits = Interface.Oxide.DataFileSystem.ReadObject<PlayerLimits>($"{Name}/Player_Limits");
                _playerThemeSelect = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, ThemeType>>($"{Name}/Players");
            }
            catch (Exception e) {
                PrintError(e.ToString());
            }
            if (_playerDataCooldowns == null) _playerDataCooldowns = new Dictionary<ulong, PlayerCooldown>();
            if (_playerDataLimits == null) _playerDataLimits = new PlayerLimits();
            if (_playerThemeSelect == null) _playerThemeSelect = new Dictionary<ulong, ThemeType>();
        }
        private static void TakeItem(Item[] playerItems, string shortname, int amount, ulong skinid = 0, bool blueprint = false) {
            List<Item> acceptedItems = Pool.GetList<Item>();
            int itemAmount = 0;
            foreach (Item item in playerItems.Where(x => x != null && (blueprint ? x.blueprintTargetDef?.shortname == shortname : x.info?.shortname == shortname) && (skinid == 0 || x.skin == skinid))) {
                if (item.isBroken || item.hasCondition && item.condition < item.info.condition.max) continue;
                acceptedItems.Add(item);
                itemAmount += item.amount;
            }
            foreach (Item use in acceptedItems) {
                if (use.amount == amount) {
                    use.RemoveFromContainer();
                    use.Remove();
                    amount = 0;
                    break;
                }
                if (use.amount > amount) {
                    use.MarkDirty();
                    use.amount -= amount;
                    amount = 0;
                    break;
                }
                if (use.amount < amount) {
                    amount -= use.amount;
                    use.RemoveFromContainer();
                    use.Remove();
                }
            }
            Pool.FreeList(ref acceptedItems);
        }
        private void UICATEGORY(BasePlayer player, ThemeType themetype, int page = 0, int categoryIndex = 0) {
            Configuration.InterfaceSettings.ThemeCustomization theme = themetype == ThemeType.Dark ? _config.interfaceSettings.DarkTheme : _config.interfaceSettings.LightTheme;
            CuiElementContainer container = new CuiElementContainer {
                {
                    new CuiPanel {
                        CursorEnabled = false, Image = {
                            Color = "1 1 1 0"
                        }
                        , RectTransform = {
                            AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-425.607 -77.449", OffsetMax = "454.613 -46.751"
                        }
                    }
                    , PanelProduct, CategoryLayer
                }
            }
            ;
            int i = 0, catIndex = page * 6;
            List<Configuration.CategoryShop> category = GetCategories(player);
            foreach (Configuration.CategoryShop cat in category.Page(page, 6)) {
                bool thisCat = catIndex == categoryIndex;
                string colorLine = thisCat ? theme.color2 : theme.color3;
                container.Add(new CuiElement {
                    Name = $"CATEGORY_{i}", Parent = CategoryLayer, Components = {
                        new CuiRawImageComponent {
                            Color = colorLine, Png = _imageUI.GetImage("18")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = $"{0.912 + (i * 133)} -13.949", OffsetMax = $"{95.559 + (i * 133)} 5.349"
                        }
                    }
                }
                );
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = colorLine, Material = "assets/content/ui/uibackgroundblur-ingamemenu.mat"
                    }
                    , RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-47.324 -9.649", OffsetMax = "47.324 -8.649"
                    }
                }
                , $"CATEGORY_{i}", "CATEGORY_LINE");
                container.Add(new CuiButton {
                    Button = {
                        Command = thisCat ? "" : $"UI_HandlerShop CHANGE_CATEGORY {page} {catIndex} {themetype}", Color = "0 0 0 0"
                    }
                    , Text = {
                        Text = cat.CategoryName, Font = thisCat ? "robotocondensed-bold.ttf" : "robotocondensed-regular.ttf", FontSize = 12, Align = TextAnchor.UpperCenter, Color = thisCat ? theme.colortext3 : theme.colortext4
                    }
                    , RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-47.323 -9.649", OffsetMax = "47.323 9.649"
                    }
                }
                , $"CATEGORY_{i}");
                catIndex++;
                if (i >= 5) break;
                i++;
            }
            if (category.Count > 6) {
                container.Add(new CuiPanel {
                    Image = {
                        Color = "1 1 1 0"
                    }
                    , RectTransform = {
                        AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-77.294 -30.698", OffsetMax = "0 0"
                    }
                }
                , CategoryLayer, "CATEGORY_PAGE");
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-10.74 -6.965", OffsetMax = "10.74 6.965"
                    }
                    , Text = {
                        Text = $"{page + 1}", Font = "robotocondensed-regular.ttf", FontSize = 10, Align = TextAnchor.MiddleCenter, Color = theme.colortext1
                    }
                    ,
                }
                , "CATEGORY_PAGE");
                if (page > 0) {
                    container.Add(new CuiElement {
                        Name = "PAGE_LEFT", Parent = "CATEGORY_PAGE", Components = {
                            new CuiRawImageComponent {
                                Color = theme.color1, Png = _imageUI.GetImage("3")
                            }
                            , new CuiRectTransformComponent {
                                AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "13 -6.31", OffsetMax = "20 4.69"
                            }
                        }
                    }
                    );
                    container.Add(new CuiButton {
                        RectTransform = {
                            AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-38.647 -15.349", OffsetMax = "0 15.349"
                        }
                        , Button = {
                            Command = $"UI_HandlerShop PAGE_CATEGORY {page - 1} {themetype} {(page - 1) * 6}", Color = "0 0 0 0"
                        }
                        , Text = {
                            Text = ""
                        }
                    }
                    , "CATEGORY_PAGE", "PAGE_LEFT_BTN");
                }
                if (page + 1 < (int)Math.Ceiling((double)category.Count / 6)) {
                    container.Add(new CuiElement {
                        Name = "PAGE_RIGHTS", Parent = "CATEGORY_PAGE", Components = {
                            new CuiRawImageComponent {
                                Color = theme.color1, Png = _imageUI.GetImage("4")
                            }
                            , new CuiRectTransformComponent {
                                AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-20 -6.31", OffsetMax = "-13 4.69"
                            }
                        }
                    }
                    );
                    container.Add(new CuiButton {
                        RectTransform = {
                            AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "0 -15.349", OffsetMax = "38.646 15.349"
                        }
                        , Button = {
                            Command = $"UI_HandlerShop PAGE_CATEGORY {page + 1} {themetype} {catIndex}", Color = "0 0 0 0"
                        }
                        , Text = {
                            Text = ""
                        }
                    }
                    , "CATEGORY_PAGE", "PAGE_RIGHT_BTN");
                }
            }
            CuiHelper.DestroyUi(player, CategoryLayer);
            CuiHelper.AddUi(player, container);
        }
        private Dictionary<ulong, PlayerCooldown> _playerDataCooldowns = new Dictionary<ulong, PlayerCooldown>();
        public static StringBuilder StringBuilderInstance;
        private float GetBalance(BasePlayer player) {
            switch (_config.economicsCustomization.TypeEconomic) {
                case EconomicsType.Economics : if (!Economics) return 0f;
                return (float)Economics?.Call<double>("Balance", player.userID.Get());
                case EconomicsType.ServerRewards : if (!ServerRewards) return 0f;
                return (int)ServerRewards?.Call("CheckPoints", player.userID.Get());
                case EconomicsType.IQEconomic : if (!IQEconomic) return 0f;
                return (int)IQEconomic?.Call("API_GET_BALANCE", player.userID.Get());
                case EconomicsType.Item : return GetItemAmount(Enumerable.ToArray(Enumerable.Concat(player.inventory.containerMain?.itemList ?? Enumerable.Empty<Item>(), Enumerable.Concat(player.inventory.containerBelt?.itemList ?? Enumerable.Empty<Item>(), player.inventory.containerWear?.itemList ?? Enumerable.Empty<Item>()))), _config.economicsCustomization.EconomicShortname, _config.economicsCustomization.EconomicSkinId);
                default : return 0f;
            }
        }
        private void OnLeaveNPC(BasePlayer npc, BasePlayer player) {
            if (!_config.humanNpcs.NPCs.ContainsKey(npc.UserIDString)) return;
            if (!_humanNpcPlayerOpen.ContainsKey(player.userID.Get())) return;
            _humanNpcPlayerOpen.Remove(player.userID.Get());
            if (_uiPlayerUseNow.Contains(player.userID.Get())) _uiPlayerUseNow.Remove(player.userID.Get());
            CuiHelper.DestroyUi(player, "NOTIFICATION_POLOSA");
            CuiHelper.DestroyUi(player, "NOTIFICATION_IMG");
            CuiHelper.DestroyUi(player, "NOTIFICATION_TEXT");
            CuiHelper.DestroyUi(player, NotificationMain);
            CuiHelper.DestroyUi(player, MainLayer);
        }
        [ConsoleCommand("UI_HandlerShop")]
        private void CmdConsoleHandler(ConsoleSystem.Arg args) {
            BasePlayer player = args.Player();
            if (player == null || !args.HasArgs(1)) return;
            switch (args.Args[0]) {
                case "PAGE_CATEGORY" : {
                    int page = int.Parse(args.Args[1]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[2]);
                    int category = int.Parse(args.Args[3]);
                    UICATEGORY(player, theme, page, category);
                    UIPRODUCT(player, theme, 0, category);
                    break;
                }
                case "CHANGE_CATEGORY" : {
                    int page = int.Parse(args.Args[1]);
                    int category = int.Parse(args.Args[2]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[3]);
                    CuiHelper.DestroyUi(player, ConfirmationsPanel);
                    CuiHelper.DestroyUi(player, ConfirmationsPanelSelling);
                    UICATEGORY(player, theme, page, category);
                    UIPRODUCT(player, theme, 0, category);
                    break;
                }
                case "PAGE_PRODUCT" : {
                    int page = int.Parse(args.Args[1]);
                    int category = int.Parse(args.Args[2]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[3]);
                    CuiHelper.DestroyUi(player, ConfirmationsPanel);
                    CuiHelper.DestroyUi(player, ConfirmationsPanelSelling);
                    UIPRODUCT(player, theme, page, category);
                    break;
                }
                case "AMOUNT_CHANGE_PLUS" : {
                    int index = int.Parse(args.Args[1]);
                    int indexCategory = int.Parse(args.Args[2]);
                    int amount = int.Parse(args.Args[3]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
                    int type = int.Parse(args.Args[5]);
                    if (type == 0) {
                        CuiHelper.DestroyUi(player, ConfirmationsPanel);
                        UPDATEAMOUNTUI(player, index, indexCategory, amount + 1, theme);
                    }
                    else {
                        UPDATE_UI_SELLING(player, index, indexCategory, amount + 1, theme);
                    }
                    break;
                }
                case "AMOUNT_CHANGE_MINUS" : {
                    int index = int.Parse(args.Args[1]);
                    int indexCategory = int.Parse(args.Args[2]);
                    int amount = int.Parse(args.Args[3]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
                    int type = int.Parse(args.Args[5]);
                    if (type == 0) {
                        CuiHelper.DestroyUi(player, ConfirmationsPanel);
                        UPDATEAMOUNTUI(player, index, indexCategory, amount - 1, theme);
                    }
                    else {
                        UPDATE_UI_SELLING(player, index, indexCategory, amount - 1, theme);
                    }
                    break;
                }
                case "AMOUNT_CHANGE_KEYBOARD" : {
                    int index = int.Parse(args.Args[1]);
                    int indexCategory = int.Parse(args.Args[2]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[3]);
                    if (!int.TryParse(args.Args[4], out int amount)) amount = 1;
                    CuiHelper.DestroyUi(player, ConfirmationsPanel);
                    UPDATEAMOUNTUI(player, index, indexCategory, amount, theme);
                    break;
                }
                case "PRODUCT_BUY_CONFIRMATION" : {
                    int indexItem = int.Parse(args.Args[1]);
                    int indexCategory = int.Parse(args.Args[2]);
                    int amount = int.Parse(args.Args[3]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
                    CuiHelper.DestroyUi(player, ConfirmationsPanelSelling);
                    CONFIRMATIONSUI(player, indexItem, indexCategory, amount, theme);
                    break;
                }
                case "PRODUCT_SALE_CONFIRMATION" : {
                    int indexItem = int.Parse(args.Args[1]);
                    int indexCategory = int.Parse(args.Args[2]);
                    int amount = int.Parse(args.Args[3]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
                    CuiHelper.DestroyUi(player, ConfirmationsPanel);
                    CONFIRMATIONSSALEUI(player, indexItem, indexCategory, amount, theme);
                    break;
                }
                case "PRODUCT_BUY" : {
                    int indexItem = int.Parse(args.Args[1]);
                    int indexCategory = int.Parse(args.Args[2]);
                    int amount = int.Parse(args.Args[3]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
                    Purchasing(player, indexItem, indexCategory, amount, theme);
                    CuiHelper.DestroyUi(player, ConfirmationsPanel);
                    break;
                }
                case "PRODUCT_SALE" : {
                    int itemId = int.Parse(args.Args[1]);
                    int indexCategory = int.Parse(args.Args[2]);
                    int amount = int.Parse(args.Args[3]);
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
                    Selling(player, itemId, indexCategory, amount, theme);
                    CuiHelper.DestroyUi(player, ConfirmationsPanelSelling);
                    break;
                }
                case "THEME_SWITCH" : {
                    ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[1]);
                    UIMAIN(player, theme == ThemeType.Dark ? ThemeType.Light : ThemeType.Dark);
                    _playerThemeSelect[player.userID.Get()] = theme == ThemeType.Dark ? ThemeType.Light : ThemeType.Dark;
                    break;
                }
                case "CLOSE_ALL_UI" : {
                    if (_config.humanNpcs.UseHumanNpcs && _humanNpcPlayerOpen.ContainsKey(player.userID.Get())) _humanNpcPlayerOpen.Remove(player.userID.Get());
                    if (_uiPlayerUseNow.Contains(player.userID.Get())) _uiPlayerUseNow.Remove(player.userID.Get());
                    CuiHelper.DestroyUi(player, "NOTIFICATION_POLOSA");
                    CuiHelper.DestroyUi(player, "NOTIFICATION_IMG");
                    CuiHelper.DestroyUi(player, "NOTIFICATION_TEXT");
                    CuiHelper.DestroyUi(player, NotificationMain);
                    CuiHelper.DestroyUi(player, MainLayer);
                    break;
                }
            }
        }
        private void OnPlayerDisconnected(BasePlayer player, string reason) {
            if (_uiPlayerUseNow.Contains(player.userID.Get())) _uiPlayerUseNow.Remove(player.userID.Get());
            if (_config.humanNpcs.UseHumanNpcs) if (_humanNpcPlayerOpen.ContainsKey(player.userID.Get())) _humanNpcPlayerOpen.Remove(player.userID.Get());
        }
        private class ItemDisplayName {
            public string ru;
            public string en;
            public string description;
        }
        private static class TimeHelper {
            public static string FormatTime(TimeSpan time, int maxSubstr = 5, string language = "ru") {
                string result = string.Empty;
                switch (language) {
                    case "ru" : int i = 0;
                    if (time.Days != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Days, "д", "д", "д")}";
                        i++;
                    }
                    if (time.Hours != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Hours, "ч", "ч", "ч")}";
                        i++;
                    }
                    if (time.Minutes != 0 && i < maxSubstr) {
                        if (!string.IsNullOrEmpty(result)) result += " ";
                        result += $"{Format(time.Minutes, "м", "м", "м")}";
                        i++;
                    }
                    if (time.Days == 0) {
                        if (time.Seconds != 0 && i < maxSubstr) {
                            if (!string.IsNullOrEmpty(result)) result += " ";
                            result += $"{Format(time.Seconds, "с", "с", "с")}";
                            i++;
                        }
                    }
                    break;
                    default : result = string.Format("{0}{1}{2}{3}", time.Duration().Days > 0 ? $"{time.Days:0} day{(time.Days == 1 ? string.Empty : "s")}, " : string.Empty, time.Duration().Hours > 0 ? $"{time.Hours:0} hour{(time.Hours == 1 ? string.Empty : "s")}, " : string.Empty, time.Duration().Minutes > 0 ? $"{time.Minutes:0} minute{(time.Minutes == 1 ? string.Empty : "s")}, " : string.Empty, time.Duration().Seconds > 0 ? $"{time.Seconds:0} second{(time.Seconds == 1 ? string.Empty : "s")}" : string.Empty);
                    if (result.EndsWith(", ")) result = result.Substring(0, result.Length - 2);
                    if (string.IsNullOrEmpty(result)) result = "0 seconds";
                    break;
                }
                return result;
            }
            private static string Format(int units, string form1, string form2, string form3) {
                int tmp = units % 10;
                if (units >= 5 && units <= 20 || tmp >= 5 && tmp <= 9) return $"{units}{form1}";
                if (tmp >= 2 && tmp <= 4) return $"{units}{form2}";
                return $"{units}{form3}";
            }
        }
        private class PlayerLimitData {
            [JsonProperty(PropertyName = "Player Limits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            private readonly Dictionary<int, ItemLimitData> _itemsLimits = new Dictionary<int, ItemLimitData>();
            public void AddItem(Configuration.CategoryShop.Product item, int lots, bool purchase) {
                if (!_itemsLimits.ContainsKey(item.ID)) _itemsLimits.Add(item.ID, new ItemLimitData());
                if (purchase) _itemsLimits[item.ID].Buy += lots;
                else _itemsLimits[item.ID].Sell += lots;
            }
            public int GetLimit(Configuration.CategoryShop.Product item, bool purchase) {
                ItemLimitData data;
                if (_itemsLimits.TryGetValue(item.ID, out data)) return purchase ? data.Buy : data.Sell;
                return 0;
            }
            private class ItemLimitData {
                public int Sell;
                public int Buy;
            }
        }
        private void Init() {
            _instance = this;
            SubAndUnSubHumanNpcHook();
            LoadData();
            foreach (KeyValuePair<string, float> discount in _config.discountStores.DiscountPerm) if (!permission.PermissionExists(discount.Key)) permission.RegisterPermission(discount.Key, this);
            foreach (string command in _config.mainSettings.Commands) cmd.AddChatCommand(command, this, nameof(XDShopUI));
        }
        private void ThemeSwitch(BasePlayer player, ThemeType themetype) {
            string img = themetype == ThemeType.Dark ? _imageUI.GetImage("12") : _imageUI.GetImage("11");
            CuiElementContainer container = new CuiElementContainer {
                new CuiElement {
                    Name = "THEME_BTN", Parent = PanelProduct, Components = {
                        new CuiRawImageComponent {
                            Color = "1 1 1 1", Png = img
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "16.5 12.8", OffsetMax = "38.5 25.8"
                        }
                    }
                }
                , {
                    new CuiButton {
                        RectTransform = {
                            AnchorMin = "0 0", AnchorMax = "1 1"
                        }
                        , Button = {
                            Command = $"UI_HandlerShop THEME_SWITCH {themetype}", Color = "0 0 0 0"
                        }
                        , Text = {
                            Text = "",
                        }
                    }
                    , "THEME_BTN"
                }
            }
            ;
            CuiHelper.DestroyUi(player, "THEME_BTN");
            CuiHelper.AddUi(player, container);
        }
        private string GetImage(string shortname, ulong skin = 0) => (string)ImageLibrary?.Call("GetImage", shortname, skin);
        private class PlayerLimits {
            [JsonProperty(PropertyName = "List of players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, PlayerLimitData> Players = new Dictionary<ulong, PlayerLimitData>();
            public static PlayerLimitData GetOrAddPlayer(ulong playerId) {
                if (!_instance._playerDataLimits.Players.ContainsKey(playerId)) _instance._playerDataLimits.Players.Add(playerId, new PlayerLimitData());
                return _instance._playerDataLimits.Players[playerId];
            }
        }
        [ConsoleCommand("xdshop.yes")]
        private void CmdShopItemsRefillYes(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel <= 0) return;
            ulong userId = arg.Connection == null || arg.IsRcon ? 0U : arg.Connection.userid;
            if (!_pdpw.Contains(userId)) return;
            PrintWarning(GetLang("XDSHOP_SERVICE_CMD_REFILL_YES"));
            RefillItems();
            _pdpw.Remove(userId);
        }
        private void OnUseNPC(BasePlayer npc, BasePlayer player) {
            if (!_config.humanNpcs.NPCs.ContainsKey(npc.UserIDString) || _humanNpcPlayerOpen.ContainsKey(player.userID.Get())) return;
            _humanNpcPlayerOpen.Add(player.userID.Get(), npc.UserIDString);
            XDShopUI(player);
        }
        private static int GetItemAmount(Item[] itemsInput, string shortname, ulong skin, bool blueprint = false) {
            List<Item> items = new List<Item>();
            foreach (Item item in itemsInput.Where(x => x != null && (blueprint ? x.blueprintTargetDef?.shortname == shortname : x.info?.shortname == shortname) && (skin == 0 || x.skin == skin))) {
                if (item.isBroken || item.hasCondition && item.condition < item.info.condition.max) continue;
                items.Add(item);
            }
            return items.Sum(item => item.amount);
        }
        private const string CategoryLayer = "CATEGORY_LAYER";
        private void ValidateConfig() {
            foreach (Configuration.CategoryShop category in _config.product) {
                foreach (Configuration.CategoryShop.Product product in category.product) {
                    foreach (KeyValuePair<string, int> buyLimits in product.BuyLimits) if (!permission.PermissionExists(buyLimits.Key)) permission.RegisterPermission(buyLimits.Key, this);
                    foreach (KeyValuePair<string, int> sellLimits in product.SellLimits) if (!permission.PermissionExists(sellLimits.Key)) permission.RegisterPermission(sellLimits.Key, this);
                    foreach (KeyValuePair<string, int> buyLimitsWipe in product.BuyLimitsWipe) if (!permission.PermissionExists(buyLimitsWipe.Key)) permission.RegisterPermission(buyLimitsWipe.Key, this);
                    foreach (KeyValuePair<string, int> sellLimitsWipe in product.SellLimitsWipe) if (!permission.PermissionExists(sellLimitsWipe.Key)) permission.RegisterPermission(sellLimitsWipe.Key, this);
                }
                if (!permission.PermissionExists(category.PermissionCategory)) permission.RegisterPermission(category.PermissionCategory, this);
            }
        }
        protected override void LoadDefaultConfig() {
            _config = new Configuration();
        }
        private readonly Dictionary<ulong, string> _humanNpcPlayerOpen = new Dictionary<ulong, string>();
        private void UIMAIN(BasePlayer player, ThemeType themetype) {
            Configuration.InterfaceSettings.ThemeCustomization theme = themetype == ThemeType.Dark ? _config.interfaceSettings.DarkTheme : _config.interfaceSettings.LightTheme;
            float discount = GetUserDiscount(player);
            CuiElementContainer container = new CuiElementContainer();
            container.Add(new CuiElement {
                Name = PanelProduct, Parent = MainLayer, Components = {
                    new CuiRawImageComponent {
                        Color = theme.colorMainBG, Png = _imageUI.GetImage("0")
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 0", AnchorMax = "1 1"
                    }
                }
            }
            );
            container.Add(new CuiButton {
                Button = {
                    Color = "0 0 0 0", Command = "UI_HandlerShop CLOSE_ALL_UI"
                }
                , Text = {
                    Text = "x", Font = "robotocondensed-bold.ttf", FontSize = 13, Align = TextAnchor.MiddleCenter, Color = theme.CloseBtnColor
                }
                , RectTransform = {
                    AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-27.467 -24.554", OffsetMax = "-6.946 -5.983"
                }
            }
            , PanelProduct, "CLOSE_MENU_BTN");
            container.Add(new CuiLabel {
                RectTransform = {
                    AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "115.291 -40.197", OffsetMax = "248.709 -21.203"
                }
                , Text = {
                    Text = GetLang("XDSHOP_UI_TITLE", player.UserIDString), Font = "robotocondensed-regular.ttf", FontSize = 11, Align = TextAnchor.MiddleLeft, Color = theme.colorTextTitle
                }
            }
            , PanelProduct, "LABEL_TITLE");
            container.Add(new CuiElement {
                Name = "IMAGE_TITLE", Parent = PanelProduct, Components = {
                    new CuiImageComponent {
                        Color = theme.colorImgTitle, Png = _imageUI.GetImage("7")
                    }
                    , new CuiRectTransformComponent {
                        AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "90.223 -40.197", OffsetMax = "107.083 -23.441"
                    }
                }
            }
            );
            if (_config.discountStores.DiscountPerm.Count != 0) {
                container.Add(new CuiPanel {
                    CursorEnabled = false, Image = {
                        Color = "1 1 1 0"
                    }
                    , RectTransform = {
                        AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-113.69 -46.75", OffsetMax = "-61.91 -18.068"
                    }
                }
                , PanelProduct, "DISCOUNT_INFO");
                container.Add(new CuiElement {
                    Name = "DISCOUNT_IMAGE", Parent = "DISCOUNT_INFO", Components = {
                        new CuiRawImageComponent {
                            Color = theme.colorImgDiscount, Png = _imageUI.GetImage("5")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "3 -7.5", OffsetMax = "18 10.5"
                        }
                    }
                }
                );
                container.Add(new CuiLabel {
                    RectTransform = {
                        AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-1.576 -7.5", OffsetMax = "25.89 7.051"
                    }
                    , Text = {
                        Text = $"{discount}%", Font = "robotocondensed-bold.ttf", FontSize = 11, Align = TextAnchor.MiddleLeft, Color = theme.colorTextDiscount
                    }
                }
                , "DISCOUNT_INFO", "DISCOUNT");
            }
            CuiHelper.DestroyUi(player, PanelProduct);
            CuiHelper.AddUi(player, container);
            UIPRODUCT(player, themetype);
            UICATEGORY(player, themetype);
            UpdateBalance(player, themetype);
            if (_config.interfaceSettings.UseChangeTheme) ThemeSwitch(player, themetype);
        }
        [ConsoleCommand("xdshop.refill")]
        private void CmdShopItemsRefill(ConsoleSystem.Arg arg) {
            if (arg.Connection != null && arg.Connection.authLevel <= 0) return;
            SendReply(arg, GetLang("XDSHOP_SERVICE_CMD_REFILL"));
            ulong userId = arg.Connection == null || arg.IsRcon ? 0U : arg.Connection.userid;
            if (_pdpw.Contains(userId)) return;
            _pdpw.Add(userId);
            timer.In(15, () => {
                if (_pdpw.Contains(userId)) _pdpw.Remove(userId);
            }
            );
        }
        private PlayerCooldown GetCooldown(ulong player) {
            PlayerCooldown cooldown;
            return _playerDataCooldowns.TryGetValue(player, out cooldown) ? cooldown : null;
        }
        private enum NotificationType {
            Error, Warning, Success
        }
        private void UpdateBalance(BasePlayer player, ThemeType themetype) {
            Configuration.InterfaceSettings.ThemeCustomization theme = themetype == ThemeType.Dark ? _config.interfaceSettings.DarkTheme : _config.interfaceSettings.LightTheme;
            CuiElementContainer container = new CuiElementContainer {
                {
                    new CuiPanel {
                        CursorEnabled = false, Image = {
                            Color = "1 1 1 0"
                        }
                        , RectTransform = {
                            AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-208.947 -46.751", OffsetMax = "-113.693 -18.067"
                        }
                    }
                    , PanelProduct, "BALANCE_INFO"
                }
                , new CuiElement {
                    Name = "BALANCE_IMAGE", Parent = "BALANCE_INFO", Components = {
                        new CuiImageComponent {
                            Color = theme.colorImgBalance, Png = _imageUI.GetImage("6")
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "7.9 -7", OffsetMax = "28.9 7"
                        }
                    }
                }
                , {
                    new CuiLabel {
                        RectTransform = {
                            AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-61.563 -9.46", OffsetMax = "-0.372 7.46"
                        }
                        , Text = {
                            Text = GetBalance(player).ToString("0.0") + _config.economicsCustomization.PrefixBalance, Font = "robotocondensed-bold.ttf", FontSize = 11, Align = TextAnchor.MiddleLeft, Color = theme.colorTextBalance
                        }
                    }
                    , "BALANCE_INFO", "BALANCE"
                }
            }
            ;
            CuiHelper.DestroyUi(player, "BALANCE_INFO");
            CuiHelper.AddUi(player, container);
        }
        private readonly List<ulong> _pdpw = new List<ulong>();
        private const string ProductsLayer = "PRODUCTS_LAYER";
        private readonly List<ulong> _uiPlayerUseNow = new List<ulong>();
        private void AddDisplayName() {
            webrequest.Enqueue($"http://api.skyplugins.ru/api/getitemlist", "", (code, response) => {
                if (code == 200) {
                    _itemList = JsonConvert.DeserializeObject<List<Items>>(response);
                    foreach (Items items in _itemList) {
                        _itemName.Add(items.ShortName, new ItemDisplayName {
                            ru = items.RUdisplayName, en = items.ENdisplayName, description = ItemManager.FindItemDefinition(items.ShortName)?.displayDescription?.english
                        }
                        );
                    }
                }
                else {
                    foreach (ItemDefinition item in ItemManager.itemList) {
                        _itemName.Add(item?.shortname, new ItemDisplayName {
                            ru = item.displayName?.english, en = item.displayName?.english, description = item.displayDescription?.english
                        }
                        );
                    }
                }
            }
            , this);
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) throw new Exception();
                SaveConfig();
            }
            catch {
                for (int i = 0; i < 3; i++) PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
                LoadDefaultConfig();
            }
            ValidateConfig();
            CheckOnDuplicates();
            SaveConfig();
        }
        private void OnKillNPC(BasePlayer npc, BasePlayer player) {
            if (!_config.humanNpcs.NPCs.ContainsKey(npc.UserIDString)) return;
            foreach (KeyValuePair<ulong, string> item in _humanNpcPlayerOpen.Where(x => x.Value == npc.UserIDString)) {
                if (!_humanNpcPlayerOpen.ContainsKey(item.Key)) continue;
                _humanNpcPlayerOpen.Remove(item.Key);
                if (_uiPlayerUseNow.Contains(player.userID.Get())) _uiPlayerUseNow.Remove(player.userID.Get());
                CuiHelper.DestroyUi(player, "NOTIFICATION_POLOSA");
                CuiHelper.DestroyUi(player, "NOTIFICATION_IMG");
                CuiHelper.DestroyUi(player, "NOTIFICATION_TEXT");
                CuiHelper.DestroyUi(player, NotificationMain);
                CuiHelper.DestroyUi(player, MainLayer);
            }
        }
        private void XDShopUI(BasePlayer player) {
            if(!string.IsNullOrWhiteSpace(_config.mainSettings.PermissionUseShop) && !permission.UserHasPermission(player.UserIDString, _config.mainSettings.PermissionUseShop)) {
                player.ChatMessage(GetLang("XDSHOP_SERVICE_5", player.UserIDString));
                return;
            }
            if(GetCategories(player).Count == 0) {
                player.ChatMessage(GetLang("XDSHOP_SERVICE_6", player.UserIDString));
                return;
            }
// ... [Code preview truncated due to length. Full source in attached file] ...

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