SHARE
TWEET

Untitled

a guest Feb 27th, 2020 117 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using Newtonsoft.Json;
  6. using Newtonsoft.Json.Linq;
  7. using Oxide.Core;
  8. using Oxide.Core.Configuration;
  9. using Oxide.Core.Libraries;
  10. using Oxide.Core.Plugins;
  11. using Oxide.Game.Rust.Cui;
  12. using UnityEngine;
  13. using WebSocketSharp;
  14.  
  15. namespace Oxide.Plugins
  16. {
  17.     [Info("GameStoresRUST", "HOUGAN & Sstine # GAMESTORES", "0.3.2")]
  18.     public class GameStoresRUST : RustPlugin
  19.     {
  20.         #region References
  21.  
  22.         [PluginReference] private Plugin ImageLibrary;
  23.  
  24.         #endregion
  25.  
  26.         #region Classes
  27.  
  28.         private static class Delays
  29.         {
  30.             [JsonProperty("Игроки с активными запросами к АПИ")]
  31.             public static List<ulong> ItemList = new List<ulong>();
  32.             [JsonProperty("Количество запросов за последнюю секунду")]
  33.             public static int RequestPerSecond = 0;
  34.             [JsonProperty("Ограничение запросов в секунду")]
  35.             public static int RequestPerSecondLimit = 20;
  36.  
  37.             public static bool CanRequest(BasePlayer player)
  38.             {
  39.                 if (RequestPerSecond > RequestPerSecondLimit)
  40.                 {
  41.                     return false;
  42.                 }
  43.  
  44.                 if (ItemList.Contains(player.userID))
  45.                 {
  46.                     player.ChatMessage($"Пожалуйста, дождитесь <<окончания>> предыдущего действия!");
  47.                     return false;
  48.                 }
  49.                 return true;
  50.             }
  51.  
  52.             public static void FinishRequest(BasePlayer player)
  53.             {
  54.                 if (ItemList.Contains(player.userID))
  55.                     ItemList.Remove(player.userID);
  56.             }
  57.  
  58.             public static IEnumerator MakeRequest(BasePlayer player)
  59.             {
  60.                 RequestPerSecond++;
  61.  
  62.                 if (ItemList.Contains(player.userID)) yield return null;
  63.                 ItemList.Add(player.userID);
  64.  
  65.                 yield return new WaitForSeconds(3f);
  66.                 if (ItemList.Contains(player.userID))
  67.                     ItemList.Remove(player.userID);
  68.             }
  69.         }
  70.  
  71.         private class Stats
  72.         {
  73.  
  74.         }
  75.  
  76.         private class Configuration
  77.         {
  78.             public class API
  79.             {
  80.                 [JsonProperty("ИД магазина в сервисе")]
  81.                 public string ShopID = "UNDEFINED";
  82.                 [JsonProperty("ИД сервера в сервисе")]
  83.                 public string ServerID = "UNDEFINED";
  84.                 [JsonProperty("Секретный ключ (не распространяйте его)")]
  85.                 public string SecretKey = "UNDEFINED";
  86.             }
  87.  
  88.             public class Interface
  89.             {
  90.                 [JsonProperty("Включить изображение корзины")]
  91.                 public bool BucketEnable = true;
  92.                 [JsonProperty("Включить отображение названий предметов")]
  93.                 public bool TextShow = true;
  94.                 [JsonProperty("Ссылка на изображение корзины (BUCKET - стандартное изображение)")]
  95.                 public string BucketURL = "BUCKET";
  96.                 [JsonProperty("Количество предметов на строке")]
  97.                 public int ItemOnString = 7;
  98.                 [JsonProperty("Количество строк в интерфейсе")]
  99.                 public int StringAmount = 3;
  100.                 [JsonProperty("Сторона одного предмета")]
  101.                 public int ItemSide = 150;
  102.                 [JsonProperty("Отступ между предметами")]
  103.                 public int ItemMargin = 5;
  104.             }
  105.  
  106.             public class TOP
  107.             {
  108.                 [JsonProperty("Отправлять данные топа игроков")]
  109.                 public bool UseTop = true;
  110.             }
  111.  
  112.             [JsonProperty("Настройки API плагина")]
  113.             public API APISettings = new API();
  114.             [JsonProperty("Настройки интерфейса плагина")]
  115.             public Interface InterfaceSettings = new Interface();
  116.             [JsonProperty("Настройки статистики сервера")]
  117.             public TOP TOPSettings = new TOP();
  118.         }
  119.  
  120.         private class WItem
  121.         {
  122.             public string ID;
  123.             public string Name;
  124.             public int ItemID;
  125.             public int Amount;
  126.             public string ShortName;
  127.             public string Command;
  128.             public string ImageUrl;
  129.  
  130.             public bool Blocked;
  131.             public double Block_Date = 0;
  132.             public bool IsBlueprint;
  133.             public bool IsCommand;
  134.             public bool IsItem;
  135.  
  136.             public WItem(Dictionary<string, object> data, bool show = true)
  137.             {
  138.                 try
  139.                 {
  140.                     if (data.ContainsKey("id")) ID = data["id"].ToString();
  141.  
  142.                     if (data.ContainsKey("name")) Name = data["name"].ToString();
  143.                     if (data.ContainsKey("item_id")) ItemID = System.Convert.ToInt32(data["item_id"]);
  144.                     if (data.ContainsKey("amount")) Amount = System.Convert.ToInt32(data["amount"]);
  145.                     if (data.ContainsKey("command")) Command = data["command"].ToString();
  146.                     if (data.ContainsKey("img")) ImageUrl = data["img"].ToString();
  147.  
  148.                     if (data.ContainsKey("blocked")) Blocked = bool.Parse(data["blocked"].ToString());
  149.  
  150.                     if (data.ContainsKey("block_date") && data["block_date"] is int)
  151.                     {
  152.                         double.TryParse(data["block_date"].ToString(), out Block_Date);
  153.                     }
  154.  
  155.                     if (data.ContainsKey("type"))
  156.                     {
  157.                         IsBlueprint = data["type"].ToString() == "bp";
  158.                         IsCommand = data["type"].ToString() == "command";
  159.                         IsItem = data["type"].ToString() == "item";
  160.                     }
  161.  
  162.                     if (ItemID != 0)
  163.                     {
  164.                         var itemInfo = ItemManager.FindItemDefinition(ItemID);
  165.                         if (itemInfo != null) ShortName = itemInfo.shortname;
  166.                         else if (IDToShortName.ContainsKey(ItemID))
  167.                         {
  168.                             itemInfo = ItemManager.FindItemDefinition(IDToShortName[ItemID]);
  169.                             if (itemInfo == null) return;
  170.  
  171.                             ShortName = itemInfo.shortname;
  172.                         }
  173.                     }
  174.  
  175.                     var imageLibrary = instance.plugins.Find("ImageLibrary");
  176.                     if (imageLibrary != null)
  177.                     {
  178.                         if (ItemID == 0)
  179.                         {
  180.                             if ((bool)imageLibrary.Call("HasImage", $"IconGS.{ID}"))
  181.                             {
  182.                                 string probablyId = (string)imageLibrary.Call("GetImage", $"IconGS.{ID}");
  183.                                 if (!probablyId.IsNullOrEmpty() && probablyId != instance.NoImageID && probablyId != instance.LoadingImageID)
  184.                                     ImageUrl = probablyId;
  185.                                 return;
  186.                             }
  187.  
  188.                             if (!ImageUrl.IsNullOrEmpty())
  189.                             {
  190.                                 imageLibrary.Call("AddImage", ImageUrl.Replace("https", "http"), $"IconGS.{ID}");
  191.                             }
  192.                         }
  193.                         else
  194.                         {
  195.                             string probablyId = (string)imageLibrary.Call("GetImage", ShortName);
  196.                             if (!probablyId.IsNullOrEmpty() && probablyId != instance.NoImageID && probablyId != instance.LoadingImageID)
  197.                                 ImageUrl = probablyId;
  198.                         }
  199.                     }
  200.                 }
  201.                 catch (NullReferenceException e)
  202.                 {
  203.                     Interface.Oxide.LogError(JsonConvert.SerializeObject(data));
  204.                 }
  205.             }
  206.         }
  207.  
  208.         #endregion
  209.  
  210.         #region Variables
  211.  
  212.         private static bool initialization = false;
  213.         private static bool Initialized = false;
  214.         private static GameStoresRUST instance;
  215.         private static Configuration Settings = new Configuration();
  216.         private string ShopURL = "UNDEFINED";
  217.         private int StartBalance = 0;
  218.         public string NoImageID = "";
  219.         public string LoadingImageID = "";
  220.         private Coroutine LoadingCoroutine;
  221.         private Dictionary<int, Dictionary<ulong, int>> ListTimeOutCommand = new Dictionary<int, Dictionary<ulong, int>>();
  222.         private Dictionary<ulong, List<int>> playersBasketCache = new Dictionary<ulong, List<int>>();
  223.         private HashSet<ulong> ListBannedCommandUserID = new HashSet<ulong>();
  224.         private string BaseRequest => $"https://gamestores.ru/api/?shop_id={Settings.APISettings.ShopID}&secret={Settings.APISettings.SecretKey}{(!Settings.APISettings.ServerID.IsNullOrEmpty() && Settings.APISettings.ServerID != "0" && Settings.APISettings.ServerID != "1" && Settings.APISettings.ServerID != "UNDEFINED" ? $"&server={Settings.APISettings.ServerID}" : "")}";
  225.         #endregion
  226.  
  227.         #region Interface
  228.  
  229.         private int TryImageCounter = 0;
  230.         private void OnServerInitialized()
  231.         {
  232.             if (!ImageLibrary)
  233.             {
  234.                 if (TryImageCounter < 3)
  235.                 {
  236.                     PrintError($"ImageLibrary is not initialized, try again in 1 sec.");
  237.                     TryImageCounter++;
  238.  
  239.                     timer.Once(1, OnServerInitialized);
  240.                     return;
  241.                 }
  242.                 else PrintWarning($"Starting without ImageLibrary");
  243.             }
  244.  
  245.             if (ImageLibrary)
  246.             {
  247.                 NoImageID = (string)ImageLibrary.Call("GetImage", "NONE");
  248.                 LoadingImageID = (string)ImageLibrary.Call("GetImage", "LOADING");
  249.             }
  250.  
  251.             if (Settings.InterfaceSettings.BucketURL.Contains("http") && plugins.Find("ImageLibrary") != null)
  252.             {
  253.                 ImageLibrary.Call("AddImage", Settings.InterfaceSettings.BucketURL, "GameStoresRUSTBucket");
  254.                 LoadingCoroutine = ServerMgr.Instance.StartCoroutine(WaitForLoad());
  255.             }
  256.             else
  257.             {
  258.                 //BasePlayer.activePlayerList.ForEach(OnPlayerInit);
  259.                 for (var i = 0; i < BasePlayer.activePlayerList.Count; i++)
  260.                 {
  261.                     OnPlayerInit(BasePlayer.activePlayerList[i]);
  262.                 }
  263.             }
  264.  
  265.             instance = this;
  266.             if (!Settings.TOPSettings.UseTop) Unsubscribe(nameof(OnEntityDeath));
  267.             if (!Settings.TOPSettings.UseTop) Unsubscribe(nameof(OnPlayerDisconnected));
  268.  
  269.             if (Settings.APISettings.ShopID == "UNDEFINED" || Settings.APISettings.SecretKey == "UNDEFINED")
  270.             {
  271.                 PrintError($"Verify that plugin is installed correct! Some of API settings are 'UNDEFINED'");
  272.                 return;
  273.             }
  274.  
  275.             FetchShopUrl();
  276.  
  277.             timer.Every(1, () => Delays.RequestPerSecond = 0);
  278.  
  279.             ListTimeOutCommand[0] = new Dictionary<ulong, int>();
  280.             ListTimeOutCommand[1] = new Dictionary<ulong, int>();
  281.             ListTimeOutCommand[2] = new Dictionary<ulong, int>();
  282.  
  283.             int totalTick = 0;
  284.             int tick = 0;
  285.             timer.Repeat(2, 0, () =>
  286.             {
  287.                 if (totalTick == 30)
  288.                 {
  289.                     totalTick = 0;
  290.                     ListBannedCommandUserID.Clear();
  291.                 }
  292.                 ListTimeOutCommand[0].Clear();
  293.                 if (tick == 3 || tick == 6)
  294.                 {
  295.                     ListTimeOutCommand[1].Clear();
  296.                 }
  297.  
  298.                 if (tick == 6)
  299.                 {
  300.                     tick = 0;
  301.                     ListTimeOutCommand[2].Clear();
  302.                 }
  303.                 tick++;
  304.                 totalTick++;
  305.             });
  306.         }
  307.  
  308.         private IEnumerator WaitForLoad()
  309.         {
  310.             while (!(bool)ImageLibrary.Call("HasImage", "GameStoresRUSTBucket"))
  311.             {
  312.                 PrintError($"Image of bucket is loading!");
  313.                 yield return new WaitForSeconds(1);
  314.             }
  315.  
  316.             PrintWarning("Image of bucket loaded correct!");
  317.             //BasePlayer.activePlayerList.ForEach(OnPlayerInit);
  318.             for (var i = 0; i < BasePlayer.activePlayerList.Count; i++)
  319.             {
  320.                 OnPlayerInit(BasePlayer.activePlayerList[i]);
  321.             }
  322.             yield return 0;
  323.         }
  324.  
  325.         protected override void LoadConfig()
  326.         {
  327.             base.LoadConfig();
  328.             try
  329.             {
  330.                 Settings = Config.ReadObject<Configuration>();
  331.                 if (Settings?.APISettings == null) LoadDefaultConfig();
  332.             }
  333.             catch
  334.             {
  335.                 PrintWarning($"Error reading config, creating one new config!");
  336.                 LoadDefaultConfig();
  337.             }
  338.  
  339.             NextTick(SaveConfig);
  340.         }
  341.  
  342.         protected override void LoadDefaultConfig()
  343.         {
  344.             Settings = new Configuration();
  345.         }
  346.  
  347.         protected override void SaveConfig() => Config.WriteObject(Settings);
  348.  
  349.         private void Unload()
  350.         {
  351.             //if (Initialized) StatHandler.SendStats();
  352.  
  353.             if (LoadingCoroutine != null) ServerMgr.Instance.StopCoroutine(LoadingCoroutine);
  354.             //BasePlayer.activePlayerList.ForEach(p => CuiHelper.DestroyUi(p, IconLayer));
  355.             //BasePlayer.activePlayerList.ForEach(p => CuiHelper.DestroyUi(p, StoreLayer));
  356.             foreach (var pl in BasePlayer.activePlayerList)
  357.             {
  358.                 CuiHelper.DestroyUi(pl, IconLayer);
  359.                 CuiHelper.DestroyUi(pl, StoreLayer);
  360.                 OnPlayerInit(pl);
  361.             }
  362.         }
  363.  
  364.         #endregion
  365.  
  366.         #region Hooks
  367.  
  368.         private void OnPlayerDisconnected(BasePlayer player, string reason)
  369.         {
  370.             StatHandler.AddStat(new StatHandler.TimeStat(player));
  371.         }
  372.  
  373.         private void OnPlayerInit(BasePlayer player)
  374.         {
  375.             if (player.IsReceivingSnapshot)
  376.             {
  377.                 NextTick(() => OnPlayerInit(player));
  378.                 return;
  379.             }
  380.  
  381.             if (Settings.InterfaceSettings.BucketEnable)
  382.                 InitializeIcon(player);
  383.         }
  384.  
  385.         #endregion
  386.  
  387.         #region Stats
  388.  
  389.         private static class StatHandler
  390.         {
  391.             internal class Stat
  392.             {
  393.                 [JsonProperty("dataType")]
  394.                 public string DataType;
  395.             }
  396.             internal class KillStat : Stat
  397.             {
  398.                 [JsonProperty("player_id")]
  399.                 public string PlayerUserId;
  400.                 [JsonProperty("victim_id")]
  401.                 public string VictimUserID;
  402.                 [JsonProperty("type")]
  403.                 public string Type;
  404.                 [JsonProperty("time")]
  405.                 public string Time;
  406.             }
  407.             internal class TimeStat : Stat
  408.             {
  409.                 [JsonProperty("player_id")]
  410.                 public string PlayerID;
  411.                 [JsonProperty("username")]
  412.                 public string PlayerName;
  413.                 [JsonProperty("played")]
  414.                 public string Played;
  415.                 [JsonProperty("time")]
  416.                 public string Time;
  417.  
  418.                 public TimeStat(BasePlayer player)
  419.                 {
  420.                     PlayerID = player.UserIDString;
  421.                     PlayerName = player.displayName;
  422.                     DataType = "leave";
  423.                     Played = player.secondsConnected.ToString();
  424.                     Time = CurrentTime().ToString();
  425.                 }
  426.             }
  427.  
  428.             private static List<Stat> Stats = new List<Stat>();
  429.             public static void AddStat(Stat stat)
  430.             {
  431.                 Stats.Add(stat);
  432.                 if (Stats.Count > 10)
  433.                 {
  434.                     SendStats();
  435.                     Stats.Clear();
  436.                 }
  437.             }
  438.  
  439.             public static void SendStats()
  440.             {
  441.                 try
  442.                 {
  443.  
  444.  
  445.                     if (!Initialized)
  446.                     {
  447.                         Interface.Oxide.LogInfo($"Sending stats error! Plugin not initialized");
  448.                         return;
  449.                     }
  450.                     if (Stats.Count == 0)
  451.                     {
  452.                         Interface.Oxide.LogInfo($"Nothing to send");
  453.                         return;
  454.                     }
  455.  
  456.                     var obj = JsonConvert.SerializeObject(Stats);
  457.                     RequestPost($"&method=topData&data={obj}", (i, s) => {
  458.                         if (i != 200)
  459.                             return;
  460.  
  461.                         Dictionary<string, object> response = JsonConvert.DeserializeObject<Dictionary<string, object>>(s, new KeyValuesConverter());
  462.                         if (response.ContainsKey("result") && response["result"].ToString() == "success")
  463.                         {
  464.                             Interface.Oxide.LogInfo($"GameStores sent stats successful!");
  465.                             Stats.Clear();
  466.                         }
  467.                         else
  468.                         {
  469.                             Interface.Oxide.LogInfo($"Sending stats error!");
  470.                         }
  471.                     });
  472.  
  473.  
  474.                 }
  475.                 catch
  476.                 {
  477.                     // ignored
  478.                 }
  479.             }
  480.         }
  481.  
  482.         [ConsoleCommand("sendtop")]
  483.         private void CmdSendTop(ConsoleSystem.Arg args)
  484.         {
  485.             if (args.Player() != null && !args.Player().IsAdmin) return;
  486.  
  487.             StatHandler.SendStats();
  488.         }
  489.  
  490.         private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
  491.         {
  492.             if (entity == null || info == null || info.Initiator == null)
  493.                 return;
  494.             if (Settings.TOPSettings.UseTop)
  495.             {
  496.                 BaseEntity initiator = info.Initiator;
  497.  
  498.                 if (entity as BasePlayer == null && initiator as BasePlayer == null)
  499.                     return;
  500.                 StatHandler.KillStat stat = new StatHandler.KillStat();
  501.  
  502.                 if (initiator as BasePlayer != null) stat.PlayerUserId = initiator.ToPlayer().UserIDString;
  503.                 else if (initiator.PrefabName.Contains("agents")) stat.PlayerUserId = "1";
  504.                 else return;
  505.  
  506.                 if (entity as BasePlayer != null)
  507.                 {
  508.                     stat.VictimUserID = entity.ToPlayer().UserIDString;
  509.                     stat.Type = entity.ToPlayer().IsSleeping() ? "sleeper" : "kill";
  510.                 }
  511.                 else if (entity.PrefabName.Contains("agents"))
  512.                 {
  513.                     stat.VictimUserID = "1";
  514.                     stat.Type = "kill";
  515.                 }
  516.                 else
  517.                 {
  518.                     return;
  519.                 }
  520.  
  521.                 stat.DataType = "death";
  522.  
  523.                 stat.Time = CurrentTime().ToString();
  524.                 StatHandler.AddStat(stat);
  525.             }
  526.         }
  527.  
  528.         #endregion
  529.  
  530.         #region Commands
  531.  
  532.         [ChatCommand("store")]
  533.         private void CmdChatStore(BasePlayer player, string command, string[] args)
  534.         {
  535.             if (!Initialized)
  536.             {
  537.  
  538.                 if (!initialization)
  539.                     FetchShopUrl();
  540.  
  541.                 player.ChatMessage($"Подождите, магазин загружается....");
  542.                 return;
  543.  
  544.             }
  545.  
  546.             if (args.Length == 1 && args[0].ToLower() == "hide")
  547.             {
  548.                 CuiHelper.DestroyUi(player, IconLayer);
  549.             }
  550.             else
  551.             {
  552.                 if (!Delays.CanRequest(player)) return;
  553.                 InitializeStore(player, 0, true);
  554.             }
  555.         }
  556.  
  557.         [ConsoleCommand("UI_GameStoresRUST")]
  558.         private void CmdConsoleCommand(ConsoleSystem.Arg args)
  559.         {
  560.             BasePlayer player = args.Player();
  561.             if (player == null) return;
  562.  
  563.             if (ListBannedCommandUserID.Contains(player.userID))
  564.             {
  565.                 player.ChatMessage("Вы сделали слишком много запросов. Отдохните немного, скоро возможность выполнять действие к вам вернется.");
  566.                 return;
  567.             }
  568.  
  569.             if (ListTimeOutCommand[0].ContainsKey(player.userID) == false)
  570.                 ListTimeOutCommand[0][player.userID] = 1;
  571.             else
  572.                 ListTimeOutCommand[0][player.userID] = ListTimeOutCommand[0][player.userID] + 1;
  573.  
  574.             if (ListTimeOutCommand[1].ContainsKey(player.userID) == false)
  575.                 ListTimeOutCommand[1][player.userID] = 1;
  576.             else
  577.                 ListTimeOutCommand[1][player.userID] = ListTimeOutCommand[1][player.userID] + 1;
  578.  
  579.             if (ListTimeOutCommand[2].ContainsKey(player.userID) == false)
  580.                 ListTimeOutCommand[2][player.userID] = 1;
  581.             else
  582.                 ListTimeOutCommand[2][player.userID] = ListTimeOutCommand[2][player.userID] + 1;
  583.  
  584.             if (ListTimeOutCommand[0][player.userID] >= 10 || ListTimeOutCommand[1][player.userID] >= 20 || ListTimeOutCommand[2][player.userID] >= 30)
  585.             {
  586.                 this.ListBannedCommandUserID.Add(player.userID);
  587.             }
  588.  
  589.             if (!args.HasArgs(1))
  590.             {
  591.                 player.SendConsoleCommand("chat.say /store");
  592.                 return;
  593.             }
  594.  
  595.             switch (args.Args[0].ToLower())
  596.             {
  597.                 case "page":
  598.                     {
  599.                         int page = 0;
  600.                         if (!args.HasArgs(2) || !int.TryParse(args.Args[1], out page)) return;
  601.                         InitializeStore(player, page, false);
  602.                         break;
  603.                     }
  604.                 case "help":
  605.                     {
  606.                         string helpLayer = StoreLayer + ".Help";
  607.                         CuiHelper.DestroyUi(player, helpLayer);
  608.                         CuiHelper.DestroyUi(player, StoreLayer);
  609.  
  610.                         CuiElementContainer container = new CuiElementContainer();
  611.                         container.Add(new CuiPanel
  612.                         {
  613.                             CursorEnabled = true,
  614.                             RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  615.                             Image = { Color = "0 0 0 0.9" },
  616.                         }, "Overlay", helpLayer);
  617.  
  618.                         container.Add(new CuiLabel
  619.                         {
  620.                             RectTransform = { AnchorMin = "0 0.6", AnchorMax = "1 0.78", OffsetMax = "0 0" },
  621.                             Text = { Text = "ИНСТРУКЦИЯ ПОЛЬЗОВАТЕЛЯ", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 34 }
  622.                         }, helpLayer);
  623.  
  624.                         container.Add(new CuiLabel
  625.                         {
  626.                             RectTransform = { AnchorMin = "0 0.3", AnchorMax = "1 0.72", OffsetMax = "0 0" },
  627.                             Text = { Text = $"Здесь вы можете забрать товары приобретенные у нас в магазине!\n" +
  628.                                                      $"Пополнить счёт можно различными способами: электронные кошельки, карты и т.д.\n" +
  629.                                                      $"Авторизация в магазине происходит при помощи вашего аккаунта STEAM",
  630.                                 Font = "robotocondensed-regular.ttf", FontSize = 22, Align = TextAnchor.MiddleCenter
  631.                         }
  632.                         }, helpLayer);
  633.  
  634.                         string addText = StartBalance > 0 ? $"\n<size=18>При первой авторизации вы получите в подарок <b>{StartBalance} рублей</b>!</size>" : "";
  635.                         container.Add(new CuiLabel
  636.                         {
  637.                             RectTransform = { AnchorMin = "0 0.1", AnchorMax = "1 0.48", OffsetMax = "0 0" },
  638.                             Text = { Text = $"" +
  639.                                                      $"{addText}\n{ShopURL.ToUpper()}", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 32}
  640.                         }, helpLayer);
  641.                         container.Add(new CuiButton
  642.                         {
  643.                             RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  644.                             Button = { Color = "0 0 0 0", Close = helpLayer, Command = "chat.say /store" },
  645.                             Text = { Text = "" }
  646.                         }, helpLayer);
  647.  
  648.                         CuiHelper.AddUi(player, container);
  649.                         break;
  650.                     }
  651.                 case "take":
  652.                     {
  653.                        
  654.                         if (!args.HasArgs(3)) return;
  655.  
  656.                         int index = 0, id = 0;
  657.                         if (!int.TryParse(args.Args[1], out index) || !int.TryParse(args.Args[2], out id)) return;
  658.  
  659.                         if (!playersBasketCache.ContainsKey(player.userID))
  660.                         {
  661.                             player.ChatMessage("Предмет не найден, попробуйте перезапустить корзину");
  662.                             return;
  663.                         } else if (!playersBasketCache[player.userID].Contains(id))
  664.                         {
  665.                             player.ChatMessage("Предмет не найден, попробуйте перезапустить корзину");
  666.                             return;
  667.                         }
  668.                                            
  669.                         if (args.HasArgs(5) && args.Args[3].ToLower() == "blocked")
  670.                         {
  671.                             double left = 0;
  672.                             if (!double.TryParse(args.Args[4], out left)) return;
  673.  
  674.                             TimeSpan span = TimeSpan.FromSeconds(left);
  675.  
  676.                             string text = "";
  677.                             if (span.Days >= 1)
  678.                                 text += $"{span.Days} дн. ";
  679.                             if (span.Hours >= 1)
  680.                                 text += $"{span.Hours} ч. ";
  681.                             if (span.Minutes >= 1)
  682.                                 text += $"{span.Minutes} мин. ";
  683.                             if (span.Seconds >= 1)
  684.                                 text += $"{span.Seconds} сек.";
  685.  
  686.                             ShowNotify(player, "Вы не можете забрать этот предмет из корзины!\n" +
  687.                                                $"До его разблокировки осталось: {text}");
  688.                             return;
  689.                         }
  690.  
  691.                         ShowNotify(player, "Подождите, ваш запрос обрабатывается!");
  692.                         CuiElementContainer container = new CuiElementContainer();
  693.  
  694.                         if (!Delays.CanRequest(player))
  695.                         {
  696.                             ShowNotify(player, "Подождите, ваш предыдущий запрос ещё обрабатывается!");
  697.                             container.Add(new CuiButton
  698.                             {
  699.                                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  700.                                 Button = { Color = "1 1 1 0.2", Close = StoreLayer + ".BlockPanel." + index + ".Open", Command = $"UI_GameStoresRUST take {index} {id}" },
  701.                                 Text = { Text = "ПОДОЖДИТЕ", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", Color = "1 1 1 0.4", FontSize = 24 }
  702.                             }, StoreLayer + ".BlockPanel." + index, StoreLayer + ".BlockPanel." + index + ".Open");
  703.  
  704.                             CuiHelper.AddUi(player, container);
  705.                             return;
  706.                         }
  707.  
  708.                         container.Add(new CuiButton
  709.                         {
  710.                             RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  711.                             Button = { FadeIn = 1f, Color = "1 1 1 0.2", Close = StoreLayer + ".BlockPanel." + index + ".Open", Command = $"UI_GameStoresRUST take {index} {id}", Material = "" },
  712.                             Text = { Text = "ПОДОЖДИТЕ", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", Color = "1 1 1 0.4", FontSize = 24 }
  713.                         }, StoreLayer + ".BlockPanel." + index, StoreLayer + ".BlockPanel." + index + ".Open");
  714.                         CuiHelper.AddUi(player, container);
  715.  
  716.                         LogPlayerAction(player, $"---------------------------------");
  717.                         LogPlayerAction(player, $"Запрос на получение предмета: {id}");
  718.                         Request($"&item=true&steam_id={player.UserIDString}&id={id}", (i, s) =>
  719.                         {
  720.                             switch (i)
  721.                             {
  722.                                 case 0:
  723.                                     LogPlayerAction(player, $"API не ответило на запрос: {id}");
  724.                                     PrintError("Api does not responded to a request");
  725.                                     if (player != null)
  726.                                     {
  727.                                         player.ChatMessage($"Непредвиденная ошибка со стороны сервера, просим прощения!");
  728.                                         CuiHelper.DestroyUi(player, StoreLayer);
  729.                                     }
  730.                                     break;
  731.                                 case 200:
  732.                                     Dictionary<string, object> response = JsonConvert.DeserializeObject<Dictionary<string, object>>(s, new KeyValuesConverter());
  733.                                     if (!response.ContainsKey("data"))
  734.                                     {
  735.                                         LogPlayerAction(player, $"Ошибка получения товара, отсутствует Data [{id}]");
  736.  
  737.                                         container.Clear();
  738.                                         CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel." + index + ".Open");
  739.                                         container.Add(new CuiButton
  740.                                         {
  741.                                             RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  742.                                             Button = { FadeIn = 1f, Color = "1 0.5 0.5 0.2", Close = StoreLayer + ".BlockPanel." + index + ".Open", Command = $"UI_GameStoresRUST take {index} {id}", Material = "" },
  743.                                             Text = { Text = "ОШИБКА\nПОЛУЧЕНИЯ", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", Color = "1 0.7 0.7 1", FontSize = 24 }
  744.                                         }, StoreLayer + ".BlockPanel." + index, StoreLayer + ".BlockPanel." + index + ".Open");
  745.                                         ShowNotify(player, "Произошла непредвиденная ошибка, попробуйте позже!\n" +
  746.                                                            "Ваш предмет в безопасности, не переживайте!");
  747.                                         CuiHelper.AddUi(player, container);
  748.                                         return;
  749.                                     }
  750.  
  751.                                     LogPlayerAction(player, $"Товар отмечен полученным [{id}]");
  752.                                     Request($"&gived=true&id={id}", (code, newResponse) =>
  753.                                     {
  754.                                         if (code != 200 || JsonConvert.DeserializeObject<JObject>(newResponse)["result"].ToString() != "success")
  755.                                         {
  756.                                             container.Clear();
  757.                                             CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel." + index + ".Open");
  758.                                             container.Add(new CuiButton
  759.                                             {
  760.                                                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  761.                                                 Button = { FadeIn = 1f, Color = "1 0.5 0.5 0.2", Close = StoreLayer + ".BlockPanel." + index + ".Open", Command = $"UI_GameStoresRUST take {index} {id}", Material = "" },
  762.                                                 Text = { Text = "ОШИБКА\nПОЛУЧЕНИЯ", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", Color = "1 0.7 0.7 1", FontSize = 24 }
  763.                                             }, StoreLayer + ".BlockPanel." + index, StoreLayer + ".BlockPanel." + index + ".Open");
  764.                                             ShowNotify(player, "Произошла непредвиденная ошибка, попробуйте позже!\n" +
  765.                                                                "Ваш предмет в безопасности, не переживайте!");
  766.                                             CuiHelper.AddUi(player, container);
  767.                                             return;
  768.                                         }
  769.                                         ProcessTake(player, response["data"] as Dictionary<string, object>);
  770.                                     }, player);
  771.  
  772.                                     container.Clear();
  773.                                     CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel." + index + ".Open");
  774.                                     container.Add(new CuiButton
  775.                                     {
  776.                                         RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  777.                                         Button = { FadeIn = 1f, Color = "0.5 1 0.5 0.2", Material = "" },
  778.                                         Text = { Text = "УСПЕШНО\nПОЛУЧЕНО", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", Color = "0.7 1 0.7 1", FontSize = 24 }
  779.                                     }, StoreLayer + ".BlockPanel." + index, StoreLayer + ".BlockPanel." + index + ".Open");
  780.  
  781.                                     if (playersBasketCache.ContainsKey(player.userID) && playersBasketCache[player.userID].Contains(id))
  782.                                         playersBasketCache[player.userID].RemoveAt(playersBasketCache[player.userID].IndexOf(id));
  783.  
  784.                                     CuiHelper.AddUi(player, container);
  785.                                     break;
  786.                                 case 404:
  787.                                     LogPlayerAction(player, $"Сайт не ответило на запрос: {id}");
  788.                                     player.ChatMessage($"Непредвиденная ошибка со стороны сервера, просим прощения!");
  789.                                     CuiHelper.DestroyUi(player, StoreLayer);
  790.                                     Debug.LogError("Response code: 404, please check your configurations");
  791.                                     break;
  792.                             }
  793.                         }, player);
  794.                         break;
  795.                     }
  796.             }
  797.         }
  798.  
  799.         #endregion
  800.  
  801.         #region Interface
  802.  
  803.         private static string StoreLayer = "UI_GameStoresRUST_Store";
  804.         private void InitializeStore(BasePlayer player, int page, bool first = true)
  805.         {
  806.             CuiElementContainer container = new CuiElementContainer();
  807.  
  808.             if (first)
  809.             {
  810.                 CuiHelper.DestroyUi(player, StoreLayer);
  811.                 container.Add(new CuiPanel
  812.                 {
  813.                     CursorEnabled = true,
  814.                     RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  815.                     Image = { Color = "0 0 0 0.8" },
  816.                 }, "Overlay", StoreLayer);
  817.  
  818.                 container.Add(new CuiButton
  819.                 {
  820.                     RectTransform = { AnchorMin = "0.3 0.9", AnchorMax = "0.7 1", OffsetMax = "0 0" },
  821.                     Button = { Color = "0 0 0 0" },
  822.                     Text = { Text = "КОРЗИНА СЕРВЕРА", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 32, Color = "1 1 1 0.6" }
  823.                 }, StoreLayer, StoreLayer + ".ITT");
  824.  
  825.                 container.Add(new CuiButton
  826.                 {
  827.                     RectTransform = { AnchorMin = "0.8 0.9", AnchorMax = "0.935 1", OffsetMax = "0 0" },
  828.                     Button = { Color = "0 0 0 0", Close = StoreLayer, Command = "closemenu" },
  829.                     Text = { Text = "ВЫХОД", Align = TextAnchor.MiddleRight, Font = "robotocondensed-regular.ttf", FontSize = 28 }
  830.                 }, StoreLayer);
  831.                 container.Add(new CuiLabel
  832.                 {
  833.                     RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0", OffsetMin = "0 -0", OffsetMax = "0 20" },
  834.                     Text = { Text = "Это ваша корзина с покупками, вы можете забрать их в любой момент", Align = TextAnchor.UpperCenter, Font = "robotocondensed-regular.ttf", Color = "1 1 1 0.4" }
  835.                 }, StoreLayer + ".ITT");
  836.  
  837.                 container.Add(new CuiButton
  838.                 {
  839.                     RectTransform = { AnchorMin = "0.065 0.9", AnchorMax = "0.2 1", OffsetMax = "0 0" },
  840.                     Button = { Color = "0 0 0 0", Command = "UI_GameStoresRUST help" },
  841.                     Text = { Text = "ПОМОЩЬ", Align = TextAnchor.MiddleLeft, Font = "robotocondensed-regular.ttf", FontSize = 28 }
  842.                 }, StoreLayer);
  843.             }
  844.  
  845.             CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel");
  846.             container.Add(new CuiPanel
  847.             {
  848.                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.9", OffsetMax = "0 0" },
  849.                 Image = { Color = "0 0 0 0" }
  850.             }, StoreLayer, StoreLayer + ".BlockPanel");
  851.  
  852.             container.Add(new CuiLabel
  853.             {
  854.                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1.1", OffsetMax = "0 0" },
  855.                 Text = { Text = "Подождите, мы обрабатываем ваш запрос...", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 34 }
  856.             }, StoreLayer + ".BlockPanel", StoreLayer + ".BlockPanel.Text");
  857.  
  858.             CuiHelper.AddUi(player, container);
  859.  
  860.             Request($"&method=basket&steam_id={player.UserIDString}", (code, response) =>
  861.             {
  862.                 switch (code)
  863.                 {
  864.                     case 0:
  865.                         {
  866.                             CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel.Text");
  867.                             CuiElementContainer secondContainer = new CuiElementContainer();
  868.                             secondContainer.Add(new CuiLabel
  869.                             {
  870.                                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  871.                                 Text = { Text = "Непредвиденная ошибка, попробуйте позже!", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 38 }
  872.                             }, StoreLayer + ".BlockPanel", StoreLayer + ".BlockPanel.Text");
  873.                             CuiHelper.AddUi(player, secondContainer);
  874.                             break;
  875.                         }
  876.                     case 200:
  877.                         {
  878.                             var firstInfo = JsonConvert.DeserializeObject<Dictionary<string, object>>(response, new KeyValuesConverter());
  879.                             if (firstInfo.ContainsKey("result"))
  880.                             {
  881.                                 if (firstInfo["result"].ToString() == "fail")
  882.                                 {
  883.                                     if (firstInfo["code"].ToString() == "104")
  884.                                     {
  885.                                         CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel.Text");
  886.                                         CuiElementContainer secondContainer = new CuiElementContainer();
  887.                                         secondContainer.Add(new CuiLabel
  888.                                         {
  889.                                             RectTransform = { AnchorMin = "0 0.1", AnchorMax = "1 1", OffsetMax = "0 0" },
  890.                                             Text = { Text = "Ваша корзина пуста", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 34 }
  891.                                         }, StoreLayer + ".BlockPanel", StoreLayer + ".BlockPanel.Text");
  892.                                         CuiHelper.AddUi(player, secondContainer);
  893.                                     }
  894.                                     if (firstInfo["code"].ToString() == "105")
  895.                                     {
  896.                                         CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel.Text");
  897.                                         CuiElementContainer secondContainer = new CuiElementContainer();
  898.                                         secondContainer.Add(new CuiLabel
  899.                                         {
  900.                                             RectTransform = { AnchorMin = "0 0.1", AnchorMax = "1 1", OffsetMax = "0 0" },
  901.                                             Text = { Text = "Вы не авторизованы в магазине!\n" +
  902.                                                         "Ссылку на авторизацию вы можете найти в разделе 'помощь'", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 34 }
  903.                                         }, StoreLayer + ".BlockPanel", StoreLayer + ".BlockPanel.Text");
  904.                                         CuiHelper.AddUi(player, secondContainer);
  905.                                     }
  906.                                 }
  907.                                 else
  908.                                 {
  909.                                     CuiElementContainer secondContainer = new CuiElementContainer();
  910.  
  911.                                     if (!(firstInfo["data"] is List<object>))
  912.                                     {
  913.                                         PrintError("Unkown error #1");
  914.                                         CuiHelper.DestroyUi(player, StoreLayer);
  915.                                         return;
  916.                                     }
  917.                                     List<object> data = firstInfo["data"] as List<object>;
  918.                                     List<WItem> wItems = new List<WItem>();
  919.  
  920.                                     foreach (var check in data.Skip(page * 21).Take(21))
  921.                                     {
  922.                                         wItems.Add(new WItem(check as Dictionary<string, object>));
  923.  
  924.                                     }
  925.                                     if (playersBasketCache.ContainsKey(player.userID))
  926.                                         playersBasketCache[player.userID].Clear();
  927.  
  928.                                     foreach (Dictionary<string, object> product in data)
  929.                                     {
  930.                                         if (product.ContainsKey("id"))
  931.                                         {
  932.                                             if (!playersBasketCache.ContainsKey(player.userID))
  933.                                                 playersBasketCache.Add(player.userID, new List<int>());
  934.  
  935.                                             playersBasketCache[player.userID].Add(Convert.ToInt32(product["id"]));
  936.                                         }
  937.                                            
  938.                                     }
  939.                                     secondContainer.Add(new CuiLabel
  940.                                     {
  941.                                         RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0.14", OffsetMax = "0 0" },
  942.                                         Text = { Text = (page + 1).ToString(), Align = TextAnchor.MiddleCenter, FontSize = 34 }
  943.                                     }, StoreLayer + ".BlockPanel");
  944.  
  945.                                     secondContainer.Add(new CuiButton
  946.                                     {
  947.                                         RectTransform = { AnchorMin = "0.4 0.14", AnchorMax = "0.4 0.14", OffsetMin = "-40 -125", OffsetMax = "125 40" },
  948.                                         Button = { Color = "0 0 0 0", Material = "", Command = page > 0 ? $"UI_GameStoresRUST page {page - 1}" : "" },
  949.                                         Text = { Text = "<", Color = page > 0 ? "1 1 1 1" : "1 1 1 0.2", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 80 }
  950.                                     }, StoreLayer + ".BlockPanel");
  951.  
  952.                                     secondContainer.Add(new CuiButton
  953.                                     {
  954.                                         RectTransform = { AnchorMin = "0.6 0.14", AnchorMax = "0.6 0.14", OffsetMin = "-125 -125", OffsetMax = "40 40" },
  955.                                         Button = { Color = "0 0 0 0", Material = "", Command = (page + 1) * 21 < data.Count ? $"UI_GameStoresRUST page {page + 1}" : "" },
  956.                                         Text = { Text = ">", Color = (page + 1) * 21 < data.Count ? "1 1 1 1" : "1 1 1 0.2", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 80 }
  957.                                     }, StoreLayer + ".BlockPanel");
  958.  
  959.  
  960.                                     double xSwitch = 0;
  961.                                     double ySwitch = 0;
  962.                                     for (int i = 0; i < Settings.InterfaceSettings.ItemOnString * Settings.InterfaceSettings.StringAmount; i++)
  963.                                     {
  964.                                         UI_RecountPosition(ref xSwitch, ref ySwitch, i, Settings.InterfaceSettings.ItemOnString * Settings.InterfaceSettings.StringAmount);
  965.  
  966.                                         secondContainer.Add(new CuiButton
  967.                                         {
  968.                                             RectTransform = { AnchorMin = "0.495 0.55", AnchorMax = "0.495 0.55", OffsetMin = $"{xSwitch} {ySwitch - Settings.InterfaceSettings.ItemSide}", OffsetMax = $"{xSwitch + Settings.InterfaceSettings.ItemSide} {ySwitch}" },
  969.                                             Button = { Color = "1 1 1 0.2", Command = $"" },
  970.                                             Text = { Text = "" }
  971.                                         }, StoreLayer + ".BlockPanel", StoreLayer + $".BlockPanel.{i}");
  972.                                     }
  973.  
  974.                                     /*if (player.IsAdmin)
  975.                                     {
  976.                                         LogToFile("Test", "123 - " + JsonConvert.SerializeObject(wItems), this);  
  977.                                     } */
  978.                                     foreach (var check in wItems.Select((i, t) => new { A = i, B = t }))
  979.                                     {
  980.                                         if (check.A.IsBlueprint)
  981.                                         {
  982.                                             if (plugins.Find("ImageLibrary") != null)
  983.                                             {
  984.                                                 secondContainer.Add(new CuiElement
  985.                                                 {
  986.                                                     Parent = StoreLayer + ".BlockPanel." + check.B,
  987.                                                     Components =
  988.                                                 {
  989.                                                     new CuiRawImageComponent { Png = (string) plugins.Find("ImageLibrary").Call("GetImage", "blueprintbase") },
  990.                                                     new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5" },
  991.                                                 }
  992.                                                 });
  993.                                             }
  994.                                             else
  995.                                             {
  996.                                                 secondContainer.Add(new CuiElement
  997.                                                 {
  998.                                                     Parent = StoreLayer + ".BlockPanel." + check.B,
  999.                                                     Components =
  1000.                                                 {
  1001.                                                     new CuiRawImageComponent { Url = "https://gamestores.ru/img/games/rust/blueprintbase.png" },
  1002.                                                     new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5" },
  1003.                                                 }
  1004.                                                 });
  1005.                                             }
  1006.                                         }
  1007.                                         if (!check.A.ImageUrl.Contains("http"))
  1008.                                         {
  1009.                                             secondContainer.Add(new CuiElement
  1010.                                             {
  1011.                                                 Parent = StoreLayer + ".BlockPanel." + check.B,
  1012.                                                 Components =
  1013.                                             {
  1014.                                                 new CuiRawImageComponent { Png = check.A.ImageUrl },
  1015.                                                 new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5" },
  1016.                                             }
  1017.                                             });
  1018.                                         }
  1019.                                         else
  1020.                                         {
  1021.                                             secondContainer.Add(new CuiElement
  1022.                                             {
  1023.                                                 Parent = StoreLayer + ".BlockPanel." + check.B,
  1024.                                                 Components =
  1025.                                             {
  1026.                                                 new CuiRawImageComponent { Url = check.A.ImageUrl },
  1027.                                                 new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5" },
  1028.                                             }
  1029.                                             });
  1030.                                         }
  1031.  
  1032.                                         if (check.A.Amount > 1)
  1033.                                         {
  1034.                                             secondContainer.Add(new CuiLabel
  1035.                                             {
  1036.                                                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 5", OffsetMax = "-5 0" },
  1037.                                                 Text = { Text = "x" + check.A.Amount, Align = TextAnchor.LowerRight, Font = "robotocondensed-regular.ttf", FontSize = 24 }
  1038.                                             }, StoreLayer + ".BlockPanel." + check.B);
  1039.                                         }
  1040.  
  1041.                                         if (check.A.Blocked)
  1042.                                         {
  1043.                                             double left = check.A.Block_Date - CurrentTime();
  1044.  
  1045.                                             secondContainer.Add(new CuiButton
  1046.                                             {
  1047.                                                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  1048.                                                 Button = { Color = "1 0.5 0.5 0.2", Command = $"UI_GameStoresRUST take {check.B} {check.A.ID} blocked {left}" },
  1049.                                                 Text = { Text = "", Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 38 }
  1050.                                             }, StoreLayer + ".BlockPanel." + check.B, StoreLayer + ".BlockPanel." + check.B + ".Open");
  1051.                                         }
  1052.                                         else
  1053.                                         {
  1054.                                             secondContainer.Add(new CuiButton
  1055.                                             {
  1056.                                                 RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  1057.                                                 Button = { Color = "0 0 0 0", Close = StoreLayer + ".BlockPanel." + check.B + ".Open", Command = $"UI_GameStoresRUST take {check.B} {check.A.ID}" },
  1058.                                                 Text = { Text = "" }
  1059.                                             }, StoreLayer + ".BlockPanel." + check.B, StoreLayer + ".BlockPanel." + check.B + ".Open");
  1060.                                         }
  1061.  
  1062.                                         secondContainer.Add(new CuiLabel
  1063.                                         {
  1064.                                             RectTransform = { AnchorMin = "0 0", AnchorMax = "1 0", OffsetMin = "0 -22.5", OffsetMax = "0 0" },
  1065.                                             Text = { Text = check.A.Name, Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 16, Color = "1 1 1 0.8" }
  1066.                                         }, StoreLayer + ".BlockPanel." + check.B);
  1067.                                     }
  1068.  
  1069.                                     CuiHelper.AddUi(player, secondContainer);
  1070.                                     CuiHelper.DestroyUi(player, StoreLayer + ".BlockPanel.Text");
  1071.                                 }
  1072.                             }
  1073.                             break;
  1074.                         }
  1075.                 }
  1076.             }, player);
  1077.         }
  1078.  
  1079.         private string IconLayer = "UI_GameStoresRUST_Bucket";
  1080.         private void InitializeIcon(BasePlayer player)
  1081.         {
  1082.             CuiHelper.DestroyUi(player, IconLayer);
  1083.             CuiElementContainer container = new CuiElementContainer();
  1084.             if (Settings.InterfaceSettings.BucketURL.Contains("http"))
  1085.             {
  1086.                 if (ImageLibrary)
  1087.                 {
  1088.                     container.Add(new CuiElement
  1089.                     {
  1090.                         Parent = "Overlay",
  1091.                         Name = IconLayer,
  1092.                         Components =
  1093.                         {
  1094.                             new CuiRawImageComponent { Png = (string) ImageLibrary.Call("GetImage", "GameStoresRUSTBucket") },
  1095.                             new CuiRectTransformComponent { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "8 -40", OffsetMax = "43 -6" }
  1096.                         }
  1097.                     });
  1098.  
  1099.                     container.Add(new CuiButton
  1100.                     {
  1101.                         RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  1102.                         Button = { Color = "0 0 0 0", Command = "chat.say /store" },
  1103.                         Text = { Text = "" }
  1104.                     }, IconLayer);
  1105.                 }
  1106.                 else
  1107.                 {
  1108.                     container.Add(new CuiElement
  1109.                     {
  1110.                         Parent = "Overlay",
  1111.                         Name = IconLayer,
  1112.                         Components =
  1113.                         {
  1114.                             new CuiRawImageComponent { Url = Settings.InterfaceSettings.BucketURL },
  1115.                             new CuiRectTransformComponent { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "8 -40", OffsetMax = "43 -6" }
  1116.                         }
  1117.                     });
  1118.  
  1119.                     container.Add(new CuiButton
  1120.                     {
  1121.                         RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0" },
  1122.                         Button = { Color = "0 0 0 0", Command = "chat.say /store" },
  1123.                         Text = { Text = "" }
  1124.                     }, IconLayer);
  1125.                 }
  1126.             }
  1127.             else
  1128.             {
  1129.                 container.Add(new CuiButton
  1130.                 {
  1131.                     RectTransform = { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "8 -40", OffsetMax = "43 -6" },
  1132.                     Button = { Color = "1 1 1 0.6", Sprite = "assets/icons/open.png", Command = "chat.say /store" },
  1133.                     Text = { Text = "" }
  1134.                 }, "Overlay", IconLayer);
  1135.             }
  1136.  
  1137.             CuiHelper.AddUi(player, container);
  1138.         }
  1139.  
  1140.         #endregion
  1141.  
  1142.         #region Utils
  1143.  
  1144.         private void ShowNotify(BasePlayer player, string text)
  1145.         {
  1146.             CuiHelper.DestroyUi(player, StoreLayer + ".Notify");
  1147.             CuiElementContainer container = new CuiElementContainer();
  1148.  
  1149.             container.Add(new CuiLabel
  1150.             {
  1151.                 RectTransform = { AnchorMin = "0 0.80", AnchorMax = "1 0.90", OffsetMax = "0 0" },
  1152.                 Text = { FadeIn = 1f, Text = text, Align = TextAnchor.UpperCenter, Font = "robotocondensed-regular.ttf", FontSize = 16 }
  1153.             }, StoreLayer, StoreLayer + ".Notify");
  1154.  
  1155.             CuiHelper.AddUi(player, container);
  1156.         }
  1157.  
  1158.         private void ProcessTake(BasePlayer player, Dictionary<string, object> obj)
  1159.         {
  1160.             //foreach (var check in obj)
  1161.             //   PrintError(check.Key + " -> " + check.Value);
  1162.             LogPlayerAction(player, $"Начало обработки товара");
  1163.             WItem itemInfo = new WItem(obj);
  1164.             if (itemInfo.IsItem)
  1165.             {
  1166.                 LogPlayerAction(player, $"Попытка получения предмета: {itemInfo.ShortName} [{itemInfo.Amount}]");
  1167.                 var info = ItemManager.FindItemDefinition(itemInfo.ShortName);
  1168.                 if (info == null) return;
  1169.  
  1170.                 var item = ItemManager.Create(info, itemInfo.Amount);
  1171.                 if (!player.inventory.GiveItem(item))
  1172.                 {
  1173.                     LogPlayerAction(player, $"У игрока не было места для получения предмета, предмет выброшен {itemInfo.ShortName} [{itemInfo.Amount} {player.transform.position}]");
  1174.  
  1175.                     item.Drop(player.transform.position, Vector3.down * 3);
  1176.                     ShowNotify(player, $"Вы успешно получили предмет  › <size=20>{info.displayName.english}</size> ‹\n" +
  1177.                                        $"У вас недостаточно места в инвентаре, <b>предмет брошен</b> под ноги!");
  1178.                 }
  1179.                 else
  1180.                 {
  1181.                     LogPlayerAction(player, $"Предмет выдан игроку в инвентарь");
  1182.                     ShowNotify(player, $"Вы успешно получили предмет  › <size=20>{info.displayName.english}</size> ‹");
  1183.                 }
  1184.             }
  1185.  
  1186.             if (itemInfo.IsCommand)
  1187.             {
  1188.                 LogPlayerAction(player, $"Попытка получения команды");
  1189.  
  1190.                 string command = itemInfo.Command.Replace("\n", "|").Replace("%steamid%", player.UserIDString, StringComparison.OrdinalIgnoreCase).Replace("%username%", player.displayName, StringComparison.OrdinalIgnoreCase);
  1191.                 foreach (var check in command.Split('|'))
  1192.                 {
  1193.                     LogPlayerAction(player, $"Исполнение команды: {check}");
  1194.                     Server.Command(check);
  1195.                 }
  1196.  
  1197.  
  1198.                 ShowNotify(player, $"Вы успешно получили предмет  › <size=20>{itemInfo.Name}</size> ‹\n" +
  1199.                                    $"Теперь вам доступны новые привилегии!");
  1200.             }
  1201.  
  1202.             if (itemInfo.IsBlueprint)
  1203.             {
  1204.                 LogPlayerAction(player, $"Попытка получения рецепта {itemInfo.ShortName}");
  1205.                 Item create = ItemManager.CreateByItemID(-996920608);
  1206.  
  1207.                 var info = ItemManager.FindItemDefinition(itemInfo.ShortName);
  1208.                 create.blueprintTarget = info.itemid;
  1209.  
  1210.                 if (!player.inventory.GiveItem(create))
  1211.                 {
  1212.                     create.Drop(player.transform.position, Vector3.down * 3);
  1213.                     ShowNotify(player, $"Вы успешно получили рецепт предмета  › <size=20>{info.displayName.english}</size> ‹\n" +
  1214.                                        $"У вас недостаточно места в инвентаре, <b>предмет брошен</b> под ноги!");
  1215.                 }
  1216.                 else
  1217.                 {
  1218.                     LogPlayerAction(player, $"У игрока не было места для получения рецепта, рецепт выброшен {itemInfo.ShortName} [{itemInfo.Amount} {player.transform.position}]");
  1219.  
  1220.                     LogPlayerAction(player, $"Рецепт выдан игроку в инвентарь");
  1221.                     ShowNotify(player, $"Вы успешно получили рецепт предмета  › <size=20>{info.displayName.english}</size> ‹");
  1222.                 }
  1223.             }
  1224.         }
  1225.  
  1226.         private static readonly Dictionary<int, string> IDToShortName = new Dictionary<int, string> { [-1461508848] = "rifle.ak", [2115555558] = "ammo.handmade.shell", [-533875561] = "ammo.pistol", [1621541165] = "ammo.pistol.fire", [-422893115] = "ammo.pistol.hv", [815896488] = "ammo.rifle", [805088543] = "ammo.rifle.explosive", [449771810] = "ammo.rifle.incendiary", [1152393492] = "ammo.rifle.hv", [1578894260] = "ammo.rocket.basic", [1436532208] = "ammo.rocket.fire", [542276424] = "ammo.rocket.hv", [1594947829] = "ammo.rocket.smoke", [-1035059994] = "ammo.shotgun", [1818890814] = "ammo.shotgun.fire", [1819281075] = "ammo.shotgun.slug", [1685058759] = "antiradpills", [93029210] = "apple", [-1565095136] = "apple.spoiled", [-1775362679] = "arrow.bone", [-1775249157] = "arrow.fire", [-1280058093] = "arrow.hv", [-420273765] = "arrow.wooden", [563023711] = "autoturret", [790921853] = "axe.salvaged", [-337261910] = "bandage", [498312426] = "barricade.concrete", [504904386] = "barricade.metal", [-1221200300] = "barricade.sandbags", [510887968] = "barricade.stone", [-814689390] = "barricade.wood", [1024486167] = "barricade.woodwire", [2021568998] = "battery.small", [97329] = "bbq", [1046072789] = "trap.bear", [97409] = "bed", [-1480119738] = "tool.binoculars", [1611480185] = "black.raspberries", [-1386464949] = "bleach", [93832698] = "blood", [-1063412582] = "blueberries", [-1887162396] = "blueprintbase", [-55660037] = "rifle.bolt", [919780768] = "bone.club", [-365801095] = "bone.fragments", [68998734] = "botabag", [-853695669] = "bow.hunting", [271534758] = "box.wooden.large", [-770311783] = "box.wooden", [-1192532973] = "bucket.water", [-307490664] = "building.planner", [707427396] = "burlap.shirt", [707432758] = "burlap.shoes", [-2079677721] = "cactusflesh", [-1342405573] = "tool.camera", [-139769801] = "campfire", [-1043746011] = "can.beans", [2080339268] = "can.beans.empty", [-171664558] = "can.tuna", [1050986417] = "can.tuna.empty", [-1693683664] = "candycaneclub", [523409530] = "candycane", [1300054961] = "cctv.camera", [-2095387015] = "ceilinglight", [1428021640] = "chainsaw", [94623429] = "chair", [1436001773] = "charcoal", [1711323399] = "chicken.burned", [1734319168] = "chicken.cooked", [-1658459025] = "chicken.raw", [-726947205] = "chicken.spoiled", [-341443994] = "chocholate", [1540879296] = "xmasdoorwreath", [94756378] = "cloth", [3059095] = "coal", [3059624] = "corn", [2045107609] = "clone.corn", [583366917] = "seed.corn", [2123300234] = "crossbow", [1983936587] = "crude.oil", [1257201758] = "cupboard.tool", [-1144743963] = "diving.fins", [-1144542967] = "diving.mask", [-1144334585] = "diving.tank", [1066729526] = "diving.wetsuit", [-1598790097] = "door.double.hinged.metal", [-933236257] = "door.double.hinged.toptier", [-1575287163] = "door.double.hinged.wood", [-2104481870] = "door.hinged.metal", [-1571725662] = "door.hinged.toptier", [1456441506] = "door.hinged.wood", [1200628767] = "door.key", [-778796102] = "door.closer", [1526866730] = "xmas.door.garland", [1925723260] = "dropbox", [1891056868] = "ducttape", [1295154089] = "explosive.satchel", [498591726] = "explosive.timed", [1755466030] = "explosives", [726730162] = "facialhair.style01", [-1034048911] = "fat.animal", [252529905] = "femalearmpithair.style01", [471582113] = "femaleeyebrow.style01", [-1138648591] = "femalepubichair.style01", [305916740] = "female_hairstyle_01", [305916742] = "female_hairstyle_03", [305916744] = "female_hairstyle_05", [1908328648] = "fireplace.stone", [-2078972355] = "fish.cooked", [-533484654] = "fish.raw", [1571660245] = "fishingrod.handmade", [1045869440] = "flamethrower", [1985408483] = "flameturret", [97513422] = "flare", [1496470781] = "flashlight.held", [1229879204] = "weapon.mod.flashlight", [-1722829188] = "floor.grill", [1849912854] = "floor.ladder.hatch", [-1266285051] = "fridge", [-1749787215] = "boots.frog", [28178745] = "lowgradefuel", [-505639592] = "furnace", [1598149413] = "furnace.large", [-1779401418] = "gates.external.high.stone", [-57285700] = "gates.external.high.wood", [98228420] = "gears", [1422845239] = "geiger.counter", [277631078] = "generator.wind.scrap", [115739308] = "burlap.gloves", [-522149009] = "gloweyes", [3175989] = "glue", [718197703] = "granolabar", [384204160] = "grenade.beancan", [-1308622549] = "grenade.f1", [-217113639] = "fun.guitar", [-1580059655] = "gunpowder", [-1832205789] = "male_hairstyle_01", [305916741] = "female_hairstyle_02", [936777834] = "attire.hide.helterneck", [-1224598842] = "hammer", [-1976561211] = "hammer.salvaged", [-1406876421] = "hat.beenie", [-1397343301] = "hat.boonie", [1260209393] = "bucket.helmet", [-1035315940] = "burlap.headwrap", [-1381682752] = "hat.candle", [696727039] = "hat.cap", [-2128719593] = "coffeecan.helmet", [-1178289187] = "deer.skull.mask", [1351172108] = "heavy.plate.helmet", [-450738836] = "hat.miner", [-966287254] = "attire.reindeer.headband", [340009023] = "riot.helmet", [124310981] = "hat.wolf", [1501403549] = "wood.armor.helmet", [698310895] = "hatchet", [523855532] = "hazmatsuit", [2045246801] = "clone.hemp", [583506109] = "seed.hemp", [-148163128] = "attire.hide.boots", [-132588262] = "attire.hide.skirt", [-1666761111] = "attire.hide.vest", [-465236267] = "weapon.mod.holosight", [-1211618504] = "hoodie", [2133577942] = "hq.metal.ore", [-1014825244] = "humanmeat.burned", [-991829475] = "humanmeat.cooked", [-642008142] = "humanmeat.raw", [661790782] = "humanmeat.spoiled", [-1440143841] = "icepick.salvaged", [569119686] = "bone.armor.suit", [1404466285] = "heavy.plate.jacket", [-1616887133] = "jacket.snow", [-1167640370] = "jacket", [-1284735799] = "jackolantern.angry", [-1278649848] = "jackolantern.happy", [776005741] = "knife.bone", [108061910] = "ladder.wooden.wall", [255101535] = "trap.landmine", [-51678842] = "lantern", [-789202811] = "largemedkit", [516382256] = "weapon.mod.lasersight", [50834473] = "leather", [-975723312] = "lock.code", [1908195100] = "lock.key", [-1097452776] = "locker", [146685185] = "longsword", [-1716193401] = "rifle.lr300", [193190034] = "lmg.m249", [371156815] = "pistol.m92", [3343606] = "mace", [825308669] = "machete", [830965940] = "mailbox", [1662628660] = "male.facialhair.style02", [1662628661] = "male.facialhair.style03", [1662628662] = "male.facialhair.style04", [-1832205788] = "male_hairstyle_02", [-1832205786] = "male_hairstyle_04", [1625090418] = "malearmpithair.style01", [-1269800768] = "maleeyebrow.style01", [429648208] = "malepubichair.style01", [-1832205787] = "male_hairstyle_03", [-1832205785] = "male_hairstyle_05", [107868] = "map", [997973965] = "mask.balaclava", [-46188931] = "mask.bandana", [-46848560] = "metal.facemask", [-2066726403] = "bearmeat.burned", [-2043730634] = "bearmeat.cooked", [1325935999] = "bearmeat", [-225234813] = "deermeat.burned", [-202239044] = "deermeat.cooked", [-322501005] = "deermeat.raw", [-1851058636] = "horsemeat.burned", [-1828062867] = "horsemeat.cooked", [-1966381470] = "horsemeat.raw", [968732481] = "meat.pork.burned", [991728250] = "meat.pork.cooked", [-253819519] = "meat.boar", [-1714986849] = "wolfmeat.burned", [-1691991080] = "wolfmeat.cooked", [179448791] = "wolfmeat.raw", [431617507] = "wolfmeat.spoiled", [688032252] = "metal.fragments", [-1059362949] = "metal.ore", [1265861812] = "metal.plate.torso", [374890416] = "metal.refined", [1567404401] = "metalblade", [-1057402571] = "metalpipe", [-758925787] = "mining.pumpjack", [-1411620422] = "mining.quarry", [88869913] = "fish.minnows", [-2094080303] = "smg.mp5", [843418712] = "mushroom", [-1569356508] = "weapon.mod.muzzleboost", [-1569280852] = "weapon.mod.muzzlebrake", [449769971] = "pistol.nailgun", [590532217] = "ammo.nailgun.nails", [3387378] = "note", [1767561705] = "burlap.trousers", [106433500] = "pants", [-1334615971] = "heavy.plate.pants", [-135651869] = "attire.hide.pants", [-1595790889] = "roadsign.kilt", [-459156023] = "pants.shorts", [106434956] = "paper", [-578028723] = "pickaxe", [-586116979] = "jar.pickle", [-1379225193] = "pistol.eoka", [-930579334] = "pistol.revolver", [548699316] = "pistol.semiauto", [142147109] = "planter.large", [148953073] = "planter.small", [102672084] = "attire.hide.poncho", [640562379] = "pookie.bear", [-1732316031] = "xmas.present.large", [-2130280721] = "xmas.present.medium", [-1725510067] = "xmas.present.small", [1974032895] = "propanetank", [-225085592] = "pumpkin", [509654999] = "clone.pumpkin", [466113771] = "seed.pumpkin", [2033918259] = "pistol.python", [2069925558] = "target.reactive", [-1026117678] = "box.repair.bench", [1987447227] = "research.table", [540154065] = "researchpaper", [1939428458] = "riflebody", [-288010497] = "roadsign.jacket", [-847065290] = "roadsigns", [3506021] = "rock", [649603450] = "rocket.launcher", [3506418] = "rope", [569935070] = "rug.bear", [113284] = "rug", [1916127949] = "water.salt", [-1775234707] = "salvaged.cleaver", [-388967316] = "salvaged.sword", [2007564590] = "santahat", [-1705696613] = "scarecrow", [670655301] = "hazmatsuit_scientist", [1148128486] = "hazmatsuit_scientist_peacekeeper", [-141135377] = "weapon.mod.small.scope", [109266897] = "scrap", [-527558546] = "searchlight", [-1745053053] = "rifle.semiauto", [1223860752] = "semibody", [-419069863] = "sewingkit", [-1617374968] = "sheetmetal", [2057749608] = "shelves", [24576628] = "shirt.collared", [-1659202509] = "shirt.tanktop", [2107229499] = "shoes.boots", [191795897] = "shotgun.double", [-1009492144] = "shotgun.pump", [2077983581] = "shotgun.waterpipe", [378365037] = "guntrap", [-529054135] = "shutter.metal.embrasure.a", [-529054134] = "shutter.metal.embrasure.b", [486166145] = "shutter.wood.a", [1628490888] = "sign.hanging.banner.large", [1498516223] = "sign.hanging", [-632459882] = "sign.hanging.ornate", [-626812403] = "sign.pictureframe.landscape", [385802761] = "sign.pictureframe.portrait", [2117976603] = "sign.pictureframe.tall", [1338515426] = "sign.pictureframe.xl", [-1455694274] = "sign.pictureframe.xxl", [1579245182] = "sign.pole.banner.large", [-587434450] = "sign.post.double", [-163742043] = "sign.post.single", [-1224714193] = "sign.post.town", [644359987] = "sign.post.town.roof", [-1962514734] = "sign.wooden.huge", [-705305612] = "sign.wooden.large", [-357728804] = "sign.wooden.medium", [-698499648] = "sign.wooden.small", [1213686767] = "weapon.mod.silencer", [386382445] = "weapon.mod.simplesight", [1859976884] = "skull_fire_pit", [960793436] = "skull.human", [1001265731] = "skull.wolf", [1253290621] = "sleepingbag", [470729623] = "small.oil.refinery", [1051155022] = "stash.small", [865679437] = "fish.troutsmall", [927253046] = "smallwaterbottle", [109552593] = "smg.2", [-2092529553] = "smgbody", [691633666] = "snowball", [-2055888649] = "snowman", [621575320] = "shotgun.spas12", [-2118132208] = "spear.stone", [-1127699509] = "spear.wooden", [-685265909] = "spikes.floor", [552706886] = "spinner.wheel", [1835797460] = "metalspring", [-892259869] = "sticks", [-1623330855] = "stocking.large", [-1616524891] = "stocking.small", [789892804] = "stone.pickaxe", [-1289478934] = "stonehatchet", [-892070738] = "stones", [-891243783] = "sulfur", [889398893] = "sulfur.ore", [-1625468793] = "supply.signal", [1293049486] = "surveycharge", [1369769822] = "fishtrap.small", [586484018] = "syringe.medical", [110115790] = "table", [1490499512] = "targeting.computer", [3552619] = "tarp", [1471284746] = "techparts", [456448245] = "smg.thompson", [110547964] = "torch", [1588977225] = "xmas.decoration.baubels", [918540912] = "xmas.decoration.candycanes", [-471874147] = "xmas.decoration.gingerbreadmen", [205978836] = "xmas.decoration.lights", [-1044400758] = "xmas.decoration.pinecone", [-2073307447] = "xmas.decoration.star", [435230680] = "xmas.decoration.tinsel", [-864578046] = "tshirt", [1660607208] = "tshirt.long", [260214178] = "tunalight", [-1847536522] = "vending.machine", [-496055048] = "wall.external.high.stone", [-1792066367] = "wall.external.high", [562888306] = "wall.frame.cell.gate", [-427925529] = "wall.frame.cell", [995306285] = "wall.frame.fence.gate", [-378017204] = "wall.frame.fence", [447918618] = "wall.frame.garagedoor", [313836902] = "wall.frame.netting", [1175970190] = "wall.frame.shopfront", [525244071] = "wall.frame.shopfront.metal", [-1021702157] = "wall.window.bars.metal", [-402507101] = "wall.window.bars.toptier", [-1556671423] = "wall.window.bars.wood", [61936445] = "wall.window.glass.reinforced", [112903447] = "water", [1817873886] = "water.catcher.large", [1824679850] = "water.catcher.small", [-1628526499] = "water.barrel", [547302405] = "waterjug", [1840561315] = "water.purifier", [-460592212] = "xmas.window.garland", [3655341] = "wood", [1554697726] = "wood.armor.jacket", [-1883959124] = "wood.armor.pants", [-481416622] = "workbench1", [-481416621] = "workbench2", [-481416620] = "workbench3", [-1151126752] = "xmas.lightstring", [-1926458555] = "xmas.tree" };
  1227.  
  1228.         private void UI_RecountPosition(ref double xSwitch, ref double ySwitch, int count, int max)
  1229.         {
  1230.             var stringAmount = Math.Ceiling((double)max / Settings.InterfaceSettings.ItemOnString);
  1231.             var currentString = Math.Floor((double)count / Settings.InterfaceSettings.ItemOnString);
  1232.             var currentPosition = count % Settings.InterfaceSettings.ItemOnString;
  1233.  
  1234.  
  1235.             var topYPosition = 0 + (float)stringAmount / 2 * Settings.InterfaceSettings.ItemSide + ((float)stringAmount / 2 - 1) * Settings.InterfaceSettings.ItemMargin;
  1236.             var topXPosition = 0 - (float)Settings.InterfaceSettings.ItemOnString / 2 * Settings.InterfaceSettings.ItemSide - ((float)Settings.InterfaceSettings.ItemOnString / 2 - 1) * Settings.InterfaceSettings.ItemMargin;
  1237.  
  1238.             var curYPosition = topYPosition - currentString * Settings.InterfaceSettings.ItemSide - (currentString) * (Settings.InterfaceSettings.ItemMargin + (Settings.InterfaceSettings.TextShow ? 20 : 0));
  1239.             var curXPosition = topXPosition + currentPosition * Settings.InterfaceSettings.ItemSide + (currentPosition) * Settings.InterfaceSettings.ItemMargin;
  1240.  
  1241.             xSwitch = curXPosition;
  1242.             ySwitch = curYPosition;
  1243.         }
  1244.  
  1245.         private void FetchShopUrl()
  1246.         {
  1247.             initialization = true;
  1248.             Request($"&info=true", (code, response) =>
  1249.             {
  1250.                 PrintWarning($"-----------------------------");
  1251.                 PrintWarning($" GameStores {Version} (c) 2019");
  1252.                 try
  1253.                 {
  1254.                     if (response.Length < 1)
  1255.                     {
  1256.                         LogToFile("Errors", $"{DateTime.Now.ToShortTimeString()}| Response: '{response}'", this);
  1257.                         PrintError(" Incorrect API response! Saved to log!");
  1258.                         PrintWarning($"-----------------------------");
  1259.                         initialization = false;
  1260.                         return;
  1261.                     }
  1262.                     var firstInfo = JsonConvert.DeserializeObject<Dictionary<string, object>>(response, new KeyValuesConverter());
  1263.                     if (!firstInfo.ContainsKey("data"))
  1264.                     {
  1265.                         PrintError($"     Wrong Secret Key");
  1266.                         PrintWarning($"-----------------------------");
  1267.                         initialization = false;
  1268.                     }
  1269.                     else
  1270.                     {
  1271.                         firstInfo = firstInfo["data"] as Dictionary<string, object>;
  1272.                         ShopURL = firstInfo["link"].ToString();
  1273.                         StartBalance = int.Parse(firstInfo["default_balance"].ToString());
  1274.                         PrintWarning("      Initialized - OK");
  1275.                         PrintWarning($"-----------------------------");
  1276.                         //BasePlayer.activePlayerList.ForEach(OnPlayerInit);
  1277.                         foreach (var pl in BasePlayer.activePlayerList)
  1278.                         {
  1279.                             OnPlayerInit(pl);
  1280.                         }
  1281.  
  1282.                         Initialized = true;
  1283.                         initialization = false;
  1284.                     }
  1285.                 }
  1286.                 catch (JsonException e)
  1287.                 {
  1288.                     LogToFile("Errors", $"{DateTime.Now.ToShortTimeString()}| JsonError | Response: '{response}'", this);
  1289.                     PrintError(" JSON Error! Saved to log!");
  1290.                     PrintWarning($"-----------------------------");
  1291.                     initialization = false;
  1292.                 }
  1293.  
  1294.             });
  1295.         }
  1296.  
  1297.         private static void Request(string ask, Action<int, string> callback, BasePlayer player = null, bool cancel = true)
  1298.         {
  1299.             if (player != null && !Delays.CanRequest(player))
  1300.             {
  1301.                 instance.ShowNotify(player, "Вы делаете слишком много запросов к серверу!\n" +
  1302.                     "Подождите <b>одну секунду</b>!");
  1303.                 instance.timer.Once(1f, () =>
  1304.                 {
  1305.                     CuiHelper.DestroyUi(player, StoreLayer + ".Notify");
  1306.                     Request(ask, callback, player, cancel);
  1307.                 });
  1308.                 return;
  1309.             };
  1310.             if (player != null) ServerMgr.Instance.StartCoroutine(Delays.MakeRequest(player));
  1311.  
  1312.             instance.webrequest.Enqueue(instance.BaseRequest + ask, "", (code, response) =>
  1313.             {
  1314.                 if (instance == null) return;
  1315.  
  1316.                 switch (code)
  1317.                 {
  1318.                     case 0:
  1319.                         {
  1320.                             instance.PrintError($"Time out waiting for GS API #1");
  1321.                             break;
  1322.                         }
  1323.                     case 404:
  1324.                         {
  1325.                             instance.PrintError($"Plese check your configuration! [404] #2");
  1326.                             break;
  1327.                         }
  1328.                 }
  1329.                 if (player != null && cancel) Delays.FinishRequest(player);
  1330.  
  1331.                 callback?.Invoke(code, response);
  1332.             }, instance, RequestMethod.GET);
  1333.         }
  1334.  
  1335.         private static void RequestPost(string ask, Action<int, string> callback, BasePlayer player = null, bool cancel = true)
  1336.         {
  1337.             if (player != null && !Delays.CanRequest(player))
  1338.             {
  1339.                 instance.ShowNotify(player, "Вы делаете слишком много запросов к серверу!\n" +
  1340.                     "Подождите <b>одну секунду</b>!");
  1341.                 instance.timer.Once(1f, () =>
  1342.                 {
  1343.                     CuiHelper.DestroyUi(player, StoreLayer + ".Notify");
  1344.                     RequestPost(ask, callback, player, cancel);
  1345.                 });
  1346.                 return;
  1347.             };
  1348.             if (player != null) ServerMgr.Instance.StartCoroutine(Delays.MakeRequest(player));
  1349.             string body, reqLink;
  1350.             int pos = instance.BaseRequest.IndexOf("?");
  1351.             if (pos < 0)
  1352.             {
  1353.                 body = ask;
  1354.                 reqLink = instance.BaseRequest;
  1355.             }
  1356.             else
  1357.             {
  1358.                 reqLink = instance.BaseRequest.Substring(0, pos);
  1359.                 body = $"{instance.BaseRequest.Substring(pos + 1)}{ask}";
  1360.             }
  1361.  
  1362.             instance.webrequest.Enqueue(reqLink, body, (code, response) =>
  1363.             {
  1364.                 if (instance == null) return;
  1365.  
  1366.                 switch (code)
  1367.                 {
  1368.                     case 0:
  1369.                         {
  1370.                             instance.PrintError($"Time out waiting for GS API #1");
  1371.                             break;
  1372.                         }
  1373.                     case 404:
  1374.                         {
  1375.                             instance.PrintError($"Plese check your configuration! [404] #2");
  1376.                             break;
  1377.                         }
  1378.                 }
  1379.                 if (player != null && cancel) Delays.FinishRequest(player);
  1380.  
  1381.                 callback?.Invoke(code, response);
  1382.             }, instance, RequestMethod.POST);
  1383.         }
  1384.  
  1385.         private void LogPlayerAction(BasePlayer player, string text) => LogToFile($"{player.userID}", $"{DateTime.Now.ToShortTimeString()} {text}", this);
  1386.         private static double CurrentTime() => DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
  1387.  
  1388.         #endregion
  1389.     }
  1390. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top