C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// #define TESTING
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Steamworks;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
#if CARBON
using Carbon.Base;
using Carbon.Modules;
#endif
namespace Oxide.Plugins
{
[Info("GameStoresRUST", "Forum: https://topplugin.ru Ds: alone_sempai Vk: https://vk.com/rustnastroika", "1.0.5")]
public class GameStoresRUST : RustPlugin
{
#region Fields
[PluginReference] private Plugin
GameStoresWipeBlock = null,
ImageLibrary = null,
NoEscape = null;
private static GameStoresRUST Instance;
#if CARBON
private ImageDatabaseModule imageDatabase = BaseModule.GetModule<ImageDatabaseModule>();
#endif
private bool initialization, Initialized, maintenance;
private string ShopURL = "UNDEFINED";
private int StartBalance;
private Dictionary<int, Dictionary<ulong, int>> ListTimeOutCommand = new();
private HashSet<ulong> ListBannedCommandUserID = new();
private Dictionary<ulong, PlayerBasket> _playerBaskets = new();
private Timer _checkInstant;
#region Images
private string NoImageID = string.Empty, LoadingImageID = string.Empty;
private const string ImageBucket = "GameStoresRUSTBucket";
private Coroutine _loadingCoroutine;
#endregion
#region Web Requests
private readonly List<Coroutine> _activeCoroutines = new();
private readonly List<UnityWebRequest> _activeRequests = new();
private bool SecureConnection = true;
private Dictionary<string, string> reqHeaders = new()
{
["User-Agent"] = "GameStores Plugin"
};
private const string
MainApiLink = "https://apip.gamestores.app/v1/",
CFApiLink = "https://ac.gamestores.app/v1/",
PayApiLink = "https://pay.gamestores.app/api/";
private string BestApiLink = string.Empty;
private int errorsReq;
private const int MaxErrorsReq = 5;
#endregion Web Requests
#endregion
#region Config
private Configuration _config;
private class Configuration
{
public class APIConfiguration
{
[JsonProperty("Store ID")] public string ShopID = "UNDEFINED";
[JsonProperty("Server ID")] public string ServerID = "UNDEFINED";
[JsonProperty("Secret key (don't spread it)")]
public string SecretKey = "UNDEFINED";
}
public class InterfaceConfiguration
{
[JsonProperty("Enable cart image")] public bool BucketEnable = true;
[JsonProperty("Enable display of item names")]
public bool TextShow = true;
[JsonProperty("Link to cart image (BUCKET - default image)")]
public string BucketURL = "BUCKET";
[JsonProperty("Number of items per line")]
public int ItemOnString = 7;
[JsonProperty("Number of lines in the interface")]
public int StringAmount = 3;
[JsonProperty("Side of one item")] public int ItemSide = 150;
[JsonProperty("Space between objects")]
public int ItemMargin = 5;
[JsonProperty("Position settings cart image")]
public InterfacePosition BucketPosition = new()
{
AnchorMin = "0 1",
AnchorMax = "0 1",
OffsetMin = "8 -40",
OffsetMax = "43 -6"
};
[JsonProperty("Background settings")] public BackgroundSettings Background = new()
{
AnchorMin = "0 0",
AnchorMax = "1 1",
OffsetMin = "0 0",
OffsetMax = "0 0",
Material = "assets/content/ui/uibackgroundblur.mat",
Sprite = string.Empty,
Image = string.Empty,
Color = IColor.Create("#000000", 80),
DisplayType = "Overlay"
};
[JsonProperty("Basket title settings")]
public ButtonSettings BasketTitle = new()
{
AnchorMin = "0.3 0.9",
AnchorMax = "0.7 1",
OffsetMin = "0 0",
OffsetMax = "0 0",
FontSize = 32,
IsBold = false,
Align = TextAnchor.MiddleCenter,
Color = IColor.Create("#FFFFFF", 60),
ButtonColor = IColor.Create("#000000", 0),
Sprite = string.Empty,
Material = string.Empty,
Image = string.Empty,
ImageColor = IColor.Create("#FFFFFF")
};
[JsonProperty("Basket description settings")]
public TextSettings BasketDescription = new()
{
AnchorMin = "0 0",
AnchorMax = "1 0",
OffsetMin = "0 -0",
OffsetMax = "0 20",
FontSize = 14,
IsBold = false,
Align = TextAnchor.UpperCenter,
Color = IColor.Create("#FFFFFF", 40)
};
[JsonProperty("Help button settings")] public ButtonSettings HelpButton = new()
{
AnchorMin = "0.065 0.9",
AnchorMax = "0.2 1",
OffsetMin = "0 0",
OffsetMax = "0 0",
FontSize = 28,
IsBold = false,
Align = TextAnchor.MiddleLeft,
Color = IColor.Create("#FFFFFF"),
ButtonColor = IColor.Create("#000000", 0),
Sprite = string.Empty,
Material = string.Empty,
Image = string.Empty,
ImageColor = IColor.Create("#FFFFFF")
};
[JsonProperty(PropertyName = "Block panel settings")]
public ImageSettings BlockPanel = new()
{
AnchorMin = "0 0",
AnchorMax = "1 0.9",
OffsetMin = "0 0",
OffsetMax = "0 0",
Color = IColor.Create("#000000", 0),
Sprite = string.Empty,
Material = string.Empty,
Image = string.Empty
};
[JsonProperty(PropertyName = "Request processing title settings")]
public TextSettings RequestProcessingTitle = new()
{
AnchorMin = "0 0",
AnchorMax = "1 1.1",
OffsetMin = "0 0",
OffsetMax = "0 0",
Align = TextAnchor.MiddleCenter,
Color = IColor.Create("#FFFFFF"),
IsBold = false,
FontSize = 34
};
[JsonProperty(PropertyName = "Store exit button settings")]
public ButtonSettings StoreExitButton = new()
{
AnchorMin = "0.8 0.9", AnchorMax = "0.935 1", OffsetMin = "0 0", OffsetMax = "0 0",
ButtonColor = IColor.Create("#000000", 0),
Material = string.Empty,
Image = string.Empty,
Sprite = string.Empty,
Color = IColor.Create("#FFFFFF"),
Align = TextAnchor.MiddleRight,
FontSize = 28,
IsBold = false,
ImageColor = IColor.Create("#FFFFFF")
};
[JsonProperty(PropertyName = "Item background color")]
public IColor ItemBackgroundColor = IColor.Create("#FFFFFF", 20);
#region UI.Components
public class BackgroundSettings : ImageSettings
{
[JsonProperty(PropertyName = "Display type (Overlay/Hud)")]
public string DisplayType;
public CuiElement Get(string name, string destroyUI, bool needCursor)
{
var image = GetImage(DisplayType, name, destroyUI);
if (needCursor)
image.Components.Add(new CuiNeedsCursorComponent());
return image;
}
}
public class ImageSettings : InterfacePosition
{
[JsonProperty(PropertyName = "Sprite")]
public string Sprite;
[JsonProperty(PropertyName = "Material")]
public string Material;
[JsonProperty(PropertyName = "Image")] public string Image;
[JsonProperty(PropertyName = "Color")] public IColor Color;
private ICuiComponent GetImage()
{
if (!string.IsNullOrEmpty(Image))
{
var rawImage = new CuiRawImageComponent
{
Png = Instance?.GetImage(Image),
Color = Color.Get
};
if (!string.IsNullOrEmpty(Sprite))
rawImage.Sprite = Sprite;
if (!string.IsNullOrEmpty(Material))
rawImage.Material = Material;
return rawImage;
}
var image = new CuiImageComponent
{
Color = Color.Get
};
if (!string.IsNullOrEmpty(Sprite))
image.Sprite = Sprite;
if (!string.IsNullOrEmpty(Material))
image.Material = Material;
return image;
}
public CuiElement GetImage(string parent,
string name = null,
string destroyUI = null)
{
if (string.IsNullOrEmpty(name))
name = CuiHelper.GetGuid();
return new CuiElement
{
Name = name,
Parent = parent,
DestroyUi = destroyUI,
Components =
{
GetImage(),
GetPosition()
}
};
}
}
public class ButtonSettings : TextSettings
{
[JsonProperty(PropertyName = "Button Color")]
public IColor ButtonColor;
[JsonProperty(PropertyName = "Sprite")]
public string Sprite;
[JsonProperty(PropertyName = "Material")]
public string Material;
[JsonProperty(PropertyName = "Image")] public string Image;
[JsonProperty(PropertyName = "Image Color")]
public IColor ImageColor;
public List<CuiElement> Get(
string msg,
string cmd,
string parent,
string name = null,
string destroyUI = null,
string close = null)
{
if (string.IsNullOrEmpty(name))
name = CuiHelper.GetGuid();
var list = new List<CuiElement>();
var btn = new CuiButtonComponent
{
Color = ButtonColor.Get
};
if (!string.IsNullOrEmpty(cmd))
btn.Command = cmd;
if (!string.IsNullOrEmpty(close))
btn.Close = close;
if (!string.IsNullOrEmpty(Sprite))
btn.Sprite = Sprite;
if (!string.IsNullOrEmpty(Material))
btn.Material = Material;
if (!string.IsNullOrEmpty(Image))
{
list.Add(new CuiElement
{
Name = name,
Parent = parent,
DestroyUi = destroyUI,
Components =
{
new CuiRawImageComponent
{
Png = Instance?.GetImage(Image),
Color = ImageColor.Get
},
GetPosition()
}
});
list.Add(new CuiElement
{
Parent = name,
Components =
{
btn,
new CuiRectTransformComponent()
}
});
}
else
{
list.Add(new CuiElement
{
Name = name,
Parent = parent,
DestroyUi = destroyUI,
Components =
{
btn,
GetPosition()
}
});
}
if (!string.IsNullOrEmpty(msg))
list.Add(new CuiElement
{
Parent = name,
Components =
{
GetTextComponent(msg),
new CuiRectTransformComponent()
}
});
return list;
}
}
public class TextSettings : InterfacePosition
{
[JsonProperty(PropertyName = "Font Size")]
public int FontSize;
[JsonProperty(PropertyName = "Is Bold?")]
public bool IsBold;
[JsonProperty(PropertyName = "Align")] [JsonConverter(typeof(StringEnumConverter))]
public TextAnchor Align;
[JsonProperty(PropertyName = "Color")] public IColor Color;
protected CuiTextComponent GetTextComponent(string msg)
{
return new CuiTextComponent
{
Text = msg,
FontSize = FontSize,
Font = IsBold ? "robotocondensed-bold.ttf" : "robotocondensed-regular.ttf",
Align = Align,
Color = Color.Get
};
}
public CuiElement GetText(string msg, string parent, string name = null, string destroyUI = null)
{
if (string.IsNullOrEmpty(name))
name = CuiHelper.GetGuid();
return new CuiElement
{
Name = name,
Parent = parent,
DestroyUi = destroyUI,
Components =
{
GetTextComponent(msg),
GetPosition()
}
};
}
}
public class InterfacePosition
{
public string AnchorMin;
public string AnchorMax;
public string OffsetMin;
public string OffsetMax;
protected CuiRectTransformComponent GetPosition()
{
return new CuiRectTransformComponent
{
AnchorMin = AnchorMin,
AnchorMax = AnchorMax,
OffsetMin = OffsetMin,
OffsetMax = OffsetMax
};
}
}
public class IColor
{
[JsonProperty(PropertyName = "Opacity (0 - 100)",
NullValueHandling = NullValueHandling.Include)]
public float Alpha;
[JsonProperty(PropertyName = "HEX", NullValueHandling = NullValueHandling.Include)]
public string Hex;
public static IColor Create(string hex, float alpha = 100)
{
return new IColor
{
Hex = hex,
Alpha = alpha
};
}
[JsonIgnore] private string _color;
[JsonIgnore]
public string Get
{
get
{
if (string.IsNullOrEmpty(_color))
UpdateColor();
return _color;
}
}
public void UpdateColor()
{
_color = GetColor();
}
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}";
}
}
#endregion
}
public class PluginConfiguration
{
[JsonProperty("Commands to open the store", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] Commands = {"store", "bucket"};
[JsonProperty("Enable show joining players in server tags")]
public bool ShowJoiningPlayers = false;
[JsonProperty("Load default images over client")]
public bool LoadSpriteImages = true;
[JsonProperty("Use Building Blocked?")]
public bool UseBuildingBlocked = false;
[JsonProperty("Use Combat Blocked?")] public bool UseCombatBlocked = false;
[JsonProperty("Use Raid Blocked?")] public bool UseRaidBlocked = false;
[JsonProperty("Execute instant commands if the player was not on the server?")]
public bool ExecuteInstantCommandsWhenNotInServer = false;
}
[JsonProperty("API configuration")] public APIConfiguration API = new();
[JsonProperty("Plugin Configuration")] public PluginConfiguration Plugin = new();
[JsonProperty("UI Configuration")] public InterfaceConfiguration UI = new();
public VersionNumber ConfigurationVersion = new(2, 0, 0);
}
#region Old Config
private void UpdateConfig(ConfigurationOld _old)
{
_config.API.ServerID = _old.API.ServerID;
_config.API.ShopID = _old.API.ShopID;
_config.API.SecretKey = _old.API.SecretKey;
_config.UI.BucketEnable = _old.Interface.BucketEnable;
_config.UI.TextShow = _old.Interface.TextShow;
_config.UI.BucketURL = _old.Interface.BucketURL;
_config.UI.ItemOnString = _old.Interface.ItemOnString;
_config.UI.StringAmount = _old.Interface.StringAmount;
_config.UI.ItemSide = _old.Interface.ItemSide;
_config.UI.ItemMargin = _old.Interface.ItemMargin;
_config.UI.BucketPosition.AnchorMin = _old.Interface.BucketPosition.AnchorMin;
_config.UI.BucketPosition.AnchorMax = _old.Interface.BucketPosition.AnchorMax;
_config.UI.BucketPosition.OffsetMin = _old.Interface.BucketPosition.OffsetMin;
_config.UI.BucketPosition.OffsetMax = _old.Interface.BucketPosition.OffsetMax;
}
private class ConfigurationOld
{
public class APIConfiguration
{
[JsonProperty("ИД магазина в сервисе")]
public string ShopID = "UNDEFINED";
[JsonProperty("ИД сервера в сервисе")] public string ServerID = "UNDEFINED";
[JsonProperty("Секретный ключ (не распространяйте его)")]
public string SecretKey = "UNDEFINED";
}
public class InterfaceConfiguration
{
[JsonProperty("Включить изображение корзины")]
public bool BucketEnable = true;
[JsonProperty("Включить отображение названий предметов")]
public bool TextShow = true;
[JsonProperty("Ссылка на изображение корзины (BUCKET - стандартное изображение)")]
public string BucketURL = "BUCKET";
[JsonProperty("Количество предметов на строке")]
public int ItemOnString = 7;
[JsonProperty("Количество строк в интерфейсе")]
public int StringAmount = 3;
[JsonProperty("Сторона одного предмета")]
public int ItemSide = 150;
[JsonProperty("Отступ между предметами")]
public int ItemMargin = 5;
[JsonProperty("Настройки позиции изображение корзины")]
public Position BucketPosition = new();
public class Position
{
public string AnchorMin = "0 1";
public string AnchorMax = "0 1";
public string OffsetMin = "8 -40";
public string OffsetMax = "43 -6";
}
}
[JsonProperty("Настройки API плагина")]
public APIConfiguration API = new();
[JsonProperty("Настройки интерфейса плагина")]
public InterfaceConfiguration Interface = new();
}
#endregion
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config?.API == null || _config.API.SecretKey == "UNDEFINED")
{
PrintWarning("Old config?");
var oldConfig = Config.ReadObject<ConfigurationOld>();
if (oldConfig?.API != null && oldConfig.API.SecretKey != "UNDEFINED")
{
PrintError("Old config! Update configuration!");
UpdateConfig(oldConfig);
NextTick(SaveConfig);
return;
}
PrintError("Your configuration is invalid! Create new!");
LoadDefaultConfig();
}
}
catch (Exception e)
{
LogAction(null, "Error reading config, creating one new config!", true, true);
LoadDefaultConfig();
Debug.LogException(e);
}
NextTick(SaveConfig);
}
protected override void LoadDefaultConfig()
{
_config = new Configuration();
}
protected override void SaveConfig()
{
Config.WriteObject(_config);
}
#endregion
#region Hooks
#region Init / Unload
private void Init()
{
BestApiLink = MainApiLink;
Instance = this;
}
private void OnServerInitialized()
{
#if !CARBON
if (ImageLibrary == null)
{
if (TryImageCounter < maxImageCheck)
{
LogAction(null, "ImageLibrary is not initialized, try again in 1 sec.", true);
TryImageCounter++;
timer.In(1, OnServerInitialized);
return;
}
LogAction(null, "Starting without ImageLibrary", true);
}
else
#endif
{
InitializeImages();
if (_config.UI.BucketURL.Contains("http")
#if !CARBON
&& ImageLibrary != null
#endif
)
InitializeBucketImage();
else
InitializePlayers();
}
LoadHeaderParams();
if (!InitializeServerSettings())
return;
RegisterCommands();
timer.Once(2, FetchShopUrl);
InitializeTimeoutCommands();
}
private void Unload()
{
try
{
DestroyInstantTimer();
if (_loadingCoroutine != null) ServerMgr.Instance.StopCoroutine(_loadingCoroutine);
foreach (var player in BasePlayer.activePlayerList)
{
CuiHelper.DestroyUi(player, IconLayer);
CuiHelper.DestroyUi(player, StoreLayer);
}
DestroyRequestCoroutines();
DisposeActiveRequests();
}
finally
{
Instance = null;
}
}
#endregion
#region Player
private void OnPlayerConnected(BasePlayer player)
{
if (player == null) return;
// if (_config.UI.BucketEnable)
// InitializeIcon(player);
}
private void OnPlayerDisconnected(BasePlayer player)
{
if (player == null) return;
DequeueBasketRequest(player.userID);
}
#endregion
#region Server
private void OnServerInformationUpdated()
{
if (!_config.Plugin.ShowJoiningPlayers)
{
Unsubscribe(nameof(OnServerInformationUpdated));
return;
}
NextTick(() =>
{
if (SteamServer.GameTags.Length > 122)
{
LogAction(null, "-----------------------------", true, true);
LogAction(null, "Perhaps you specified it incorrectly 'server.tags'!", true, true);
LogAction(null, "The tag of connecting players WILL NOT be added!", true, true);
LogAction(null, "-----------------------------", true, true);
Unsubscribe(nameof(OnServerInformationUpdated));
return;
}
var newTags = new List<string>();
foreach (var tag in SteamServer.GameTags.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
{
newTags.Add(tag);
if (tag.Substring(0, 2) == "qp")
newTags.Add($"jp{SingletonComponent<ServerMgr>.Instance.connectionQueue.Joining}");
}
try
{
SteamServer.GameTags = string.Join(",", newTags);
}
catch (Exception ex)
{
Unsubscribe(nameof(OnServerInformationUpdated));
}
});
}
#endregion
#endregion
#region Commands
[ConsoleCommand("mb.store.open")]
private void cmdOpenStore(ConsoleSystem.Arg arg)
{
if (arg.Player() == null)
return;
var player = arg.Player();
if (player == null || player.Connection == null || player.IsSleeping())
return;
if (maintenance)
{
Reply(player, Maintenance);
return;
}
if (!Initialized)
{
HandleInitializationError(player);
return;
}
if (CanRequestBasket(player))
{
InitializeStore(player, 0);
}
}
[ConsoleCommand("mb.store")]
private void cmdOpenStoreAlias(ConsoleSystem.Arg arg)
{
// alias to open the store from MenuBase or other plugins
cmdOpenStore(arg);
}
private void CmdChatStore(IPlayer cov, string command, string[] args)
{
}
[ConsoleCommand("UI_GameStoresRUST")]
private void CmdConsoleCommand(ConsoleSystem.Arg args)
{
var player = args.Player();
if (player == null) return;
if (HandleCommandBan(player, args)) return;
switch (args.Args[0].ToLower())
{
// case "page":
// {
// var page = args.GetInt(1);
//
// InitializeStore(player, page, false);
// break;
// }
//
// case "help":
// {
// ShowHelpUI(player);
// break;
// }
case "take":
{
UI_UpdateTakeButton(player, "");
if (!args.HasArgs(3)) return;
if (!int.TryParse(args.Args[1], out var index) ||
!int.TryParse(args.Args[2], out var basketID)) return;
ProcessTakeCommand(player, index, basketID);
break;
}
}
}
[ConsoleCommand("closemenu")]
private void CmdCloseMenu(ConsoleSystem.Arg args)
{
var player = args.Player();
if (player == null) return;
DequeueBasketRequest(player.userID);
}
#endregion
#region Interface
private const string
StoreLayer = "UI_GameStoresRUST_Store",
IconLayer = "UI_GameStoresRUST_Bucket",
HelpLayer = StoreLayer + ".Help";
private void InitializeStore(BasePlayer player, int page, bool first = true)
{
var container = new CuiElementContainer();
if (first)
CreateStoreUiContainer(ref container, player);
// CreateBlockPanel(ref container, player);
//
// if (first)
// CreateStoreExitButtonUI(player, ref container);
//
CuiHelper.AddUi(player, container);
//
if (first)
RequestBasket(player, page);
else
ShowBasketItemsUI(player, page);
}
private void ShowNotify(BasePlayer player, string text, float destroyTime = 0f)
{
// CuiHelper.AddUi(player, new CuiElementContainer
// {
// {
// new CuiLabel
// {
// RectTransform =
// {
// AnchorMin = "0 0.80", AnchorMax = "1 0.90", OffsetMax = "0 0"
// },
// Text =
// {
// FadeIn = 1f, Text = text, Align = TextAnchor.UpperCenter,
// Font = "robotocondensed-regular.ttf",
// FontSize = 16
// }
// },
// StoreLayer, StoreLayer + ".Notify", StoreLayer + ".Notify"
// }
// });
//
// if (destroyTime > 0f)
// timer.In(destroyTime, () => CuiHelper.DestroyUi(player, StoreLayer + ".Notify"));
}
private void ShowHelpUI(BasePlayer player)
{
CuiHelper.DestroyUi(player, StoreLayer);
var container = new CuiElementContainer();
container.Add(new CuiPanel
{
CursorEnabled = true,
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"},
Image = {Color = "0 0 0 0.9", Material = "assets/content/ui/uibackgroundblur.mat"}
}, "Overlay", HelpLayer, HelpLayer);
container.Add(new CuiLabel
{
RectTransform = {AnchorMin = "0 0.6", AnchorMax = "1 0.78", OffsetMax = "0 0"},
Text =
{
Text = Msg(player, MsgUserManual), Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf", FontSize = 34
}
}, HelpLayer);
container.Add(new CuiLabel
{
RectTransform = {AnchorMin = "0 0.3", AnchorMax = "1 0.72", OffsetMax = "0 0"},
Text =
{
Text = Msg(player, MsgUserManualDescription),
Font = "robotocondensed-regular.ttf", FontSize = 14, Align = TextAnchor.MiddleCenter
}
}, HelpLayer);
var addText = StartBalance > 0 ? Msg(player, MsgUserManualBalance, StartBalance) : string.Empty;
container.Add(new CuiLabel
{
RectTransform = {AnchorMin = "0 0.1", AnchorMax = "1 0.48", OffsetMax = "0 0"},
Text =
{
Text = $"{addText}\n{ShopURL.ToUpper()}", Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf", FontSize = 32
}
}, HelpLayer);
container.Add(new CuiButton
{
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"},
Button = {Color = "0 0 0 0", Close = HelpLayer, Command = "chat.say /store"},
Text = {Text = string.Empty}
}, HelpLayer);
CuiHelper.AddUi(player, container);
}
#region UI.Components
private int basketItemsPerPage => _config.UI.ItemOnString * _config.UI.StringAmount;
private void ShowBasketItemsUI(BasePlayer player,
int page)
{
if (!_playerBaskets.TryGetValue(player.userID, out var playerBasket))
return;
var wItems = playerBasket.GetItems(0, 500000);
var secondContainer = new CuiElementContainer();
secondContainer.Add(new CuiElement()
{
Name = Layer + ".main.div" + ".store" + ".items.div",
DestroyUi = Layer + ".main.div" + ".store" + ".items.div",
Parent = Layer + ".main.div" + ".store",
Components =
{
new CuiScrollViewComponent
{
Vertical = true,
Horizontal = false,
MovementType = ScrollRect.MovementType.Unrestricted,
Elasticity = 0,
Inertia = false,
DecelerationRate = 0,
ScrollSensitivity = 20,
ContentTransform = new()
{
AnchorMin = "0 1",
AnchorMax = "0 1",
OffsetMin = "0 -339.856",
OffsetMax = "0 0"
},
HorizontalScrollbar = null,
VerticalScrollbar = new()
{
Invert = false,
AutoHide = false,
HandleSprite = null,
Size = 2,
HandleColor = "0.9490196 0.5019608 0.05490196 1",
HighlightColor = "0.9490196 0.5019608 0.05490196 1",
PressedColor = "0.9490196 0.5019608 0.05490196 1",
TrackSprite = null,
TrackColor = "0 0 0 0.4"
}
},
new CuiRectTransformComponent()
{
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "11.44 -344.256", OffsetMax = "615.551 -4.4"
}
}
});
secondContainer.Add(new CuiPanel()
{
Image = { Color = "1 1 1 0.3" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-1000 -10000", OffsetMax = "1000 0"}
}, Layer + ".main.div" + ".store" + ".items.div");
//
// secondContainer.Add(new CuiPanel
// {
// CursorEnabled = false,
// Image = { Color = "1 1 1 0.4" },
// RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-303.56 -141.256", OffsetMax = "300.551 198.6" }
// }, Layer + ".main.div" + ".store", Layer + ".main.div" + ".store" + ".items.div", Layer + ".main.div" + ".store" + ".items.div");
float minx = 16.80002f;
float maxx = 95.60751f;
float miny = -95.05719f;
float maxy = -16.1875f;
int i = 0;
foreach (var x in wItems)
{
if (i % 6 == 0 && i != 0)
{
minx = 16.80002f;
maxx = 95.60751f;
miny -= 86.978f;
maxy -= 86.978f;
}
secondContainer.Add(new CuiButton
{
Button = { Color = "0 0 0 0.4", Command = $"mb.store.selectitem {x.basketId}"},
RectTransform = { AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = $"{minx} {miny}", OffsetMax = $"{maxx} {maxy}" }
}, Layer + ".main.div" + ".store" + ".items.div", Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}");
if (x.IsBlueprint)
{
secondContainer.Add(new CuiElement
{
Parent = Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}",
Components =
{
new CuiImageComponent { ItemId = ItemManager.blueprintBaseDef.itemid },
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
}
if (_config.Plugin.LoadSpriteImages && x.IsValid && x.itemDefinition != null)
{
secondContainer.Add(new CuiElement
{
Parent = Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}",
Components =
{
new CuiImageComponent {ItemId = x.itemDefinition.itemid},
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
}
else
{
if (!x.ImageUrl.Contains("http"))
secondContainer.Add(new CuiElement
{
Parent = Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}",
Components =
{
new CuiRawImageComponent {Png = x.ImageUrl},
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
else
secondContainer.Add(new CuiElement
{
Parent = Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}",
Components =
{
new CuiRawImageComponent { Url = x.ImageUrl },
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
}
// secondContainer.Add(new CuiPanel
// {
// CursorEnabled = false,
// Image = { Color = "1 1 1 1" },
// RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-25 -25", OffsetMax = "25 25" }
// }, Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}", Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}" + ".img");
secondContainer.Add(new CuiElement
{
Name = Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}" + ".text",
Parent = Layer + ".main.div" + ".store" + ".items.div" + $".{x.basketId}",
Components = {
new CuiTextComponent { Text = x.Name, Font = "robotocondensed-regular.ttf", FontSize = 9, Align = TextAnchor.LowerCenter, Color = "1 1 1 1" },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-42.344 -37.269", OffsetMax = "42.344 -21.331" }
}
});
i++;
minx += 97.696f;
maxx += 97.696f;
}
(secondContainer[0].Components[0] as CuiScrollViewComponent).ContentTransform.OffsetMin = $"0 {Mathf.Min(miny - 14, -339.856f)}";
if (miny > -339.856f)
{
(secondContainer[0].Components[0] as CuiScrollViewComponent).VerticalScrollbar = null;
}
// for (int i = 0; i < option.Count; i++) {
// if (i != 0) {
// int[] resetIndexs = {6,12};
// if (resetIndexs.Contains(i)){
// minx = -285.2f;
// maxx = -206.3925f;
// miny -= 86.978f;
// maxy -= 86.978f;
// } else {
// minx += -97.696f;
// maxx += -97.696f;
// }
// }
//
// secondContainer.Add(new CuiButton
// {
// Button = { Color = "1 1 1 0" },
// Text = { Text = "VIP на 7 дней", Font = "robotocondensed-regular.ttf", FontSize = 9, Align = TextAnchor.LowerCenter, Color = "1 1 1 1" },
// RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = $"{minx} {miny}", OffsetMax = $"{maxx} {maxy}" }
// }, "items.div", "1");
// }
// secondContainer.Add(new CuiLabel
// {
// RectTransform = {AnchorMin = "0 0", AnchorMax = "1 0.14", OffsetMax = "0 0"},
// Text = {Text = (page + 1).ToString(), Align = TextAnchor.MiddleCenter, FontSize = 34}
// }, StoreLayer + ".BlockPanel");
//
// secondContainer.Add(new CuiButton
// {
// RectTransform =
// {AnchorMin = "0.4 0.14", AnchorMax = "0.4 0.14", OffsetMin = "-40 -125", OffsetMax = "125 40"},
// Button = {Color = "0 0 0 0", Command = page > 0 ? $"UI_GameStoresRUST page {page - 1}" : string.Empty},
// Text =
// {
// Text = "<", Color = page > 0 ? "1 1 1 1" : "1 1 1 0.2", Align = TextAnchor.MiddleCenter,
// Font = "robotocondensed-regular.ttf", FontSize = 80
// }
// }, StoreLayer + ".BlockPanel");
//
// secondContainer.Add(new CuiButton
// {
// RectTransform =
// {AnchorMin = "0.6 0.14", AnchorMax = "0.6 0.14", OffsetMin = "-125 -125", OffsetMax = "40 40"},
// Button =
// {
// Color = "0 0 0 0",
// Command = (page + 1) * basketItemsPerPage < playerBasket.GetCount()
// ? $"UI_GameStoresRUST page {page + 1}"
// : string.Empty
// },
// Text =
// {
// Text = ">",
// Color = (page + 1) * basketItemsPerPage < playerBasket.GetCount() ? "1 1 1 1" : "1 1 1 0.2",
// Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 80
// }
// }, StoreLayer + ".BlockPanel");
//
// for (var i = 0; i < basketItemsPerPage; i++)
// {
// UI_RecountPosition(out var xSwitch, out var ySwitch, i, basketItemsPerPage);
//
// secondContainer.Add(new CuiButton
// {
// RectTransform =
// {
// AnchorMin = "0.495 0.55",
// AnchorMax = "0.495 0.55",
// OffsetMin = $"{xSwitch} {ySwitch - _config.UI.ItemSide}",
// OffsetMax = $"{xSwitch + _config.UI.ItemSide} {ySwitch}"
// },
// Button = {Color = _config.UI.ItemBackgroundColor.Get, Command = string.Empty},
// Text = {Text = string.Empty}
// }, StoreLayer + ".BlockPanel", StoreLayer + $".BlockPanel.{i}");
// }
//
// for (var index = 0; index < wItems.Count; index++)
// {
// var item = wItems[index];
//
// ShowBasketItemUI(player, item, ref secondContainer, index);
// }
CuiHelper.AddUi(player, secondContainer);
}
[ConsoleCommand("mb.store.selectitem")]
private void cmdSelectItem(ConsoleSystem.Arg arg)
{
if (arg.Player() == null || arg.Args.IsNullOrEmpty())
return;
string basketId = arg.Args[0];
UI_UpdateTakeButton(arg.Player(), basketId);
}
private void UI_UpdateTakeButton(BasePlayer player, string basketId)
{
var container = new CuiElementContainer();
if (string.IsNullOrEmpty(basketId))
{
CuiHelper.DestroyUi(player, Layer + ".main.div" + ".store" + ".itemname");
CuiHelper.DestroyUi(player, Layer + ".main.div" + ".store" + ".take.btn");
return;
}
if (!_playerBaskets.TryGetValue(player.userID, out var basket))
return;
if (!basket.BasketItems.TryGetValue(int.Parse(basketId), out var item))
return;
container.Add(new CuiElement
{
Name = Layer + ".main.div" + ".store" + ".itemname",
DestroyUi = Layer + ".main.div" + ".store" + ".itemname",
Parent = Layer + ".main.div" + ".store",
Components = {
new CuiTextComponent { Text = item.Name + (item.Amount <= 1 || item.IsCommand ? "" : $" x{item.Amount}"), Font = "robotocondensed-regular.ttf", FontSize = 16, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1" },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-303.25 -192.104", OffsetMax = "-76.49 -150.576" }
}
});
// container.Add(new CuiPanel()
// {
// Image = { Sprite = "assets/icons/square.png", Color = "0.9490196 0.5019608 0.05490196 1" },
// RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "-11 -11", OffsetMax = "11 11"}
// }, Layer + ".main.div" + ".store" + ".items.div" + $".{basketId}", Layer + ".main.div" + ".store" + ".selectedItem", Layer + ".main.div" + ".store" + ".selectedItem");
container.Add(new CuiButton
{
Button = { Color = "0.247 0.933 0.0 0.26", Command = $"UI_GameStoresRUST take {basketId} {basketId}" },
Text = { Text = "ЗАБРАТЬ", Font = "robotocondensed-bold.ttf", FontSize = 15, Align = TextAnchor.MiddleCenter, Color = "1 1 1 0.8" },
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-67.79 -186.1", OffsetMax = "67.79 -156.573" }
}, Layer + ".main.div" + ".store", Layer + ".main.div" + ".store" + ".take.btn", Layer + ".main.div" + ".store" + ".take.btn");
CuiHelper.AddUi(player, container);
}
private void ShowBasketItemUI(BasePlayer player, WItem item, ref CuiElementContainer secondContainer,
int index)
{
if (item.IsBlueprint) ItemBlueprintImageUI(ref secondContainer, index);
if (_config.Plugin.LoadSpriteImages && item.IsValid && item.itemDefinition != null)
{
secondContainer.Add(new CuiElement
{
Parent = StoreLayer + $".BlockPanel.{index}",
Components =
{
new CuiImageComponent {ItemId = item.itemDefinition.itemid},
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
}
else
{
if (!item.ImageUrl.Contains("http"))
secondContainer.Add(new CuiElement
{
Parent = StoreLayer + $".BlockPanel.{index}",
Components =
{
new CuiRawImageComponent {Png = item.ImageUrl},
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
else
secondContainer.Add(new CuiElement
{
Parent = StoreLayer + $".BlockPanel.{index}",
Components =
{
new CuiRawImageComponent {Url = item.ImageUrl},
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
}
if (item.Amount > 1)
secondContainer.Add(new CuiLabel
{
RectTransform =
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "0 5", OffsetMax = "-5 0"},
Text =
{
Text = "x" + item.Amount, Align = TextAnchor.LowerRight,
Font = "robotocondensed-regular.ttf", FontSize = 14
}
}, StoreLayer + $".BlockPanel.{index}");
secondContainer.Add(new CuiButton
{
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"},
Button =
{
Color = "0 0 0 0", Close = StoreLayer + $".BlockPanel.{index}.Open",
Command =
$"UI_GameStoresRUST take {index} {item.basketId}"
},
Text = {Text = string.Empty}
}, StoreLayer + $".BlockPanel.{index}", StoreLayer + $".BlockPanel.{index}.Open");
if (_config.UI.TextShow)
secondContainer.Add(new CuiLabel
{
RectTransform =
{AnchorMin = "0 0", AnchorMax = "1 0", OffsetMin = "0 -22.5", OffsetMax = "0 0"},
Text =
{
Text = item.Name, Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-regular.ttf", FontSize = 16, Color = "1 1 1 0.8"
}
}, StoreLayer + $".BlockPanel.{index}");
if (!CanRequestGetItem(Convert.ToInt32(item.basketId)))
{
ShowNotify(player, Msg(player, MsgTakeRequestProcessing));
secondContainer.Add(new CuiButton
{
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"},
Button =
{
FadeIn = 1f, Color = "1 1 1 0.2",
Close = StoreLayer + ".BlockPanel." + index + ".Open",
Command = $"UI_GameStoresRUST take {index} {item.basketId}"
},
Text =
{
Text = Msg(player, MsgTakeWait), Align = TextAnchor.MiddleCenter,
Font = "robotocondensed-bold.ttf", Color = "1 1 1 0.4", FontSize = 14
}
}, StoreLayer + ".BlockPanel." + index, StoreLayer + ".BlockPanel." + index + ".Open");
}
}
private void ItemBlueprintImageUI(ref CuiElementContainer secondContainer, int index)
{
if (_config.Plugin.LoadSpriteImages)
{
secondContainer.Add(new CuiElement
{
Parent = StoreLayer + $".BlockPanel.{index}",
Components =
{
new CuiImageComponent {ItemId = ItemManager.blueprintBaseDef.itemid},
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
}
else
{
#if CARBON
var blueprintImageComponent = new CuiRawImageComponent {Png = GetImage("blueprintbase")};
#else
var blueprintImageComponent = ImageLibrary?.IsLoaded == true
? new CuiRawImageComponent {Png = GetImage("blueprintbase")}
: new CuiRawImageComponent {Url = "https://gamestores.app/img/games/rust/blueprintbase.png"};
#endif
secondContainer.Add(new CuiElement
{
Parent = StoreLayer + $".BlockPanel.{index}",
Components =
{
blueprintImageComponent,
new CuiRectTransformComponent
{AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "5 5", OffsetMax = "-5 -5"}
}
});
}
}
private void CreateStoreExitButtonUI(BasePlayer player, ref CuiElementContainer container)
{
container.AddRange(_config.UI.StoreExitButton.Get(Msg(player, MsgExit), "closemenu", StoreLayer,
close: StoreLayer));
}
private const string Layer = "ui.MenuBase.bg";
private void CreateStoreUiContainer(ref CuiElementContainer container, BasePlayer player)
{
container.Add(new CuiPanel
{
CursorEnabled = false,
Image = { Color = "0.3568628 0.3568628 0.3568628 0" },
RectTransform = { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-314.691 -229.228", OffsetMax = "314.689 176.992" }
}, Layer + ".main.div", Layer + ".main.div" + ".store");
container.Add(new CuiElement
{
Name = Layer + ".main.div" + ".label",
Parent = Layer + ".main.div" + ".store",
Components = {
new CuiTextComponent { Text = "КОРЗИНА", Font = "robotocondensed-bold.ttf", FontSize = 27, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1" },
new CuiRectTransformComponent { AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-303.556 203.112", OffsetMax = "40.556 255.344" }
}
});
// container.Add(_config.UI.Background.Get(StoreLayer, StoreLayer, true));
// container.AddRange(_config.UI.BasketTitle.Get(Msg(player, MsgBasket), string.Empty, StoreLayer));
// container.Add(_config.UI.BasketDescription.GetText(Msg(player, MsgBasketDescription), StoreLayer));
// container.AddRange(_config.UI.HelpButton.Get(Msg(player, MsgHelp), "UI_GameStoresRUST help",
// StoreLayer));
}
private void CreateBlockPanel(ref CuiElementContainer container, BasePlayer player)
{
container.Add(_config.UI.BlockPanel.GetImage(StoreLayer, StoreLayer + ".BlockPanel",
StoreLayer + ".BlockPanel"));
container.Add(_config.UI.RequestProcessingTitle.GetText(Msg(player, MsgRequestProcessing),
StoreLayer + ".BlockPanel", StoreLayer + ".BlockPanel.Text"));
}
private void InitializeIcon(BasePlayer player)
{
UpdateUI(player, container =>
{
if (_config.UI.BucketURL.Contains("http"))
CreateBucketIconWithImageLibrary(ref container);
else
CreateBucketIconWithoutImageLibrary(ref container);
});
}
private void CreateBucketIconWithImageLibrary(ref CuiElementContainer container)
{
#if CARBON
var bucketImageComponent = new CuiRawImageComponent {Png = GetImage(ImageBucket)};
#else
var bucketImageComponent = ImageLibrary is {IsLoaded: true}
? new CuiRawImageComponent {Png = GetImage(ImageBucket)}
: new CuiRawImageComponent {Url = _config.UI.BucketURL};
#endif
container.Add(new CuiElement
{
Parent = "Overlay",
Name = IconLayer,
DestroyUi = IconLayer,
Components =
{
bucketImageComponent,
new CuiRectTransformComponent
{
AnchorMin = _config.UI.BucketPosition.AnchorMin,
AnchorMax = _config.UI.BucketPosition.AnchorMax,
OffsetMin = _config.UI.BucketPosition.OffsetMin,
OffsetMax = _config.UI.BucketPosition.OffsetMax
}
}
});
container.Add(new CuiButton
{
RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1", OffsetMax = "0 0"},
Button = {Color = "0 0 0 0", Command = "chat.say /store"},
Text = {Text = string.Empty}
}, IconLayer);
}
private void CreateBucketIconWithoutImageLibrary(ref CuiElementContainer container)
{
container.Add(new CuiButton
{
RectTransform =
{
AnchorMin = _config.UI.BucketPosition.AnchorMin,
AnchorMax = _config.UI.BucketPosition.AnchorMax,
OffsetMin = _config.UI.BucketPosition.OffsetMin,
OffsetMax = _config.UI.BucketPosition.OffsetMax
},
Button = {Color = "1 1 1 0.6", Sprite = "assets/icons/open.png", Command = "chat.say /store"},
Text = {Text = string.Empty}
}, "Overlay", IconLayer, IconLayer);
}
private void UI_RecountPosition(out double xSwitch, out double ySwitch, int count, int max)
{
var stringAmount = Math.Ceiling((double) max / _config.UI.ItemOnString);
var currentString = Math.Floor((double) count / _config.UI.ItemOnString);
var currentPosition = count % _config.UI.ItemOnString;
var topYPosition = 0 + (float) stringAmount / 2 * _config.UI.ItemSide +
((float) stringAmount / 2 - 1) * _config.UI.ItemMargin;
var topXPosition = 0 - (float) _config.UI.ItemOnString / 2 * _config.UI.ItemSide -
((float) _config.UI.ItemOnString / 2 - 1) * _config.UI.ItemMargin;
var curYPosition = topYPosition - currentString * _config.UI.ItemSide - currentString *
(_config.UI.ItemMargin + (_config.UI.TextShow ? 20 : 0));
var curXPosition = topXPosition + currentPosition * _config.UI.ItemSide +
currentPosition * _config.UI.ItemMargin;
xSwitch = curXPosition;
ySwitch = curYPosition;
}
#endregion
#region UI.Helpers
private static void UpdateUI(BasePlayer player, Action<CuiElementContainer> callback)
{
if (player == null) return;
var container = new CuiElementContainer();
callback?.Invoke(container);
CuiHelper.AddUi(player, container);
}
#endregion
#endregion
#region Utils
#region Player Basket
#region Classes
private class PlayerBasket
{
public Dictionary<int, WItem> BasketItems = new();
public PlayerBasket(List<object> data)
{
foreach (Dictionary<string, object> product in data)
{
if (!product.TryGetValue("basketId", out var basketIdObj) ||
!int.TryParse(basketIdObj.ToString(), out var basketId))
continue;
var item = new WItem(product);
BasketItems[basketId] = item;
var leftTime = Instance?.WB_GetLeftTime(item.productId, item.ItemID, item.IsBlueprint) ?? 0;
if (leftTime > 0)
{
item.IsBlocked = true;
item.LeftTime = leftTime;
}
}
}
public void Clear()
{
BasketItems.Clear();
}
public List<WItem> GetItems(int page, int count)
{
return new List<WItem>(BasketItems.Values.Skip(page * count).Take(count));
}
public int GetCount()
{
return BasketItems.Count;
}
}
#endregion
#endregion
#region Blocks
private bool NE_IsCombatBlocked(BasePlayer player)
{
return Convert.ToBoolean(NoEscape?.Call("IsCombatBlocked", player));
}
private bool NE_IsRaidBlocked(BasePlayer player)
{
return Convert.ToBoolean(NoEscape?.Call("IsRaidBlocked", player));
}
private double WB_GetLeftTime(string productId, int itemID, bool isBlueprint)
{
return Convert.ToDouble(GameStoresWipeBlock?.Call("GetLeftTime", productId, itemID, isBlueprint));
}
#endregion
#region Plugin Loading
private void LoadHeaderParams()
{
reqHeaders.Add("X-Plugin-Version", Version.ToString());
reqHeaders.Add("storeId", _config.API.ShopID);
reqHead
// ... [Code preview truncated due to length. Full source in attached file] ...