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

FREE Shop : 1.0.26 1.0.26

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Facepunch;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Random = UnityEngine.Random;

namespace Oxide.Plugins
{
    [Info("Shop", "Mevent", "1.0.26")]
    public class Shop : RustPlugin
    {
        #region Fields

        [PluginReference]
        private Plugin ImageLibrary, ItemCostCalculator, HumanNPC, Notify, UINotify, NoEscape, Duel, Duelist;

        private static Shop _instance;

        private readonly Dictionary<int, ShopItem> _shopItems = new Dictionary<int, ShopItem>();

        private readonly Dictionary<BasePlayer, Coroutine> _coroutines = new Dictionary<BasePlayer, Coroutine>();

        private readonly Dictionary<string, List<string>> _itemsCategories =
            new Dictionary<string, List<string>>();

        private readonly List<string> _images = new List<string>();

        private const string Layer = "UI.Shop";

        private const string ModalLayer = "UI.Shop.Modal";

        private const string EditingLayer = "UI.Shop.Editing";

        private const string PermAdmin = "Shop.admin";

        private readonly Dictionary<ulong, DataCart> _carts = new Dictionary<ulong, DataCart>();

        private class DataCart
        {
            public readonly Dictionary<ShopItem, int> Items = new Dictionary<ShopItem, int>();

            public void AddItem(ShopItem item)
            {
                if (Items.ContainsKey(item))
                    Items[item]++;
                else
                    Items.Add(item, 1);
            }

            public void RemoveItem(ShopItem item)
            {
                Items.Remove(item);
            }

            public void ChangeAmountItem(ShopItem item, int amount)
            {
                if (amount > 0)
                    Items[item] = amount;
                else
                    Items.Remove(item);
            }

            public int GetAmount()
            {
                return Items.Sum(x => x.Key.Amount * x.Value);
            }

            public double GetPrice(BasePlayer player)
            {
                return Items.Sum(x => x.Key.GetPrice(player) * x.Value);
            }

            public int GetTotalAmount()
            {
                return (from check in Items
                    let shopItem = check.Key
                    where shopItem.Type == ItemType.Item && shopItem.Definition != null
                    select shopItem.GetStacks(shopItem.Definition, shopItem.Amount * check.Value).Count).Sum();
            }

            #region Data

            public PlayerCart ToPlayerCart()
            {
                return new PlayerCart
                {
                    Items = Items.ToDictionary(x => x.Key.ID, y => y.Value)
                };
            }

            public DataCart()
            {
            }

            public DataCart(PlayerCart cart)
            {
                Items = cart.Items.ToDictionary(x => _instance.FindItemById(x.Key), y => y.Value);
            }

            #endregion
        }

        private readonly Dictionary<BasePlayer, NPCShop> _openedShops = new Dictionary<BasePlayer, NPCShop>();

        private NPCShop GetShopByPlayer(BasePlayer player)
        {
            NPCShop shop;
            return _openedShops.TryGetValue(player, out shop) ? shop : null;
        }

        private readonly Dictionary<BasePlayer, Dictionary<string, object>> _itemEditing =
            new Dictionary<BasePlayer, Dictionary<string, object>>();

        #endregion

        #region Colors

        private string _firstColor;
        private string _secondColor;
        private string _thirdColor;
        private string _fourthColor;
        private string _fifthColor;
        private string _sixthColor;
        private string _seventhColor;

        #endregion

        #region Config

        private Configuration _config;

