C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Facepunch;
using Oxide.Core;
using System.Text;
using Oxide.Core.Plugins;
using System;
using System.Collections.Generic;
using Oxide.Plugins.TPShopExtensionMethods;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Game.Rust.Cui;
using System.Collections;
namespace Oxide.Plugins {
[Info("TPShop", "Sempai", "11.0.1")]
[Description("Дополнение для сборки")]
internal class TPShop : RustPlugin {
private void CONFIRMATIONSUI(BasePlayer player, int itemID, int indexCategory, int amount, ThemeType themetype) {
Configuration.InterfaceSettings.ThemeCustomization theme = themetype == ThemeType.Dark ? _config.interfaceSettings.DarkTheme : _config.interfaceSettings.LightTheme;
Configuration.CategoryShop.Product product = GetCategories(player)[indexCategory].product.Find(x => x.ID == itemID);
float discount = GetUserDiscount(player);
int playerLim = GetLimit(player, product, true);
string limit = playerLim == -1 ? GetLang("TPShop_UI_PATTERN", player.UserIDString) : playerLim + "/" + product.GetLimitLotWipe(player, true);
CuiElementContainer container = new CuiElementContainer {
new CuiElement {
Name = ConfirmationsPanel, Parent = PanelProduct, Components = {
new CuiRawImageComponent {
Color = theme.colorMainBG, Png =GetImage($"{Name}_" +"13")
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-230.488 -109.615", OffsetMax = "261.007 77.799"
}
}
}
, new CuiElement {
Name = "IMAGE_PRODUCT_BACKGROUND", Parent = ConfirmationsPanel, Components = {
new CuiRawImageComponent {
Color = theme.colortext6, Png =GetImage($"{Name}_" +"15")
}
, new CuiRectTransformComponent {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "46.52 -114.22", OffsetMax = "122.52 -42.22"
}
}
}
}
;
if (!string.IsNullOrWhiteSpace(product.Url) || product.Type == ItemType.Kit || product.Type == ItemType.Command) {
container.Add(new CuiElement {
Name = "PRODUCT_IMAGE", Parent = "IMAGE_PRODUCT_BACKGROUND", Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = GetImage(string.IsNullOrWhiteSpace(product.Url) ? "NONE" : product.Url)
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-30 -30", OffsetMax = "30 30"
}
}
}
);
}
else if (product.Type == ItemType.CustomItem) {
container.Add(new CuiElement {
Name = "PRODUCT_IMAGE", Parent = "IMAGE_PRODUCT_BACKGROUND", Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = GetImage(product.ShortName + 60, product.SkinID)
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-30 -30", OffsetMax = "30 30"
}
}
}
);
}
else if (product.Type == ItemType.Item) {
container.Add(new CuiElement {
Name = "PRODUCT_IMAGE", Parent = "IMAGE_PRODUCT_BACKGROUND", Components = {
new CuiImageComponent {
Color = "1 1 1 1", ItemId = ItemManager.FindItemDefinition(product.ShortName).itemid
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-30 -30", OffsetMax = "30 30"
}
}
}
);
}
else {
container.Add(new CuiElement {
Name = "PRODUCT_IMAGE", Parent = "IMAGE_PRODUCT_BACKGROUND", Components = {
new CuiImageComponent {
Color = "1 1 1 1", ItemId = ItemManager.FindItemDefinition("blueprintbase").itemid
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-30 -30", OffsetMax = "30 30"
}
}
}
);
container.Add(new CuiElement {
Name = "PRODUCT_IMAGE", Parent = "IMAGE_PRODUCT_BACKGROUND", Components = {
new CuiImageComponent {
Color = "1 1 1 1", ItemId = ItemManager.FindItemDefinition(product.ShortName).itemid
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-30 -30", OffsetMax = "30 30"
}
}
}
);
}
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-118.134 -68.265", OffsetMax = "8.346 -39.543"
}
, Text = {
Text = product.GetProductName(player.UserIDString), Font = "robotocondensed-bold.ttf", FontSize = 11, Align = TextAnchor.LowerLeft, Color = theme.colortext7
}
,
}
, ConfirmationsPanel);
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-118.134 -137.191", OffsetMax = "8.346 -70.689"
}
, Text = {
Text = GetLang("TPShop_UI_PRODUCT_INFO", player.UserIDString, GetDiscountedPrice(product.Price * amount, discount) + _config.economicsCustomization.PrefixBalance, product.Amount * amount, limit), Font = "robotocondensed-regular.ttf", FontSize = 11, Align = TextAnchor.MiddleLeft, Color = theme.Colortext5
}
,
}
, ConfirmationsPanel);
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-228.122 -8.202", OffsetMax = "-44.678 54.164"
}
, Text = {
Text = product.GetProductDescription(), Font = "robotocondensed-regular.ttf", FontSize = 10, Align = TextAnchor.UpperLeft, Color = theme.Colortext5
}
,
}
, ConfirmationsPanel);
container.Add(new CuiElement {
Name = "PRODUCT_BUY_BTN", Parent = ConfirmationsPanel, Components = {
new CuiRawImageComponent {
Color = theme.colortext8, Png =GetImage($"{Name}_" +"14")
}
, new CuiRectTransformComponent {
AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-162.4 42.9", OffsetMax = "-109.4 63.9"
}
}
}
);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Button = {
Command = $"UI_HandlerShop PRODUCT_BUY {itemID} {indexCategory} {amount} {themetype}", Color = "0 0 0 0"
}
, Text = {
Text = GetLang("TPShop_UI_BTN_BUY", player.UserIDString).ToUpper(), Font = "robotocondensed-regular.ttf", FontSize = 11, Align = TextAnchor.MiddleCenter
}
}
, "PRODUCT_BUY_BTN");
container.Add(new CuiElement {
Name = "PRODUCT_CLOSE_BTN", Parent = ConfirmationsPanel, Components = {
new CuiRawImageComponent {
Color = theme.closeBtnColor2, Png = GetImage($"{Name}_" +"14")
}
, new CuiRectTransformComponent {
AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-100 42.9", OffsetMax = "-47 63.9"
}
}
}
);
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Button = {
Close = "CONFIRMATIONS_PANEL", Color = "0 0 0 0"
}
, Text = {
Text = GetLang("TPShop_UI_PRODUCT_INFO_EXIT", player.UserIDString), Font = "robotocondensed-regular.ttf", FontSize = 11, Align = TextAnchor.MiddleCenter
}
}
, "PRODUCT_CLOSE_BTN");
CuiHelper.DestroyUi(player, ConfirmationsPanel);
CuiHelper.AddUi(player, container);
}
[ConsoleCommand("TPShop.refill")]
private void CmdShopItemsRefill(ConsoleSystem.Arg arg) {
if (arg.Connection != null && arg.Connection.authLevel <= 0) return;
SendReply(arg, GetLang("TPShop_SERVICE_CMD_REFILL"));
ulong userId = arg.Connection == null || arg.IsRcon ? 0U : arg.Connection.userid;
if (_pdpw.Contains(userId)) return;
_pdpw.Add(userId);
timer.In(15, () => {
if (_pdpw.Contains(userId)) _pdpw.Remove(userId);
}
);
}
private const string MainLayer = "MAIN_SHOP_LAYER";
private class CooldownData {
public DateTime Buy = new DateTime(1970, 1, 1, 0, 0, 0);
public DateTime Sell = new DateTime(1970, 1, 1, 0, 0, 0);
}
private void AddLimit(BasePlayer player, Configuration.CategoryShop.Product item, int lots, bool purchase) {
PlayerLimits.GetOrAddPlayer(player.userID).AddItem(item, lots, purchase);
}
private void Purchasing(BasePlayer player, int itemId, int category, int amount, ThemeType themetype) {
Configuration.CategoryShop.Product product = GetCategories(player)[category].product.Find(x => x.ID == itemId);
if (product != null) {
if (IsDuel(player)) {
NotificationUI(player, NotificationType.Error, GetLang("TPShop_UI_NOTIFICATION_IS_DUEL", player.UserIDString));
return;
}
if (_config.mainSettings.RaidBlock && IsRaid(player)) {
NotificationUI(player, NotificationType.Error, GetLang("TPShop_UI_NOTIFICATION_IS_RAID", player.UserIDString));
return;
}
if (product.Type == ItemType.Blueprint || product.Type == ItemType.CustomItem || product.Type == ItemType.Item) {
List<int> stack = GetStacks(product.Definition, product.Amount * amount);
int slots = player.inventory.containerBelt.capacity - player.inventory.containerBelt.itemList.Count + (player.inventory.containerMain.capacity - player.inventory.containerMain.itemList.Count);
if (slots < stack.Count) {
NotificationUI(player, NotificationType.Warning, GetLang("TPShop_UI_NOTIFICATION_NOT_ENOUGH_SPACE", player.UserIDString));
return;
}
}
float price = GetDiscountedPrice(product.Price * amount, GetUserDiscount(player));
if (GetBalance(player) < price) {
NotificationUI(player, NotificationType.Error, GetLang("TPShop_UI_NOTIFICATION_INSUFFICIENT_FUNDS", player.UserIDString));
return;
}
if (product.BuyCooldown > 0) {
int cooldown = GetCooldownTime(player.userID, product, true);
if (cooldown > 0) {
NotificationUI(player, NotificationType.Warning, GetLang("TPShop_UI_NOTIFICATION_BUY_RECHARGE", player.UserIDString, product.GetProductName(player.UserIDString), TimeHelper.FormatTime(TimeSpan.FromSeconds(cooldown), 5, lang.GetLanguage(player.UserIDString))));
return;
}
SetCooldown(player, product, true);
}
int limit = GetLimit(player, product, true);
if (limit != -1) {
if (limit == 0) {
NotificationUI(player, NotificationType.Warning, GetLang("TPShop_UI_NOTIFICATION_BUY_LIMIT", player.UserIDString, product.GetProductName(player.UserIDString)));
return;
}
else if (amount > limit) {
NotificationUI(player, NotificationType.Warning, GetLang("TPShop_UI_NOTIFICATION_BUY_LIMIT_1", player.UserIDString, product.GetProductName(player.UserIDString), limit));
return;
}
AddLimit(player, product, amount, true);
}
switch (_config.economicsCustomization.TypeEconomic) {
case EconomicsType.Economics : if ((bool)Economics?.Call("Withdraw", player.userID, (double)price)) {
GiveProduct(player, product, amount);
NotificationUI(player, NotificationType.Success, GetLang("TPShop_UI_NOTIFICATION_SUCCESSFUL_PURCHASE", player.UserIDString, product.GetProductName(player.UserIDString)));
}
break;
case EconomicsType.ServerRewards : if (ServerRewards?.Call<object>("TakePoints", player.userID, (int)price) != null) {
GiveProduct(player, product, amount);
NotificationUI(player, NotificationType.Success, GetLang("TPShop_UI_NOTIFICATION_SUCCESSFUL_PURCHASE", player.UserIDString, product.GetProductName(player.UserIDString)));
}
break;
case EconomicsType.IQEconomic : IQEconomic?.Call("API_REMOVE_BALANCE", player.userID, (int)price);
GiveProduct(player, product, amount);
NotificationUI(player, NotificationType.Success, GetLang("TPShop_UI_NOTIFICATION_SUCCESSFUL_PURCHASE", player.UserIDString, product.GetProductName(player.UserIDString)));
break;
/*case EconomicsType.TPEconomic:
TPEconomic?.Call("API_PUT_BALANCE_MINUS", player.userID, (float)price);
GiveProduct(player, product, amount);
NotificationUI(player, NotificationType.Success, GetLang("TPShop_UI_NOTIFICATION_SUCCESSFUL_PURCHASE", player.UserIDString, product.GetProductName(player.UserIDString)));
if(TPMenuSystem)
TPMenuSystem?.Call("UpdateUIBalance", player);
break;*/
}
}
}
private const string ProductAmountChangeBg = "PRODUCT_AMOUNT_CHANGE_BG";
private enum EconomicsType {
Economics, ServerRewards, IQEconomic, Item, TPEconomic,
}
private void NotificationUI(BasePlayer player, NotificationType type, string msg) {
string color = type == NotificationType.Error ? "1.00 0.30 0.31 1.00" : type == NotificationType.Warning ? "0.98 0.68 0.08 1.00" : "0.32 0.77 0.10 1.00";
ThemeType themeType = _playerThemeSelect[player.userID];
Configuration.InterfaceSettings.ThemeCustomization theme = themeType == ThemeType.Dark ? _config.interfaceSettings.DarkTheme : _config.interfaceSettings.LightTheme;
CuiElementContainer container = new CuiElementContainer {
new CuiElement {
FadeOut = 0.30f, Name = NotificationMain, Parent = "OverlayNonScaled", Components = {
new CuiRawImageComponent {
Color = theme.colorMainBG, Png =GetImage($"{Name}_" +"16"), FadeIn = 0.30f
}
, new CuiRectTransformComponent {
AnchorMin = "0 1", AnchorMax = "0 1", OffsetMin = "112 -78", OffsetMax = "383 -10"
}
}
}
, new CuiElement {
FadeOut = 0.30f, Name = "NOTIFICATION_POLOSA", Parent = NotificationMain, Components = {
new CuiRawImageComponent {
Color = color, Png = GetImage($"{Name}_" +"17") , FadeIn = 0.30f
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0", AnchorMax = "0.5 0", OffsetMin = "-95.99 -1.97", OffsetMax = "75.01 2.03"
}
}
}
, new CuiElement {
FadeOut = 0.30f, Name = "NOTIFICATION_IMG", Parent = NotificationMain, Components = {
new CuiRawImageComponent {
Color = color, Png = GetImage($"{Name}_" +"10") , FadeIn = 0.30f
}
, new CuiRectTransformComponent {
AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "13.5 -32.47", OffsetMax = "73.5 28.53"
}
}
}
, {
new CuiLabel {
FadeOut = 0.30f, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-58 -32.47", OffsetMax = "119.546 28.53"
}
, Text = {
Text = msg, Font = "robotocondensed-regular.ttf", FontSize = 11, Align = TextAnchor.MiddleLeft, Color = theme.Colortext10, FadeIn = 0.30f
}
,
}
, NotificationMain, "NOTIFICATION_TEXT"
}
}
;
CuiHelper.DestroyUi(player, "NOTIFICATION_POLOSA");
CuiHelper.DestroyUi(player, "NOTIFICATION_IMG");
CuiHelper.DestroyUi(player, "NOTIFICATION_TEXT");
CuiHelper.DestroyUi(player, NotificationMain);
CuiHelper.AddUi(player, container);
DeleteNotification(player);
}
private void GiveProduct(BasePlayer player, Configuration.CategoryShop.Product product, int amount) {
switch (product.Type) {
case ItemType.Item : GetStacks(product.Definition, product.Amount * amount)?.ForEach(stack => {
Item newItem = ItemManager.CreateByPartialName(product.ShortName, stack);
player.GiveItem(newItem, BaseEntity.GiveItemReason.PickedUp);
}
);
break;
case ItemType.Blueprint : GetStacks(product.Definition, product.Amount * amount)?.ForEach(stack => {
Item itemBp = ItemManager.CreateByItemID(-996920608, stack);
if (itemBp.instanceData == null) itemBp.instanceData = new ProtoBuf.Item.InstanceData();
itemBp.instanceData.ShouldPool = false;
itemBp.instanceData.blueprintAmount = 1;
itemBp.instanceData.blueprintTarget = product.Definition.itemid;
itemBp.MarkDirty();
player.GiveItem(itemBp, BaseEntity.GiveItemReason.PickedUp);
}
);
break;
case ItemType.CustomItem : GetStacks(product.Definition, product.Amount * amount)?.ForEach(stack => {
Item customItem = ItemManager.CreateByPartialName(product.ShortName, stack, product.SkinID);
customItem.name = product.Name;
player.GiveItem(customItem, BaseEntity.GiveItemReason.PickedUp);
}
);
break;
case ItemType.Command : foreach (string cammand in product.Commands) Server.Command(cammand.Replace("%STEAMID%", player.UserIDString));
break;
case ItemType.Kit : if (Kits) Kits.Call("GiveKit", player, product.KitName);
else if (IQKits) IQKits.Call("API_KIT_GIVE", player, product.KitName);
break;
}
}
[ConsoleCommand("TPShop.no")]
private void CmdShopItemsRefillNo(ConsoleSystem.Arg arg) {
if (arg.Connection != null && arg.Connection.authLevel <= 0) return;
ulong userId = arg.Connection == null || arg.IsRcon ? 0U : arg.Connection.userid;
if (!_pdpw.Contains(userId)) return;
SendReply(arg, GetLang("TPShop_SERVICE_CMD_REFILL_NO"));
_pdpw.Remove(userId);
}
private float GetDiscountedPrice(float price, float discount) {
float dicsount = (price * discount / 100);
return (float)Math.Round(price - dicsount, 2);
}
private void UPDATEAMOUNTUI(BasePlayer player, int categoryIndex, int cat, int amount) {
Configuration.CategoryShop.Product item = GetCategories(player)[cat].product.Find(x => x.ID == categoryIndex);
if (amount <= 0 || (item.GetLimitLot(player, true) != 0 && amount > item.GetLimitLot(player, true)) || amount >= 100) return;
float discount = GetUserDiscount(player);
CuiHelper.DestroyUi(player, $"PRODUCT_BACKGROUND_BUTTON_{item.ID}");
CuiHelper.DestroyUi(player, $"PRODUCT_PRICE_{item.ID}");
CuiHelper.DestroyUi(player, $"PRODUCT_AMOUNT_CHANGE_{item.ID}");
CuiHelper.DestroyUi(player, $"PRODUCT_IMAGE_{item.ID}");
CuiHelper.DestroyUi(player, $"PRODUCT_BUY_BTN_IMAGE_{item.ID}");
var container = new CuiElementContainer();
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-31 -55", OffsetMax = "5 34"
}
, Text = {
Text = $"{GetDiscountedPrice(item.Price, discount)}{_config.economicsCustomization.PrefixBalance}", Font = "robotocondensed-bold.ttf", FontSize = 11, Align = TextAnchor.UpperLeft, Color = "1 1 1 0.7"
}
,
}
, $"PRODUCT_BACKGROUND_{item.ID}", $"PRODUCT_PRICE_{item.ID}");
var imageItemContainer = UIPRODUCTGETIMAGEITEM(item);
foreach (var element in imageItemContainer) {
container.Add(element);
}
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1", OffsetMin = "8 5", OffsetMax = "-8 -50"
}
, Button = {
Command = $"UI_HandlerShop PRODUCT_BUY_CONFIRMATION {item.ID} {cat} {amount} 1", Color = "1 1 1 0"
}
,
}
, $"PRODUCT_BACKGROUND_{item.ID}", $"PRODUCT_BUY_BTN_{item.ID}");
container.Add(new CuiElement {
Name = $"PRODUCT_BUY_BTN_IMAGE_{item.ID}", Parent = $"PRODUCT_BUY_BTN_{item.ID}", Components = {
new CuiRawImageComponent {
Png = GetImage($"{Name}_" +"20"),
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1",
}
}
}
);
container.Add(new CuiElement {
Parent = $"PRODUCT_BUY_BTN_IMAGE_{item.ID}", Components = {
new CuiTextComponent {
Text = GetLang("TPShop_UI_BTN_BUY", player.UserIDString), FontSize = 11, Align = TextAnchor.MiddleCenter,
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "1 1",
}
,
}
}
);
//ПЕРЕКЛЮЧАТЕЛЬ + -
container.Add(new CuiPanel {
CursorEnabled = false, Image = {
Color = "1 1 1 0"
}
, RectTransform = {
AnchorMin = "1 0", AnchorMax = "1 0", OffsetMin = "-50 45", OffsetMax = "0 70"
}
}
, $"PRODUCT_BACKGROUND_{item.ID}", $"PRODUCT_AMOUNT_CHANGE_{item.ID}");
//КАРТИНКА ПЕРЕКЛЮЧАТЕЛЯ
container.Add(new CuiElement {
Name = ProductAmountChangeBg + $"_{item.ID}", Parent = $"PRODUCT_AMOUNT_CHANGE_{item.ID}", Components = {
new CuiRawImageComponent {
Color ="1 1 1 1", Png =GetImage($"{Name}_" +"9")
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-20 -4", OffsetMax = "20 10"
}
}
}
);
//КНОПКА ПЕРЕКЛЮЧАТЕЛЯ -
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "0 -8", OffsetMax = "14.936 8"
}
, Button = {
Command = $"UI_HandlerShop AMOUNT_CHANGE_MINUS {item.ID} {cat} {amount} 0", Color = "0 0 0 0"
}
, Text = {
Text = ""
}
}
, ProductAmountChangeBg + $"_{item.ID}", $"PRODUCT_AMOUNT_MINUS_{item.ID}");
//КНОПКА ПЕРЕКЛЮЧАТЕЛЯ +
container.Add(new CuiButton {
RectTransform = {
AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-15.628 -8", OffsetMax = "0 8"
}
, Button = {
Command = $"UI_HandlerShop AMOUNT_CHANGE_PLUS {item.ID} {cat} {amount} 0", Color = "0 0 0 0"
}
, Text = {
Text = ""
}
}
, ProductAmountChangeBg + $"_{item.ID}", $"PRODUCT_AMOUNT_PLUS_{item.ID}");
//ЦИФЕРКА ПЕРЕКЛЮЧАТЕЛЯ
container.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-10.064 -8", OffsetMax = "9.372 8"
}
, Text = {
Text = $"{amount}", Font = "robotocondensed-regular.ttf", FontSize = 9, Align = TextAnchor.MiddleCenter, Color = "1 1 1 0.8"
}
,
}
, ProductAmountChangeBg + $"_{item.ID}", $"PRODUCT_LOT_COUNT_{item.ID}");
CuiHelper.AddUi(player, container);
}
private void OnPlayerDisconnected(BasePlayer player, string reason) {
if (_uiPlayerUseNow.Contains(player.userID)) _uiPlayerUseNow.Remove(player.userID);
if (_config.humanNpcs.UseHumanNpcs) if (_humanNpcPlayerOpen.ContainsKey(player.userID)) _humanNpcPlayerOpen.Remove(player.userID);
}
private void OnNewSave(string filename) {
_playerDataLimits.Players.Clear();
_playerDataCooldowns.Clear();
}
private const string CategoryLayer = "CATEGORY_LAYER";
private static Dictionary<string, string> _imageList = new Dictionary<string, string> {
["0"]
= "https://gspics.org/images/2024/06/30/0z0dgL.png", ["1"] = "https://i.ibb.co/pzTNbwt/J5WoK4d.png", ["2"] = "https://i.ibb.co/mqrck03/ZR7bbZm.png", ["3"] = "https://i.ibb.co/PFB7390/lariGpB.png", ["4"] = "https://i.ibb.co/qgLpYq3/jjEsmL5.png", ["5"] = "https://i.ibb.co/M1HKWvd/jo3WN9H.png", ["6"] = "https://i.ibb.co/mF2ShwK/odqNSDS.png", ["7"] = "https://i.ibb.co/JCxP15p/xOWHmh0.png", ["8"] = "https://i.ibb.co/Tbg6B6w/4-33-16.png", ["9"] = "https://i.ibb.co/2gb5MZX/1544.png", ["10"] = "https://i.ibb.co/vc8mrkN/z88veYB.png", ["11"] = "https://i.ibb.co/0Zc09M3/yENDy73.png", ["12"] = "https://i.ibb.co/SBfKg7y/khOBy3x.png", ["13"] = "https://i.ibb.co/0F6VtZR/e0y4aM5.png", ["14"] = "https://i.ibb.co/nsJ2x7m/d5YRaLB.png", ["15"] = "https://i.ibb.co/KK7n7XM/eV9QUa0.png", ["16"] = "https://i.ibb.co/wC5cx5R/e0FCvGc.png", ["17"] = "https://i.ibb.co/gT5xYtz/Tbv05TC.png", ["18"] = "https://i.ibb.co/DtBBX4X/4-4.png", ["19"] = "https://i.ibb.co/9qGpNYS/12.png", ["20"] = "https://i.ibb.co/BnJCCqY/33324.png",
}
;
public static StringBuilder StringBuilderInstance;
private void OnLeaveNPC(BasePlayer npc, BasePlayer player) {
if (!_config.humanNpcs.NPCs.ContainsKey(npc.UserIDString)) return;
if (!_humanNpcPlayerOpen.ContainsKey(player.userID)) return;
_humanNpcPlayerOpen.Remove(player.userID);
if (_uiPlayerUseNow.Contains(player.userID)) _uiPlayerUseNow.Remove(player.userID);
CuiHelper.DestroyUi(player, "NOTIFICATION_POLOSA");
CuiHelper.DestroyUi(player, "NOTIFICATION_IMG");
CuiHelper.DestroyUi(player, "NOTIFICATION_TEXT");
CuiHelper.DestroyUi(player, NotificationMain);
CuiHelper.DestroyUi(player, MainLayer);
}
private string GetImage(string fileName, ulong skin = 0) {
string imageId = (string)plugins.Find("ImageLibrary").CallHook("GetImage", fileName, skin);
if (!string.IsNullOrEmpty(imageId)) return imageId;
return string.Empty;
}
private const string ConfirmationsPanelSelling = "CONFIRMATIONS_PANEL_SELLING";
private readonly List<ulong> _pdpw = new List<ulong>();
private Dictionary<ulong, ThemeType> _playerThemeSelect = new Dictionary<ulong, ThemeType>();
private void ValidateConfig() {
foreach (Configuration.CategoryShop category in _config.product) {
foreach (Configuration.CategoryShop.Product product in category.product) {
foreach (KeyValuePair<string, int> buyLimits in product.BuyLimits) if (!permission.PermissionExists(buyLimits.Key)) permission.RegisterPermission(buyLimits.Key, this);
foreach (KeyValuePair<string, int> buyLimitsWipe in product.BuyLimitsWipe) if (!permission.PermissionExists(buyLimitsWipe.Key)) permission.RegisterPermission(buyLimitsWipe.Key, this);
}
if (!permission.PermissionExists(category.PermissionCategory)) permission.RegisterPermission(category.PermissionCategory, this);
}
}
private void CheckingProducts() {
foreach (Configuration.CategoryShop category in _config.product) {
foreach (Configuration.CategoryShop.Product product in category.product) {
if (product.ID == 0) product.ID = Core.Random.Range(int.MinValue, int.MaxValue);
if (product.Type == ItemType.Item || product.Type == ItemType.Blueprint || product.Type == ItemType.CustomItem) {
product.Definition = ItemManager.FindItemDefinition(product.ShortName);
if (product.Definition == null) {
product.ItemsError = true;
PrintError(GetLang("TPShop_SERVICE_CONFIG_1", args : product.ID));
continue;
}
}
if (product.Price <= 0) {
product.ItemsError = true;
PrintError(GetLang("TPShop_SERVICE_CONFIG_2", args : product.ID));
}
}
}
}
private void UIMAIN(BasePlayer player, ThemeType themetype) {
Configuration.InterfaceSettings.ThemeCustomization theme = themetype == ThemeType.Dark ? _config.interfaceSettings.DarkTheme : _config.interfaceSettings.LightTheme;
float discount = GetUserDiscount(player);
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiElement {
Name = PanelProduct, Parent = ".Mains", Components = {
new CuiRawImageComponent {
Png = GetImage($"{Name}_" +"0"),
}
, new CuiRectTransformComponent {
AnchorMin = "-0.315 -0.27", AnchorMax = "1.3 1.275", OffsetMax = "0 0"
}
}
}
);
container.Add(new CuiButton {
Button = {
Color = "1 1 1 0", Command = "UI_HandlerShop CLOSE_ALL_UI"
}
, RectTransform = {
AnchorMin = "0.801 0.805", AnchorMax = "0.815 0.83"
}
}
, PanelProduct, "CLOSE_MENU_BTN");
if (_config.discountStores.DiscountPerm.Count != 0) {
container.Add(new CuiPanel {
CursorEnabled = false, Image = {
Color = "1 1 1 0"
}
, RectTransform = {
AnchorMin = "1 1", AnchorMax = "1 1", OffsetMin = "-283 -133", OffsetMax = "-231.91 -113.3"
}
}
, PanelProduct, "DISCOUNT_INFO");
}
CuiHelper.DestroyUi(player, PanelProduct);
CuiHelper.AddUi(player, container);
UIPRODUCT(player, themetype);
UICATEGORY(player, themetype);
}
private void SaveCooldowns() {
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Player_Cooldowns", _playerDataCooldowns);
}
private void OnPlayerConnected(BasePlayer player) {
if (!_playerThemeSelect.ContainsKey(player.userID)) {
_playerThemeSelect.Add(player.userID, _config.interfaceSettings.ThemeTypeDefault);
}
}
private void ThemeSwitch(BasePlayer player, ThemeType themetype) {
string img = themetype == ThemeType.Dark ? GetImage($"{Name}_" +"12") : GetImage($"{Name}_" +"11");
CuiElementContainer container = new CuiElementContainer {
new CuiElement {
Name = "THEME_BTN", Parent = PanelProduct, Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Png = img
}
, new CuiRectTransformComponent {
AnchorMin = "0 0", AnchorMax = "0 0", OffsetMin = "16.5 12.8", OffsetMax = "38.5 25.8"
}
}
}
, {
new CuiButton {
RectTransform = {
AnchorMin = "0 0", AnchorMax = "1 1"
}
, Button = {
Command = $"UI_HandlerShop THEME_SWITCH {themetype}", Color = "0 0 0 0"
}
, Text = {
Text = "",
}
}
, "THEME_BTN"
}
}
;
CuiHelper.DestroyUi(player, "THEME_BTN");
CuiHelper.AddUi(player, container);
}
protected override void LoadDefaultConfig() {
_config = new Configuration();
}
private List<int> GetStacks(ItemDefinition items, int amount) {
List<int> list = new List<int>();
int maxStack = items.stackable;
while (amount > maxStack) {
amount -= maxStack;
list.Add(maxStack);
}
list.Add(amount);
return list;
}
private class Items {
public string ShortName;
public string ENdisplayName;
public string RUdisplayName;
}
private void AddDisplayName() {
webrequest.Enqueue($"http://api.skyplugins.ru/api/getitemlist", "", (code, response) => {
if (code == 200) {
_itemList = JsonConvert.DeserializeObject<List<Items>>(response);
foreach (Items items in _itemList) {
_itemName.Add(items.ShortName, new ItemDisplayName {
ru = items.RUdisplayName, en = items.ENdisplayName, description = ItemManager.FindItemDefinition(items.ShortName)?.displayDescription?.english
}
);
}
}
else {
foreach (ItemDefinition item in ItemManager.itemList) {
_itemName.Add(item?.shortname, new ItemDisplayName {
ru = item.displayName?.english, en = item.displayName?.english, description = item.displayDescription?.english
}
);
}
}
}
, this);
}
private void LoadData() {
try {
_playerDataCooldowns = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerCooldown>>($"{Name}/Player_Cooldowns");
_playerDataLimits = Interface.Oxide.DataFileSystem.ReadObject<PlayerLimits>($"{Name}/Player_Limits");
_playerThemeSelect = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, ThemeType>>($"{Name}/Players");
}
catch (Exception e) {
PrintError(e.ToString());
}
if (_playerDataCooldowns == null) _playerDataCooldowns = new Dictionary<ulong, PlayerCooldown>();
if (_playerDataLimits == null) _playerDataLimits = new PlayerLimits();
if (_playerThemeSelect == null) _playerThemeSelect = new Dictionary<ulong, ThemeType>();
}
private PlayerCooldown GetCooldown(ulong player) {
PlayerCooldown cooldown;
return _playerDataCooldowns.TryGetValue(player, out cooldown) ? cooldown : null;
}
private readonly Dictionary<BasePlayer, Timer> PlayerTimer = new Dictionary<BasePlayer, Timer>();
private const string NotificationMain = "NOTIFICATION_MAIN";
private void RefillItems() {
_config.product.Clear();
if (_apiLoadImage != null) {
ServerMgr.Instance.StopCoroutine(_apiLoadImage);
_apiLoadImage = null;
}
Dictionary<string, List<ItemDefinition>> itemDefinitionsList = new Dictionary<string, List<ItemDefinition>>();
foreach (ItemDefinition itemDefinition in ItemManager.itemList) {
string categoryName = itemDefinition.category.ToString();
if (itemDefinitionsList.ContainsKey(categoryName)) itemDefinitionsList[categoryName].Add(itemDefinition);
else itemDefinitionsList.Add(categoryName, new List<ItemDefinition> {
itemDefinition
}
);
}
int itemId = 1;
foreach (KeyValuePair<string, List<ItemDefinition>> item in itemDefinitionsList) {
Configuration.CategoryShop category = new Configuration.CategoryShop {
CategoryName = item.Key, PermissionCategory = string.Empty, product = new List<Configuration.CategoryShop.Product>()
}
;
foreach (ItemDefinition itemDef in item.Value) {
if (_exclude.Contains(itemDef.shortname)) continue;
double itemPrice = ItemCostCalculator?.Call<double>("GetItemCost", itemDef) ?? 1;
category.product.Add(new Configuration.CategoryShop.Product {
Type = ItemType.Item, ID = itemId++, ShortName = itemDef.shortname, Descriptions = string.Empty, Price = (float)itemPrice, Amount = 1, Name = string.Empty, SkinID = 0, Commands = new List<string>(), Url = string.Empty, KitName = string.Empty, BuyCooldown = 0, BuyLimits = new Dictionary<string, int> {
["TPShop.default"]
= 10,
}
, BuyLimitsWipe = new Dictionary<string, int> {
["TPShop.default"]
= 100,
}
,
}
);
}
_config.product.Add(category);
}
SaveConfig();
PrintWarning(GetLang("TPShop_SERVICE_CMD_REFILL_SUCCESSFULLY"));
NextTick(() => {
Interface.Oxide.ReloadPlugin(Name);
}
);
}
private class PlayerCooldown {
[JsonProperty(PropertyName = "Player Limits", ObjectCreationHandling = ObjectCreationHandling.Replace)]
private readonly Dictionary<int, CooldownData> _itemsCooldowns = new Dictionary<int, CooldownData>();
private CooldownData GetCooldown(Configuration.CategoryShop.Product item) {
CooldownData data;
return _itemsCooldowns.TryGetValue(item.ID, out data) ? data : null;
}
public int GetCooldownTime(Configuration.CategoryShop.Product item, bool buy) {
CooldownData data = GetCooldown(item);
if (data == null) return -1;
return (int)((buy ? data.Buy : data.Sell).AddSeconds(item.BuyCooldown) - DateTime.Now).TotalSeconds;
}
public PlayerCooldown SetCooldown(Configuration.CategoryShop.Product item, bool buy) {
if (!_itemsCooldowns.ContainsKey(item.ID)) _itemsCooldowns.Add(item.ID, new CooldownData());
if (buy) _itemsCooldowns[item.ID].Buy = DateTime.Now;
else _itemsCooldowns[item.ID].Sell = DateTime.Now;
return this;
}
}
private void SubAndUnSubHumanNpcHook(bool sub = false) {
if (!sub) {
Unsubscribe(nameof(OnUseNPC));
Unsubscribe(nameof(OnLeaveNPC));
Unsubscribe(nameof(OnKillNPC));
}
else {
Subscribe(nameof(OnUseNPC));
Subscribe(nameof(OnLeaveNPC));
Subscribe(nameof(OnKillNPC));
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch {
for (int i = 0; i < 3; i++) PrintError("Configuration file is corrupt! Check your config file at https://jsonlint.com/");
LoadDefaultConfig();
}
ValidateConfig();
CheckOnDuplicates();
SaveConfig();
}
private enum ItemType {
Item, Blueprint, CustomItem, Command, Kit
}
private void SaveLimits() {
Interface.Oxide.DataFileSystem.WriteObject($"{Name}/Player_Limits", _playerDataLimits);
}
private static TPShop _instance;
[ConsoleCommand("UI_HandlerShop")]
private void CmdConsoleHandler(ConsoleSystem.Arg args) {
BasePlayer player = args.Player();
if (player == null || !args.HasArgs(1)) return;
switch (args.Args[0]) {
case "PAGE_CATEGORY" : {
int page = int.Parse(args.Args[1]);
ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[2]);
int category = int.Parse(args.Args[3]);
UICATEGORY(player, theme, page, category);
UIPRODUCT(player, theme, 0, category);
break;
}
case "CHANGE_CATEGORY" : {
int page = int.Parse(args.Args[1]);
int category = int.Parse(args.Args[2]);
ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[3]);
CuiHelper.DestroyUi(player, ConfirmationsPanel);
CuiHelper.DestroyUi(player, ConfirmationsPanelSelling);
UICATEGORY(player, theme, page, category);
UIPRODUCT(player, theme, 0, category);
break;
}
case "PAGE_PRODUCT" : {
int page = int.Parse(args.Args[1]);
int category = int.Parse(args.Args[2]);
ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[3]);
CuiHelper.DestroyUi(player, ConfirmationsPanel);
CuiHelper.DestroyUi(player, ConfirmationsPanelSelling);
UIPRODUCT(player, theme, page, category);
break;
}
case "PRODUCT_BUY_CONFIRMATION" : {
int indexItem = int.Parse(args.Args[1]);
int indexCategory = int.Parse(args.Args[2]);
int amount = int.Parse(args.Args[3]);
ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
CuiHelper.DestroyUi(player, ConfirmationsPanelSelling);
CONFIRMATIONSUI(player, indexItem, indexCategory, amount, theme);
break;
}
case "PRODUCT_BUY" : {
int indexItem = int.Parse(args.Args[1]);
int indexCategory = int.Parse(args.Args[2]);
int amount = int.Parse(args.Args[3]);
ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[4]);
Purchasing(player, indexItem, indexCategory, amount, theme);
CuiHelper.DestroyUi(player, ConfirmationsPanel);
break;
}
case "THEME_SWITCH" : {
ThemeType theme = (ThemeType)Enum.Parse(typeof(ThemeType), args.Args[1]);
UIMAIN(player, theme == ThemeType.Dark ? ThemeType.Light : ThemeType.Dark);
_playerThemeSelect[player.userID] = theme == ThemeType.Dark ? ThemeType.Light : ThemeType.Dark;
// ... [Code preview truncated due to length. Full source in attached file] ...