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

FREE Shop : 1.1.2 1.1.2

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

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

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

        private static Shop _instance;

        private bool _enabledImageLibrary;

        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<KeyValuePair<int, string>>> _itemsCategories =
            new Dictionary<string, List<KeyValuePair<int, string>>>();

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

        private List<ulong> _openedUI = new List<ulong>();

        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 const string PermFreeBypass = "Shop.free";

        private const string PermSetVM = "Shop.setvm";

        private const int _itemsPerTick = 10;

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

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

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

        private Timer _updateController;

        #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 static Configuration _config;

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

            [JsonProperty(PropertyName = "Enable money transfers between players??")]
            public readonly bool Transfer = true;

            [JsonProperty(PropertyName = "Enable logging to the console?")]
            public readonly bool LogToConsole = true;

            [JsonProperty(PropertyName = "Enable logging to the file?")]
            public readonly bool LogToFile = true;

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

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

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

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

            [JsonProperty(PropertyName = "Wipe Block")]
            public bool WipeCooldown = false;

            [JsonProperty(PropertyName = "Wipe Cooldown")]
            public float WipeCooldownTimer = 3600;

            [JsonProperty(PropertyName = "Respawn Block")]
            public bool RespawnCooldown = true;

            [JsonProperty(PropertyName = "Respawn Cooldown")]
            public float RespawnCooldownTimer = 60;

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

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

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

            [JsonProperty(PropertyName = "Additional Economics",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public List<AdditionalEconomy> AdditionalEconomics = new List<AdditionalEconomy>
            {
                new AdditionalEconomy
                {
                    ID = 1,
                    Enabled = true,
                    Type = EconomyType.Plugin,
                    AddHook = "AddPoints",
                    BalanceHook = "CheckPoints",
                    RemoveHook = "TakePoints",
                    Plug = "ServerRewards",
                    ShortName = "scrap",
                    DisplayName = string.Empty,
                    Skin = 0,
                    TitleLangKey = "sr_title",
                    BalanceLangKey = "sr_balance"
                }
            };

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

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

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

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

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

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

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

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

            [JsonProperty(PropertyName = "NPC Shops (NPC ID - shop categories)",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public readonly 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 readonly UserInterface UI = new UserInterface
            {
                DisplayType = "Overlay",
                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,
                SelectCurrency = new SelectCurrencyUI
                {
                    Title = new LabelSettings
                    {
                        Align = TextAnchor.MiddleCenter,
                        Font = "robotocondensed-bold.ttf",
                        FontSize = 14,
                        Color = new IColor("#FFFFFF")
                    },
                    TitlePosition = new InterfacePosition
                    {
                        AnchorMin = "0 1", AnchorMax = "1 1",
                        OffsetMin = "0 -30", OffsetMax = "0 0"
                    },
                    EconomyTitle = new LabelSettings
                    {
                        Align = TextAnchor.MiddleCenter,
                        Font = "robotocondensed-regular.ttf",
                        FontSize = 12,
                        Color = new IColor("#FFFFFF")
                    },
                    SelectedEconomyColor = new IColor("#4B68FF"),
                    UnselectedEconomyColor = new IColor("#4B68FF", 33),
                    EconomyWidth = 105f,
                    EconomyHeight = 25f,
                    EconomyMargin = 5f,
                    EconomyIndent = 5f,
                    FrameWidth = 10,
                    FrameIndent = 15,
                    FrameHeader = 35,
                    CloseAfterChange = true
                }
            };

            [JsonProperty(PropertyName = "Blocked skins for sell",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public readonly 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
                }
            };

            [JsonProperty(PropertyName = "Auto-Wipe Settings")]
            public WipeSettings Wipe = new WipeSettings
            {
                Cooldown = true,
                Players = true,
                Limits = true
            };

            [JsonProperty(PropertyName = "Custom Vending Machines (Entity ID - settings)",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public readonly Dictionary<uint, CustomVendingConf> CustomVending =
                new Dictionary<uint, CustomVendingConf>
                {
                    [123343941] = new CustomVendingConf
                    {
                        Categories = new List<string>
                        {
                            "Cars", "Misc"
                        }
                    }
                };

            public VersionNumber Version;
        }

        private class SelectCurrencyUI
        {
            [JsonProperty(PropertyName = "Title")] public LabelSettings Title;

            [JsonProperty(PropertyName = "Title Position")]
            public InterfacePosition TitlePosition;

            [JsonProperty(PropertyName = "Economy Title")]
            public LabelSettings EconomyTitle;

            [JsonProperty(PropertyName = "Selected Economy Color")]
            public IColor SelectedEconomyColor;

            [JsonProperty(PropertyName = "Unselected Economy Color")]
            public IColor UnselectedEconomyColor;

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

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

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

            [JsonProperty(PropertyName = "Economy Indent")]
            public float EconomyIndent;

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

            [JsonProperty(PropertyName = "Frame Indent")]
            public float FrameIndent;

            [JsonProperty(PropertyName = "Frame Header")]
            public float FrameHeader;

            [JsonProperty(PropertyName = "Close the menu after a currency change?")]
            public bool CloseAfterChange;
        }

        private class InterfacePosition
        {
            public string AnchorMin;

            public string AnchorMax;

            public string OffsetMin;

            public string OffsetMax;
        }

        private class LabelSettings
        {
            [JsonProperty(PropertyName = "FontSize")]
            public int FontSize;

            [JsonProperty(PropertyName = "Align")] [JsonConverter(typeof(StringEnumConverter))]
            public TextAnchor Align;

            [JsonProperty(PropertyName = "Color")] public IColor Color;

            [JsonProperty(PropertyName = "Font")] public string Font;
        }

        private class IColor
        {
            [JsonProperty(PropertyName = "HEX")] public string Hex;

            [JsonProperty(PropertyName = "Opacity (0 - 100)")]
            public readonly float Alpha;

            [JsonIgnore] private string _color;

            [JsonIgnore]
            public string Get
            {
                get
                {
                    if (string.IsNullOrEmpty(_color))
                        _color = GetColor();

                    return _color;
                }
            }

            private string GetColor()
            {
                if (string.IsNullOrEmpty(Hex)) Hex = "#FFFFFF";

                var str = Hex.Trim('#');
                if (str.Length != 6) throw new Exception(Hex);
                var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
                var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
                var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);

                return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
            }

            public IColor()
            {
            }

            public IColor(string hex, float alpha = 100)
            {
                Hex = hex;
                Alpha = alpha;
            }
        }

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

        private class WipeSettings
        {
            [JsonProperty(PropertyName = "Wipe Cooldowns?")]
            public bool Cooldown;

            [JsonProperty(PropertyName = "Wipe Players?")]
            public bool Players;

            [JsonProperty(PropertyName = "Wipe Limits?")]
            public bool Limits;
        }

        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;

            [JsonProperty(PropertyName = "Select Currency Settings")]
            public SelectCurrencyUI SelectCurrency;
        }

        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 = string.Empty;

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

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

            [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 = 0;

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

            [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 = "Daily Buy Limits (0 - no limit)",
                ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, int> DailyBuyLimits = new Dictionary<string, int>();

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

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

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

            [JsonProperty(PropertyName = "Force Buy")]
            public bool ForceBuy;

            [JsonIgnore] private int _itemId = -1;

            [JsonIgnore]
            public int itemId
            {
                get
                {
                    if (_itemId == -1)
                        _itemId = ItemManager.FindItemDefinition(ShortName)?.itemid ?? -1;

                    return _itemId;
                }
            }

            [JsonIgnore] private string _publicTitle;

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

                    return _publicTitle;
                }
            }

            [JsonIgnore] private ICuiComponent _image;

            public CuiElement GetImage(string aMin, string aMax, string oMin, string oMax, string parent,
                string name = null)
            {
                if (_image == null)
                {
                    if (_instance._enabledImageLibrary && !string.IsNullOrEmpty(Image))
                        _image = new CuiRawImageComponent
                        {
                            Png = _instance.ImageLibrary.Call<string>("GetImage", Image)
                        };
                    else
                        _image = new CuiImageComponent
                        {
                            ItemId = itemId,
                            SkinId = Skin
                        };
                }

                return new CuiElement
                {
                    Name = string.IsNullOrEmpty(name) ? CuiHelper.GetGuid() : name,
                    Parent = parent,
                    Components =
                    {
                        _image,
                        new CuiRectTransformComponent
                        {
                            AnchorMin = aMin, AnchorMax = aMax,
                            OffsetMin = oMin, OffsetMax = oMax
                        }
                    }
                };
            }

            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,
                    _config.UI.RoundDigits);
            }

            public int GetDiscount(BasePlayer player)
            {
                var result = 0;
                Discount.Where(check => player.HasPermission(check.Key)).ForEach(
                    check =>
                    {
                        if (check.Value > result)
                            result = check.Value;
                    });

                return result;
            }

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

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

                var result = 0;
                dict.Where(check => player.HasPermission(check.Key)).ForEach(
                    check =>
                    {
                        if (check.Value > result)
                            result = check.Value;
                    });

                return result;
            }

            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('|'))
                        if (check.Contains("chat.say"))
                        {
                            var args = check.Split(' ');
                            player.SendConsoleCommand(
                                $"{args[0]}  \" {string.Join(" ", args.ToList().GetRange(1, args.Length - 1))}\" 0");
                        }
                        else
                        {
                            _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;
            }

            public override string ToString()
            {
                switch (Type)
                {
                    case ItemType.Item:
                        return $"[ITEM-{ID}] {ShortName}x{Amount}(DN: {DisplayName}, SKIN: {Skin})";
                    case ItemType.Command:
                        return $"[COMMAND-{ID}] {Command}";
                    case ItemType.Plugin:
                        return
                            $"[PLUGIN-{ID}] Name: {Plugin?.Plugin}, Hook: {Plugin?.Hook}, Amount: {Plugin?.Amount ?? 0}";
                    case ItemType.Kit:
                        return $"[KIT-{ID}] {Kit}";
                    default:
                        return base.ToString();
                }
            }
        }

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

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

            [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 class AdditionalEconomy : EconomyConf
        {
            [JsonProperty(PropertyName = "ID")] public int ID;

            [JsonProperty(PropertyName = "Enabled")]
            public bool Enabled;

            public bool IsSame(EconomyConf configEconomy)
            {
                return Type == configEconomy.Type &&
                       Plug == configEconomy.Plug &&
                       ShortName == configEconomy.ShortName &&
                       Skin == configEconomy.Skin;
            }

            public AdditionalEconomy(EconomyConf configEconomy)
            {
                Type = configEconomy.Type;
                Plug = configEconomy.Plug;
                AddHook = configEconomy.AddHook;
                RemoveHook = configEconomy.RemoveHook;
                BalanceHook = configEconomy.BalanceHook;
                ShortName = configEconomy.ShortName;
                DisplayName = configEconomy.DisplayName;
                Skin = configEconomy.Skin;
                TitleLangKey = configEconomy.TitleLangKey;
                BalanceLangKey = configEconomy.BalanceLangKey;
                ID = 0;
                Enabled = true;
            }

            [JsonConstructor]
            public AdditionalEconomy()
            {
            }
        }

        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;

            [JsonProperty(PropertyName = "Lang Key (for Title)")]
            public string TitleLangKey;

            [JsonProperty(PropertyName = "Lang Key (for Balance)")]
            public string BalanceLangKey;

            public string GetTitle(BasePlayer player)
            {
                return _instance.Msg(player, TitleLangKey);
            }

            public string GetBalanceTitle(BasePlayer player)
            {
                return _instance.Msg(player, BalanceLangKey, ShowBalance(player));
            }

            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)), 2);
                    }
                    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;
                }
            }

            public bool Transfer(BasePlayer player, BasePlayer targetPlayer, double amount)
            {
                if (!RemoveBalance(player, amount))
                    return false;

                AddBalance(targetPlayer, amount);
                return true;
            }

            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
                        };
                        item.DailyBuyLimits = new Dictionary<string, int>
                        {
                            ["shop.default"] = 0,
                            ["shop.vip"] = 0
                        };
                        item.DailySellLimits = 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();

            SaveSelectEconomy();
        }

        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 SaveSelectEconomy()
        {
            Interface.Oxide.DataFileSystem.WriteObject($"{Name}/EconomyChoice", _economyChoice);
        }

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

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

        private class PluginData
        {
            [JsonProperty(PropertyName = "Players", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public readonly 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>();
        }

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

            public void AddCartItem(ShopItem item, BasePlayer player)
            {
                int result;
                int amount;
                if (Items.TryGetValue(item, out amount))
                {
                    if (item.BuyMaxAmount > 0 && amount >= item.BuyMaxAmount) return;

                    if (!CanCartAdd(player, item, amount + 1, out result))
                    {
                        _instance.SendNotify(player, result == 1 ? BuyLimitReached : DailyBuyLimitReached, 1,
                            item.PublicTitle);
                        return;
                    }

                    Items[item]++;
                }
                else
                {
                    if (!CanCartAdd(player, item, 1, out result))
                    {
                        _instance.SendNotify(player, result == 1 ? BuyLimitReached : DailyBuyLimitReached, 1,
                            item.PublicTitle);
                        return;
                    }

                    Items.Add(item, 1);
                }
            }

            private bool CanCartAdd(BasePlayer player, ShopItem item, int amount, out int result)
            {
                int leftLimit;
                if (HasLimit(player, item, true, out leftLimit) && amount >= leftLimit) //total Limit
                {
                    result = 1;
                    return false;
                }

                if (HasLimit(player, item, true, out leftLimit, true) && amount > leftLimit) //daily Limit
                {
                    result = 2;
                    return false;
                }

                result = 0;
                return true;
            }

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

            public void ChangeAmountItem(BasePlayer player, ShopItem item, int amount)
            {
                if (amount > 0)
                {
                    int totalLimit;
                    if (HasLimit(player, item, true, out totalLimit) && amount >= totalLimit)
                        amount = Math.Min(totalLimit, amount);

                    int dailyLimit;
                    if (HasLimit(player, item, true, out dailyLimit, true) && amount >= dailyLimit)
                        amount = Math.Min(dailyLimit, amount);

                    if (amount <= 0) return;

                    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
// ... [Code preview truncated due to length. Full source in attached file] ...

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