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

FREE Shop : 1.2.12 1.2.12

Нет прав для скачивания
C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
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", "Sempai#3239", "1.2.12")]
	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 string PermSetNPC = "Shop.setnpc";

		private const int _itemsPerTick = 10;

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

		private readonly Dictionary<ulong, Dictionary<string, DataCart>> _cartsNPC =
			new Dictionary<ulong, Dictionary<string, 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
		{
			#region Fields

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

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

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

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

			[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 = 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 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,
				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 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 = "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 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 Dictionary<uint, CustomVendingConf> CustomVending =
				new Dictionary<uint, CustomVendingConf>
				{
					[123343941] = new CustomVendingConf
					{
						Categories = new List<string>
						{
							"Cars", "Misc"
						}
					}
				};

			[JsonProperty(PropertyName = "Settings available containers for selling item")]
			public SellContainers SellContainers = new SellContainers
			{
				Enabled = true,
				Containers = new List<string>
				{
					"main",
					"belt"
				}
			};

			public VersionNumber Version;

			#endregion

			#region Classes

			public enum SortType
			{
				None,
				Name,
				Amount,
				PriceDecrease,
				PriceIncrease
			}

			#endregion
		}

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

			[JsonProperty(PropertyName = "Available Containers (main, belt, wear)",
				ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public List<string> Containers = new List<string>();

			public List<ItemContainer> GetContainers(BasePlayer player)
			{
				if (player == null || player.inventory == null)
					return new List<ItemContainer>();

				var list = new List<ItemContainer>();

				Containers.ForEach(cont =>
				{
					switch (cont)
					{
						case "main":
						{
							list.Add(player.inventory.containerMain);
							break;
						}
						case "belt":
						{
							list.Add(player.inventory.containerBelt);
							break;
						}
						case "wear":
						{
							list.Add(player.inventory.containerWear);
							break;
						}
					}
				});

				return list;
			}

			public Item[] AllItems(BasePlayer player)
			{
				var items = new List<Item>();

				GetContainers(player).ForEach(cont => items.AddRange(cont.itemList));

				return items.ToArray();
			}
		}

		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;

			[JsonIgnore] public string BotID;
		}

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

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

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

			[JsonProperty(PropertyName = "Sort Type")]
			[JsonConverter(typeof(StringEnumConverter))]
			[DefaultValue(Configuration.SortType.None)]
			public Configuration.SortType SortType;

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

			[JsonIgnore] public List<ShopItem> SortedItems;

			[JsonIgnore]
			public List<ShopItem> GetItems
			{
				get
				{
					switch (SortType)
					{
						case Configuration.SortType.None:
							return Items;
						default:
							if (SortedItems == null) SortItems();

							return SortedItems;
					}
				}
			}

			public void SortItems()
			{
				switch (SortType)
				{
					case Configuration.SortType.Name:
					{
						SortedItems = Items.ToList();
						SortedItems.Sort((x, y) =>
							string.Compare(x.PublicTitle, y.PublicTitle, StringComparison.Ordinal));
						break;
					}
					case Configuration.SortType.Amount:
					{
						SortedItems = Items.ToList();
						SortedItems.Sort((x, y) => x.Amount.CompareTo(y.Amount));
						break;
					}
					case Configuration.SortType.PriceIncrease:
					{
						SortedItems = Items.ToList();
						SortedItems.Sort((x, y) => x.Amount.CompareTo(y.Price));
						break;
					}
					case Configuration.SortType.PriceDecrease:
					{
						SortedItems = Items.ToList();
						SortedItems.Sort((x, y) => y.Amount.CompareTo(x.Price));
						break;
					}
					default:
					{
						SortedItems = Items.ToList();
						break;
					}
				}

				LoadIDs(true);
			}

			public void LoadIDs(bool sort = false)
			{
				if (sort)
					Items.ForEach(item => _instance._shopItems.Remove(item.ID));

				GetItems.ForEach(item =>
				{
					var id = item.ID;
					if (_instance._shopItems.ContainsKey(item.ID))
						id = _instance.GetId();
					_instance._shopItems.Add(id, item);

					if (item.Discount != null)
						foreach (var check in item.Discount)
							if (!string.IsNullOrEmpty(check.Key) && !_instance.permission.PermissionExists(check.Key))
								_instance.permission.RegisterPermission(check.Key, _instance);

					if (item.Type == ItemType.Item && item.Definition == null && !string.IsNullOrEmpty(item.ShortName))
						item.Definition = !string.IsNullOrEmpty(item.ShortName)
							? ItemManager.FindItemDefinition(item.ShortName)
							: null;
				});
			}
		}

		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 = "Is Blueprint")]
			public bool Blueprint;

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

			[JsonProperty(PropertyName = "Prohibit splitting item into stacks?")]
			public bool ProhibitSplit;

			[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,
					["Blueprint"] = Blueprint,
					["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"];
				Blueprint = (bool) dictionary["Blueprint"];
				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);
			}

			[JsonIgnore] private ItemDefinition _itemDefinition;

			[JsonIgnore]
			public ItemDefinition ItemDefinition
			{
				get
				{
					if (_itemDefinition == null) _itemDefinition = ItemManager.FindItemDefinition(ShortName);

					return _itemDefinition;
				}
			}

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

				if (Blueprint)
				{
					GiveBlueprint(Amount * count, player);
				}
				else
				{
					if (ProhibitSplit)
						GiveItem(Amount * count, player);
					else
						GetStacks(count)?.ForEach(stack => GiveItem(stack, player));
				}
			}

			private void GiveBlueprint(int count, BasePlayer player)
			{
				for (var i = 0; i < count; i++) GiveBlueprint(player);
			}

			private void GiveBlueprint(BasePlayer player)
			{
				var bp = ItemManager.CreateByName("blueprintbase");
				if (bp == null)
				{
					_instance?.PrintError("Error creating blueprintbase");
					return;
				}

				bp.blueprintTarget = ItemManager.FindItemDefinition(ShortName).itemid;

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

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

			private void GiveItem(int amount, BasePlayer player)
			{
				var newItem = ItemManager.Create(ItemDefinition, amount, 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(int amount)
			{
				amount *= Amount;

				var maxStack = ItemDefinition.stackable;

				var list = new List<int>();

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

			public static ShopItem GetDefault(int id, double itemCost, string shortName)
			{
				return new ShopItem
				{
					Type = ItemType.Item,
					ID = id,
					Price = itemCost,
					SellPrice = itemCost,
					Image = string.Empty,
					Title = string.Empty,
					Command = string.Empty,
					Plugin = new PluginItem(),
					DisplayName = string.Empty,
					ShortName = shortName,
					Skin = 0,
					Blueprint = false,
					Amount = 1,
					Discount = new Dictionary<string, int>
					{
						["shop.default"] = 0,
						["shop.vip"] = 10
					},
					SellLimits = new Dictionary<string, int>
					{
						["shop.default"] = 0,
						["shop.vip"] = 0
					},
					BuyLimits = new Dictionary<string, int>
					{
						["shop.default"] = 0,
						["shop.vip"] = 0
					},
					DailyBuyLimits = new Dictionary<string, int>
					{
						["shop.default"] = 0,
						["shop.vip"] = 0
					},
					DailySellLimits = new Dictionary<string, int>
					{
						["shop.default"] = 0,
						["shop.vip"] = 0
					},
					BuyMaxAmount = 0,
					SellMaxAmount = 0,
					ForceBuy = false,
					ProhibitSplit = false
				};
			}
		}

		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":
							case "IQEconomic":
								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":
							case "IQEconomic":
								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());

			foreach (var cartData in _cartsNPC)
			{
				PlayerCart cart;
				if (!_data.PlayerCarts.TryGetValue(cartData.Key, out cart))
					_data.PlayerCarts.Add(cartData.Key, cart = new PlayerCart());

				foreach (var npcData in cartData.Value)
					cart.NPCCart[npcData.Key] = new NPCCart
					{
						Items = npcData.Value.GetPlayerCartItems()
					};
			}

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

			[JsonProperty(PropertyName = "NPC Carts", ObjectCreationHandling = ObjectCreationHandling.Replace)]
			public Dictionary<string, NPCCart> NPCCart = new Dictionary<string, NPCCart>();
		}

		private class NPCCart
		{
			[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) * x.Value);
			}

			public int GetTotalAmount()
			{
				return
					Items.Sum(check => check.Key.Type == ItemType.Item && check.Key.Definition != null
						? check.Key.ProhibitSplit
							? 1
							: check.Key.GetStacks(check.Value).Count
						: 0);
			}

			public void ClearItems()
			{
				Items.Clear();
			}

			#region Data

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

			public Dictionary<int, int> GetPlayerCartItems()
			{
				return 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);
			}

			public DataCart(Dictionary<int, int> items)
			{
				Items = items.ToDictionary(x => _instance.FindItemById(x.Key), y => y.Value);
			}

			#endregion
		}

		#endregion

		#region Hooks

		private void Init()
		{
			_instance = this;

			LoadData();

			LoadColors();

			RegisterPermissions();

			CheckOnDuplicates();

			LoadEconomics();
		}

		private void OnServerInitialized()
		{
			PrintWarning("\n-----------------------------\n" +
            "     Author - Sempai#3239\n" +
            "     VK - https://vk.com/rustnastroika/n" +
            "     Discord - https://discord.gg/5DPTsRmd3G/n"
			FillCategories();

			LoadItems();

			LoadNPCs();

			LoadImages();

			ItemsToDict();

			CacheImages();

			LoadCarts();

			LoadPlayers();

			LoadCustomVMs();

			RegisterCommands();

			CheckUpdateController();

			LoadCacheUI();
		}

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

				OnPlayerDisconnected(player);
			}

			SaveData();

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

			GetAvatar(player.userID,
				avatar => ImageLibrary?.Call("AddImage", avatar, $"avatar_{player.UserIDString}"));

			if (_config.LoginImages)
				_coroutines[player] = ServerMgr.Instance.StartCoroutine(LoadImages(player));
		}

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

			_itemsToUpdate.Remove(player);
			_openedShops.Remove(player);
			_openSHOP.Remove(player);

			CheckUpdateController();

			_itemEditing.Remove(player);

			Coroutine coroutine;
			if (_coroutines.TryGetValue(player, out coroutine) && 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, first: true);
		}

		private void OnNewSave()
		{
			if (_config.Wipe.Players)
				_data.PlayerCarts.Clear();

			if (_config.Wipe.Cooldown)
				_cooldown.Clear();

			if (_config.Wipe.Limits)
				_limits.Players.Clear();

			SaveData();
		}

		#region Image Library

		private void OnPluginLoaded(Plugin plugin)
		{
			if (plugin.Name == "ImageLibrary") _enabledImageLibrary = true;
		}

		private void OnPluginUnloaded(Plugin plugin)
		{
			if (plugin.Name == "ImageLibrary") _enabledImageLibrary = false;
		}

		#endregion

		#region Vending Machine

		private object CanLootEntity(BasePlayer player, VendingMachine vendingMachine)
		{
			if (player == null || vendingMachine == null)
				return null;

			CustomVendingConf customVendingConf;
			if (_config.CustomVending.TryGetValue(vendingMachine.net.ID, out customVendingConf))
			{
				_openedCustomVending[player] = customVendingConf;

				MainUi(player, first: true);
				return false;
			}

			return null;
		}

		#endregion

		#endregion

		#region Commands

		[ConsoleCommand("openshopUI")]
		private void OpenShopUI(ConsoleSystem.Arg arg)
		{
			var player = arg?.Player();
			if (player == null) return;

			if (_openedUI.Contains(player.userID))
			{
				CuiHelper.DestroyUi(player, Layer);
				_openedUI.Remove(player.userID);
			}
			else
			{
				MainUi(player, first: true);
				_openedUI.Add(player.userID);
			}
		}

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

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

			if (!player.HasPermission(PermSetVM))
			{
				SendNotify(player, NoPermission, 1);
				return;
			}

			if (args.Length == 0)
			{
				SendNotify(player, ErrorSyntax, 1, $"{command} [categories: cat1 cat2...]");
				return;
			}

			var categories = args.ToList();
			categories.RemoveAll(cat => !_config.Shop.Exists(confCat => confCat.Title == cat));
			if (categories.Count == 0)
			{
				SendNotify(player, VMNotFoundCategories, 1);
				return;
			}

			var workbench = GetLookVM(player);
			if (workbench == null)
			{
				SendNotify(player, VMNotFound, 1);
				return;
			}

			if (_config.CustomVending.ContainsKey(workbench.net.ID))
			{
				SendNotify(player, VMExists, 1);
				return;
			}

			var conf = new CustomVendingConf
			{
				Categories = categories
			};

			_config.CustomVending[workbench.net.ID] = conf;

			SaveConfig();

			SendNotify(player, VMInstalled, 0);

			Subscribe(nameof(CanLootEntity));
		}

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

			if (!player.HasPermission(PermSetNPC))
			{
				SendNotify(player, NoPermission, 1);
				return;
			}

			if (args.Length == 0)
			{
				SendNotify(player, ErrorSyntax, 1, $"{command} [categories: cat1 cat2...]");
				return;
			}

			var categories = args.ToList();
			categories.RemoveAll(cat => !_config.Shop.Exists(confCat => confCat.Title == cat));
			if (categories.Count == 0)
			{
				SendNotify(player, VMNotFoundCategories, 1);
				return;
			}

			var npc = GetLookNPC(player);
			if (npc == null)
			{
				SendNotify(player, NPCNotFound, 1);
				return;
			}

			if (_config.NPCs.ContainsKey(npc.UserIDString))
			{
				SendNotify(player, VMExists, 1);
				return;
			}

			var conf = new NPCShop
			{
				Shops = categories,
				BotID = npc.UserIDString
			};

			_config.NPCs[npc.UserIDString] = conf;

			SaveConfig();

			SendNotify(player, NPCInstalled, 0);
		}

		[ConsoleCommand("UI_Sho
// ... [Code preview truncated due to length. Full source in attached file] ...

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

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

Сверху