        private class Configuration
        {
            [JsonProperty(PropertyName = "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public string[] Commands = { "shop", "shops" };

            [JsonProperty(PropertyName = "Load images when logging into the server?")]
            public bool LoginImages = true;

            [JsonProperty(PropertyName = "Work with Notify?")]
            public bool UseNotify = true;

            [JsonProperty(PropertyName = "Can admins edit? (by flag)")]
            public bool FlagAdmin = true;

            [JsonProperty(PropertyName = "Block (NoEscape)")]
            public bool BlockNoEscape;

            [JsonProperty(PropertyName = "Blocking the opening in duels?")]
            public bool UseDuels;

            [JsonProperty(PropertyName = "Delay between loading images")]
            public float ImagesDelay = 1f;

            [JsonProperty(PropertyName = "Economy")]
            public EconomyConf Economy = new EconomyConf
            {
                Type = EconomyType.Plugin,
                AddHook = "Deposit",
                BalanceHook = "Balance",
                RemoveHook = "Withdraw",
                Plug = "Economics",
                ShortName = "scrap",
                DisplayName = string.Empty,
                Skin = 0
            };

            [JsonProperty(PropertyName = "Shop", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ShopCategory> Shop = new List<ShopCategory>();

            [JsonProperty(PropertyName = "First Color")]
            public string FirstColor = "#161617";

            [JsonProperty(PropertyName = "Second Color")]
            public string SecondColor = "#4B68FF";

            [JsonProperty(PropertyName = "Third Color")]
            public string ThirdColor = "#0E0E10";

            [JsonProperty(PropertyName = "Fourth Color")]
            public string FourthColor = "#A0A935";

            [JsonProperty(PropertyName = "Fifth Color")]
            public string FifthColor = "#FF4B4B";

            [JsonProperty(PropertyName = "Sixth Color")]
            public string SixthColor = "#324192";

            [JsonProperty(PropertyName = "Seventh Color")]
            public string SeventhColor = "#CD3838";

            [JsonProperty(PropertyName = "NPC Shops (NPC ID - shop categories)",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, NPCShop> NPCs = new Dictionary<string, NPCShop>
            {
                ["1234567"] = new NPCShop
                {
                    Shops = new List<string>
                    {
                        "Tool",
                        "Food"
                    }
                },
                ["7654321"] = new NPCShop
                {
                    Shops = new List<string>
                    {
                        "Weapon",
                        "Ammunition"
                    }
                },
                ["4644687478"] = new NPCShop
                {
                    Shops = new List<string>
                    {
                        "*"
                    }
                }
            };

            [JsonProperty(PropertyName = "Interface")]
            public UserInterface UI = new UserInterface
            {
                DisplayType = "Menu",
                Width = 770,
                Height = 500,
                CategoriesOnString = 9,
                CategoriesMargin = 7.5f,
                CategoriesHeight = 40,
                ItemsOnString = 4,
                Strings = 2,
                ItemWidth = 150,
                ItemHeight = 165,
                Margin = 35,
                UseScrollCategories = true,
                EnableSearch = true,
                RoundDigits = 5
            };

            [JsonProperty(PropertyName = "Blocked skins for sell",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, List<ulong>> BlockedSkins = new Dictionary<string, List<ulong>>
            {
                ["short name"] = new List<ulong>
                {
                    52,
                    25
                },

                ["short name 2"] = new List<ulong>
                {
                    52,
                    25
                }
            };

            public VersionNumber Version;
        }

        private class UserInterface
        {
            [JsonProperty(PropertyName = "Display type (Overlay/Hud)")]
            public string DisplayType;

            [JsonProperty(PropertyName = "Height")]
            public float Height;

            [JsonProperty(PropertyName = "Width")] public float Width;

            [JsonProperty(PropertyName = "Categories On Page")]
            public int CategoriesOnString;

            [JsonProperty(PropertyName = "Categories Margin")]
            public float CategoriesMargin;

            [JsonProperty(PropertyName = "Categories Height")]
            public float CategoriesHeight;

            [JsonProperty(PropertyName = "Items On String")]
            public int ItemsOnString;

            [JsonProperty(PropertyName = "Strings")]
            public int Strings;

            [JsonProperty(PropertyName = "Item Height")]
            public float ItemHeight;

            [JsonProperty(PropertyName = "Item Width")]
            public float ItemWidth;

            [JsonProperty(PropertyName = "Margin")]
            public float Margin;

            [JsonProperty(PropertyName = "Use scroll in categories?")]
            public bool UseScrollCategories;

            [JsonProperty(PropertyName = "Enable search?")]
            public bool EnableSearch;

            [JsonProperty(PropertyName = "Number of digits after decimal point for rounding prices")]
            public int RoundDigits;
        }

        private class NPCShop
        {
            [JsonProperty(PropertyName = "Categories (Titles) [* - all]",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<string> Shops;
        }

        private class ShopCategory
        {
            [JsonProperty(PropertyName = "Enabled")]
            public bool Enabled;

            [JsonProperty(PropertyName = "Title")] public string Title;

            [JsonProperty(PropertyName = "Permission")]
            public string Permission;

            [JsonProperty(PropertyName = "Items", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<ShopItem> Items;
        }

        private enum ItemType
        {
            Item,
            Command,
            Plugin,
            Kit
        }

        private class ShopItem
        {
            [JsonProperty(PropertyName = "Type")] [JsonConverter(typeof(StringEnumConverter))]
            public ItemType Type;

            [JsonProperty(PropertyName = "ID")] public int ID;

            [JsonProperty(PropertyName = "Image")] public string Image;

            [JsonProperty(PropertyName = "Title")] public string Title;

            [JsonProperty(PropertyName = "Description")]
            public string Description;

            [JsonProperty(PropertyName = "Command (%steamid%)")]
            public string Command;

            [JsonProperty(PropertyName = "Kit")] public string Kit;

            [JsonProperty(PropertyName = "Plugin")]
            public PluginItem Plugin;

            [JsonProperty(PropertyName = "DisplayName (empty - default)")]
            public string DisplayName;

            [JsonProperty(PropertyName = "ShortName")]
            public string ShortName;

            [JsonProperty(PropertyName = "Skin")] public ulong Skin;

            [JsonProperty(PropertyName = "Amount")]
            public int Amount;

            [JsonProperty(PropertyName = "Price")] public double Price;

            [JsonProperty(PropertyName = "Sell Price")]
            public double SellPrice;

            [JsonProperty(PropertyName = "Buy Cooldown (0 - disable)")]
            public float BuyCooldown;

            [JsonProperty(PropertyName = "Sell Cooldown (0 - disable)")]
            public float SellCooldown;

            [JsonProperty(PropertyName = "Discount (%)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, int> Discount = new Dictionary<string, int>();

            [JsonProperty(PropertyName = "Sell Limits (0 - no limit)",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, int> SellLimits = new Dictionary<string, int>();

            [JsonProperty(PropertyName = "Buy Limits (0 - no limit)",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, int> BuyLimits = new Dictionary<string, int>();

            [JsonProperty(PropertyName = "Max Buy Amount (0 - disable)")]
            public int BuyMaxAmount;

            [JsonProperty(PropertyName = "Max Sell Amount (0 - disable)")]
            public int SellMaxAmount;

            [JsonIgnore] private string _publicTitle;

            [JsonIgnore]
            public string PublicTitle
            {
                get
                {
                    if (string.IsNullOrEmpty(_publicTitle))
                        _publicTitle = GetName();

                    return _publicTitle;
                }
            }

            private string GetName()
            {
                if (!string.IsNullOrEmpty(Title))
                    return Title;

                if (!string.IsNullOrEmpty(DisplayName))
                    return DisplayName;

                var def = ItemManager.FindItemDefinition(ShortName);
                if (!string.IsNullOrEmpty(ShortName) && def != null)
                    return def.displayName.translated;

                return string.Empty;
            }

            [JsonIgnore] public ItemDefinition Definition;

            public Dictionary<string, object> ToDictionary()
            {
                return new Dictionary<string, object>
                {
                    ["Generated"] = false,
                    ["ID"] = ID,
                    ["Type"] = Type,
                    ["Image"] = Image,
                    ["Title"] = Title,
                    ["Command"] = Command,
                    ["DisplayName"] = DisplayName,
                    ["ShortName"] = ShortName,
                    ["Skin"] = Skin,
                    ["Amount"] = Amount,
                    ["Price"] = Price,
                    ["SellPrice"] = SellPrice,
                    ["Plugin_Hook"] = Plugin.Hook,
                    ["Plugin_Name"] = Plugin.Plugin,
                    ["Plugin_Amount"] = Plugin.Amount
                };
            }

            public ShopItem()
            {
            }

            public ShopItem(Dictionary<string, object> dictionary)
            {
                ID = (int)dictionary["ID"];
                Type = (ItemType)dictionary["Type"];
                Image = (string)dictionary["Image"];
                Title = (string)dictionary["Title"];
                Command = (string)dictionary["Command"];
                DisplayName = (string)dictionary["DisplayName"];
                ShortName = (string)dictionary["ShortName"];
                Skin = (ulong)dictionary["Skin"];
                Amount = (int)dictionary["Amount"];
                Price = (double)dictionary["Price"];
                SellPrice = (double)dictionary["SellPrice"];
                Plugin = new PluginItem
                {
                    Hook = (string)dictionary["Plugin_Hook"],
                    Plugin = (string)dictionary["Plugin_Name"],
                    Amount = (int)dictionary["Plugin_Amount"]
                };
                Discount = new Dictionary<string, int>();
            }

            public double GetPrice(BasePlayer player)
            {
                var discount = GetDiscount(player);

                var price = Price;

                return Math.Round(discount != 0 ? price * (1f - discount / 100f) : price,
                    _instance._config.UI.RoundDigits);
            }

            public int GetDiscount(BasePlayer player)
            {
                return (from check in Discount
                    where _instance.permission.UserHasPermission(player.UserIDString, check.Key)
                    select check.Value).Prepend(0).Max();
            }

            public int GetLimit(BasePlayer player, bool buy = true)
            {
                var dict = buy ? BuyLimits : SellLimits;

                if (dict.Count == 0)
                    return 0;

                return (from check in dict
                    where _instance.permission.UserHasPermission(player.UserIDString, check.Key)
                    select check.Value).Prepend(0).Max();
            }

            public void Get(BasePlayer player, int count = 1)
            {
                switch (Type)
                {
                    case ItemType.Item:
                        ToItem(player, count);
                        break;
                    case ItemType.Command:
                        ToCommand(player, count);
                        break;
                    case ItemType.Plugin:
                        Plugin.Get(player, count);
                        break;
                    case ItemType.Kit:
                        ToKit(player, count);
                        break;
                }
            }

            private void ToKit(BasePlayer player, int count)
            {
                if (string.IsNullOrEmpty(Kit)) return;

                for (var i = 0; i < count; i++)
                    Interface.Oxide.CallHook("GiveKit", player, Kit);
            }

            private void ToItem(BasePlayer player, int count)
            {
                var def = ItemManager.FindItemDefinition(ShortName);
                if (def == null)
                {
                    Debug.LogError($"Error creating item with ShortName '{ShortName}'");
                    return;
                }

                GetStacks(def, Amount * count)?.ForEach(stack =>
                {
                    var newItem = ItemManager.Create(def, stack, Skin);
                    if (newItem == null)
                    {
                        _instance?.PrintError($"Error creating item with ShortName '{ShortName}'");
                        return;
                    }

                    if (!string.IsNullOrEmpty(DisplayName)) newItem.name = DisplayName;

                    player.GiveItem(newItem, BaseEntity.GiveItemReason.PickedUp);
                });
            }

            private void ToCommand(BasePlayer player, int count)
            {
                for (var i = 0; i < count; i++)
                {
                    var command = Command.Replace("\n", "|").Replace("%steamid%", player.UserIDString, StringComparison.OrdinalIgnoreCase).Replace(
                            "%username%",
                            player.displayName, StringComparison.OrdinalIgnoreCase);

                    foreach (var check in command.Split('|')) _instance?.Server.Command(check);
                }
            }

            public List<int> GetStacks(ItemDefinition item, int amount)
            {
                var list = new List<int>();
                var maxStack = item.stackable;

                if (maxStack == 0) maxStack = 1;

                while (amount > maxStack)
                {
                    amount -= maxStack;
                    list.Add(maxStack);
                }

                list.Add(amount);

                return list;
            }
        }

        private class PluginItem
        {
            [JsonProperty(PropertyName = "Hook")] public string Hook;

            [JsonProperty(PropertyName = "Plugin Name")]
            public string Plugin;

            [JsonProperty(PropertyName = "Amount")]
            public int Amount;

            public void Get(BasePlayer player, int count = 1)
            {
                var plug = _instance?.plugins.Find(Plugin);
                if (plug == null)
                {
                    _instance?.PrintError($"Plugin '{Plugin}' not found !!! ");
                    return;
                }

                switch (Plugin)
                {
                    case "Economics":
                    {
                        plug.Call(Hook, player.userID, (double)Amount * count);
                        break;
                    }
                    default:
                    {
                        plug.Call(Hook, player.userID, Amount * count);
                        break;
                    }
                }
            }
        }

        private enum EconomyType
        {
            Plugin,
            Item
        }

        private class EconomyConf
        {
            [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;

            public double ShowBalance(BasePlayer player)
            {
                switch (Type)
                {
                    case EconomyType.Plugin:
                    {
                        var plugin = _instance?.plugins?.Find(Plug);
                        if (plugin == null) return 0;

                        return Math.Round(Convert.ToDouble(plugin.Call(BalanceHook, player.userID)));
                    }
                    case EconomyType.Item:
                    {
                        return ItemCount(player.inventory.AllItems(), 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":
                                plugin.Call(AddHook, player.userID, (int)amount);
                                break;
                            default:
                                plugin.Call(AddHook, player.userID, 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":
                                plugin.Call(RemoveHook, player.userID, (int)amount);
                                break;
                            default:
                                plugin.Call(RemoveHook, player.userID, amount);
                                break;
                        }

                        return true;
                    }
                    case EconomyType.Item:
                    {
                        var playerItems = player.inventory.AllItems();
                        var am = (int)amount;

                        if (ItemCount(playerItems, ShortName, Skin) < am) return false;

                        Take(playerItems, ShortName, Skin, am);
                        return true;
                    }
                    default:
                        return false;
                }
            }

            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;
            }
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<Configuration>();
                if (_config == null) throw new Exception();

                if (_config.Version < Version)
                    UpdateConfigValues();

                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();
        }

        private void UpdateConfigValues()
        {
            PrintWarning("Config update detected! Updating config values...");

            var baseConfig = new Configuration();

            if (_config.Version == default(VersionNumber) && _config.Version < new VersionNumber(1, 0, 21))
            {
                _data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>(Name);
                if (_data != null)
                    Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Players", _data);
            }

            if (_config.Version < new VersionNumber(1, 0, 21))
                _config.Shop.ForEach(shop =>
                {
                    shop.Items.ForEach(item =>
                    {
                        item.SellLimits = new Dictionary<string, int>
                        {
                            ["shop.default"] = 0,
                            ["shop.vip"] = 0
                        };
                        item.BuyLimits = new Dictionary<string, int>
                        {
                            ["shop.default"] = 0,
                            ["shop.vip"] = 0
                        };
                    });
                });

            if (_config.Version < new VersionNumber(1, 0, 24)) _config.UI.DisplayType = baseConfig.UI.DisplayType;

            _config.Version = Version;
            PrintWarning("Config update completed!");
        }

        #endregion

        #region Data

        private PluginData _data;

        private void SaveData()
        {
            SavePlayers();

            SaveCooldown();

            SaveLimits();
        }

        private void SavePlayers()
        {
            _data.PlayerCarts.Clear();

            foreach (var check in _carts)
                _data.PlayerCarts.Add(check.Key, check.Value.ToPlayerCart());

            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Players", _data);
        }

        private void SaveCooldown()
        {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Cooldown", _cooldown);
        }

        private void SaveLimits()
        {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Limits", _limits);
        }

        private void LoadData()
        {
            try
            {
                _data = Interface.Oxide.DataFileSystem.ReadObject<PluginData>($"{Name}/Players");
                _cooldown = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, Cooldown>>($"{Name}/Cooldown");
                _limits = Interface.Oxide.DataFileSystem.ReadObject<PlayerLimits>($"{Name}/Limits");
            }
            catch (Exception e)
            {
                PrintError(e.ToString());
            }

            if (_data == null) _data = new PluginData();
            if (_cooldown == null) _cooldown = new Dictionary<ulong, Cooldown>();
            if (_limits == null) _limits = new PlayerLimits();
        }

        private class PluginData
        {
            [JsonProperty(PropertyName = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<ulong, PlayerCart> PlayerCarts = new Dictionary<ulong, PlayerCart>();
        }

        private class PlayerCart
        {
            [JsonProperty(PropertyName = "Items", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<int, int> Items = new Dictionary<int, int>();
        }

        #endregion

        #region Hooks

        private void Init()
        {
            _instance = this;

            LoadData();

            if (!_config.LoginImages)
                Unsubscribe(nameof(OnPlayerConnected));

            _firstColor = HexToCuiColor(_config.FirstColor);
            _secondColor = HexToCuiColor(_config.SecondColor);
            _thirdColor = HexToCuiColor(_config.ThirdColor);
            _fourthColor = HexToCuiColor(_config.FourthColor);
            _fifthColor = HexToCuiColor(_config.FifthColor);
            _sixthColor = HexToCuiColor(_config.SixthColor);
            _seventhColor = HexToCuiColor(_config.SeventhColor);
        }

        private void OnServerInitialized()
        {
            if (_config.Shop.Count == 0)
                FillCategories();

            LoadImages();

            _config.Shop.ForEach(category =>
            {
                if (!string.IsNullOrEmpty(category.Permission) && !permission.PermissionExists(category.Permission))
                    permission.RegisterPermission(category.Permission, this);
            });

            if (!permission.PermissionExists(PermAdmin))
                permission.RegisterPermission(PermAdmin, this);

            CheckOnDuplicates();

            ItemsToDict();

            foreach (var image in _shopItems.Values.Select(shopItem => !string.IsNullOrEmpty(shopItem.Image) ? shopItem.Image : shopItem.ShortName).Where(image => !_images.Contains(image))) _images.Add(image);

            foreach (var check in _data.PlayerCarts)
                _carts.Add(check.Key, new DataCart(check.Value));

            if (_config.LoginImages)
                foreach (var player in BasePlayer.activePlayerList)
                    OnPlayerConnected(player);

            AddCovalenceCommand(_config.Commands, nameof(CmdShopOpen));

            if (_shopItems.Any(x => x.Value.BuyCooldown > 0 || x.Value.SellCooldown > 0))
                timer.Every(1, ItemsUpdateController);
        }

        private void Unload()
        {
            foreach (var player in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(player, Layer);
                CuiHelper.DestroyUi(player, ModalLayer);
                CuiHelper.DestroyUi(player, EditingLayer);

                OnPlayerDisconnected(player);
            }

            SaveData();

            _instance = null;
        }

        private void OnPlayerConnected(BasePlayer player)
        {
            if (player == null) return;

            var coroutine = ServerMgr.Instance.StartCoroutine(LoadImages(player));

            if (_coroutines.ContainsKey(player))
                _coroutines[player] = coroutine;
            else
                _coroutines.Add(player, coroutine);
        }

        private void OnPlayerDisconnected(BasePlayer player)
        {
            if (player == null) return;

            _itemsToUpdate.Remove(player);

            if (_itemEditing.ContainsKey(player)) _itemEditing.Remove(player);

            if (_coroutines.ContainsKey(player))
            {
                var coroutine = _coroutines[player];
                if (coroutine != null)
                    ServerMgr.Instance.StopCoroutine(coroutine);
            }
        }

        private void OnUseNPC(BasePlayer npc, BasePlayer player)
        {
            if (npc == null || player == null) return;

            NPCShop npcShop;
            if (!_config.NPCs.TryGetValue(npc.UserIDString, out npcShop) || npcShop == null) return;

            _openedShops[player] = npcShop;

            MainUi(player, npcShop: npcShop, first: true);
        }

        #endregion

        #region Commands

        private void CmdShopOpen(IPlayer cov, string command, string[] args)
        {
            var player = cov?.Object as BasePlayer;
            if (player == null) return;

            if (_config.UseDuels && InDuel(player))
            {
                SendNotify(player, NoUseDuel, 1);
                return;
            }

            MainUi(player, first: true);
        }

        [ConsoleCommand("UI_Shop")]
        private void CmdConsoleShop(ConsoleSystem.Arg arg)
        {
            var player = arg?.Player();
            if (player == null || !arg.HasArgs()) return;

            switch (arg.Args[0])
            {
                case "closeui":
                {
                    _itemsToUpdate.Remove(player);
                    _openedShops.Remove(player);
                    break;
                }

                case "main_page":
                {
                    int catPage, page;
                    if (!arg.HasArgs(3) || !int.TryParse(arg.Args[1], out catPage) ||
                        !int.TryParse(arg.Args[2], out page)) return;

                    var search = string.Empty;
                    if (arg.HasArgs(4)) search = string.Join(" ", arg.Args.Skip(3));

                    if (string.IsNullOrEmpty(search) && catPage == -1)
                        catPage = 0;

                    MainUi(player, catPage, page, GetShopByPlayer(player), search);
                    break;
                }

                case "buyitem":
                {
                    int id;
                    if (!arg.HasArgs(2) ||
                        !int.TryParse(arg.Args[1], out id)) return;

                    var shopItem = FindItemById(id);
                    if (shopItem == null) return;

                    var playerCart = GetPlayerCart(player);
                    if (playerCart == null) return;

                    playerCart.AddItem(shopItem);

                    var cooldownTime = GetCooldownTime(player.userID, shopItem, true);
                    if (cooldownTime > 0)
                    {
                        SendNotify(player, BuyCooldownMessage, 1, shopItem.PublicTitle,
                            FormatShortTime(player, TimeSpan.FromSeconds(cooldownTime)));
                        return;
                    }

                    var container = new CuiElementContainer();
                    RefreshCart(ref container, player, playerCart);
                    CuiHelper.AddUi(player, container);
                    break;
                }

                case "changeicat":
                {
                    int catPage, iCategory;
                    if (!arg.HasArgs(3) || !int.TryParse(arg.Args[1], out catPage) ||
                        !int.TryParse(arg.Args[2], out iCategory)) return;

                    var container = new CuiElementContainer();
                    RefreshCategories(ref container, player, GetCategories(player, GetShopByPlayer(player)), catPage,
                        iCategory);
                    CuiHelper.AddUi(player, container);
                    break;
                }

                case "gocat":
                {
                    int catPage, iCategory;
                    if (!arg.HasArgs(3) || !int.TryParse(arg.Args[1], out catPage) ||
                        !int.TryParse(arg.Args[2], out iCategory)) return;

                    MainUi(player, catPage, npcShop: GetShopByPlayer(player));

                    var container = new CuiElementContainer();
                    RefreshCategories(ref container, player, GetCategories(player, GetShopByPlayer(player)), catPage,
                        iCategory);
                    CuiHelper.AddUi(player, container);
                    break;
                }

                case "cart_page":
                {
                    int page;
                    if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out page)) return;

                    var playerCart = GetPlayerCart(player);
                    if (playerCart == null) return;

                    var container = new CuiElementContainer();
                    RefreshCart(ref container, player, playerCart, page);
                    CuiHelper.AddUi(player, container);
                    break;
                }

                case "cart_item_remove":
                {
                    int id;
                    if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out id)) return;

                    var shopItem = FindItemById(id);
                    if (shopItem == null) return;

                    var playerCart = GetPlayerCart(player);
                    if (playerCart == null) return;

                    playerCart.RemoveItem(shopItem);

                    var container = new CuiElementContainer();
                    RefreshCart(ref container, player, playerCart);
                    CuiHelper.AddUi(player, container);
                    break;
                }

                case "cart_item_change":
                {
                    int id, amount;
                    if (!arg.HasArgs(3) ||
                        !int.TryParse(arg.Args[1], out id) ||
                        !int.TryParse(arg.Args[2], out amount)) return;

                    var shopItem = FindItemById(id);
                    if (shopItem == null) return;

                    var playerCart = GetPlayerCart(player);
                    if (playerCart == null) return;

                    if (shopItem.BuyMaxAmount > 0 && amount > shopItem.BuyMaxAmount)
                        amount = shopItem.BuyMaxAmount;

                    playerCart.ChangeAmountItem(shopItem, amount);

                    var container = new CuiElementContainer();
                    RefreshCart(ref container, player, playerCart);
                    CuiHelper.AddUi(player, container);
                    break;
                }

                case "cart_try_buyitems":
                {
                    AcceptBuy(player);
                    break;
                }

                case "cart_buyitems":
                {
                    var playerCart = GetPlayerCart(player);
                    if (playerCart == null) return;

                    var price = playerCart.GetPrice(player);
                    if (price <= 0) return;

                    if (_config.BlockNoEscape && NoEscape != null)
                    {
                        var success = NoEscape?.Call("IsBlocked", player);
                        if (success is bool && (bool)success)
                        {
                            ErrorUi(player, Msg(player, BuyRaidBlocked));
                            return;
                        }
                    }

                    var totalcount = playerCart.GetTotalAmount();

                    var slots = player.inventory.containerBelt.capacity -
                                player.inventory.containerBelt.itemList.Count +
                                (player.inventory.containerMain.capacity -
                                 player.inventory.containerMain.itemList.Count);
                    if (slots < totalcount)
                    {
                        ErrorUi(player, Msg(player, NotEnoughtSpace));
                        return;
                    }

                    if (!_config.Economy.RemoveBalance(player, price))
                    {
                        ErrorUi(player, Msg(player, NotMoney));
                        return;
                    }

                    if (playerCart.Items.Any(x =>
                    {
                        var limit = GetLimit(player, x.Key, true);
                        if (limit > 0) return false;

                        ErrorUi(player, Msg(player, BuyLimitReached, x.Key.PublicTitle));
                        return true;
                    }))
                        return;

                    foreach (var cartItem in playerCart.Items)
                    {
                        cartItem.Key?.Get(player, cartItem.Value);

                        SetCooldown(player, cartItem.Key, true);
                        UseLimit(player, cartItem.Key, true);
                    }

                    CuiHelper.DestroyUi(player, Layer);
                    _carts.Remove(player.userID);
                    _itemsToUpdate.Remove(player);

                    SendNotify(player, ReceivedItems, 0);
                    break;
                }

                case "trysellitem":
                {
                    int itemId;
                    if (!arg.HasArgs(2) || !int.TryParse(arg.Args[1], out itemId)) return;

                    var item = FindItemById(itemId);
                    if (item == null) return;

                    var amount = 1;
                    if (arg.HasArgs(3) && !int.TryParse(arg.Args[2], out amount) || amount < 1) return;

                    if (item.SellMaxAmount > 0 && amount > item.SellMaxAmount) amount = item.SellMaxAmount;

                    SellUi(player, item, amount);
                    break;
                }

                case "sellitem":
                {
                    int itemId, amount;
                    if (!arg.HasArgs(3) ||
                        !int.TryParse(arg.Args[1], out itemId) ||
                        !int.TryParse(arg.Args[2], out amount)) return;

                    var item = FindItemById(itemId);
                    if (item == null) return;

                    var cooldownTime = GetCooldownTime(player.userID, item, false);
                    if (cooldownTime > 0)
                    {
                        ErrorUi(player, Msg(player, SellCooldownMessage));
                        return;
                    }

                    if (_config.BlockNoEscape && NoEscape != null)
                    {
                        var success = NoEscape?.Call("IsBlocked", player);
                        if (success is bool && (bool)success)
                        {
                            ErrorUi(player, Msg(player, SellRaidBlocked));
                            return;
                        }
                    }

                    var limit = GetLimit(player, item, false);
                    if (limit <= 0)
                    {
                        ErrorUi(player, Msg(player, SellLimitReached, item.PublicTitle));
                        return;
                    }

                    List<ulong> blockedSkins;
                    if (_config.BlockedSkins.TryGetValue(item.ShortName, out blockedSkins))
                        if (blockedSkins.Contains(item.Skin))
                        {
                            ErrorUi(player, Msg(player, SkinBlocked));
                            return;
                        }

                    var totalAmount = item.Amount * amount;
                    var playerItems = player.inventory.AllItems();

                    if (ItemCount(playerItems, item.ShortName, item.Skin) < totalAmount)
                    {
                        ErrorUi(player, Msg(player, NotEnough));
                        return;
                    }

                    Take(playerItems, item.ShortName, item.Skin, totalAmount);

                    _config.Economy.AddBalance(player, item.SellPrice * amount);

                    SetCooldown(player, item, false, true);
                    UseLimit(player, item, false);

                    if (_itemsToUpdate.ContainsKey(player))
                    {
                        if (!_itemsToUpdate[player].Contains(item))
                            _itemsToUpdate[player].Add(item);
                    }
                    else
                    {
                        _itemsToUpdate.Add(player, new List<ShopItem> { item });
                    }


                    var container = new CuiElementContainer();
                    SellButtonUi(player, ref container, item);
                    BalanceUi(ref container, player);
                    CuiHelper.AddUi(player, container);

                    SendNotify(player, SellNotify, 0, totalAmount, item.PublicTitle);
                    break;
                }

                case "startedititem":
                {
                    int id, category, page;
                    if (!IsAdmin(player) || !arg.HasArgs(4) ||
                        !int.TryParse(arg.Args[1], out category) ||
                        !int.TryParse(arg.Args[2], out page) ||
                        !int.TryParse(arg.Args[3], out id)) return;

                    _itemEditing.Remove(player);

                    EditUi(player, category, page, id, true);
                    break;
                }

                case "edititem":
                {
                    int category, page;
                    if (!IsAdmin(player) || !arg.HasArgs(5) || !int.TryParse(arg.Args[1], out category) ||
                        !int.TryParse(arg.Args[2], out page)) return;

            
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху