C#:
//#define TESTING
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;
using Facepunch;
using Facepunch.Extend;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Plugins.ShopExtensionMethods;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Random = UnityEngine.Random;
namespace Oxide.Plugins {
[Info("Shop", "Mevent", "1.2.26")]
public class Shop : RustPlugin {
#region Fields
[PluginReference]
private Plugin ImageLibrary = null, ItemCostCalculator = null, Notify = null, UINotify = null, NoEscape = null, Duel = null, Duelist = null;
private static Shop _instance;
private bool _enabledImageLibrary;
private readonly Dictionary<int, ShopItem> _shopItems = new Dictionary<int, ShopItem>();
private readonly Dictionary<BasePlayer, Coroutine> _coroutines = new Dictionary<BasePlayer, Coroutine>();
private readonly Dictionary<string, List<KeyValuePair<int, string>>> _itemsCategories = new Dictionary<string, List<KeyValuePair<int, string>>>();
private readonly List<string> _images = new List<string>();
private List<ulong> _openedUI = new List<ulong>();
private const string Layer = "UI.Shop";
private const string ModalLayer = "UI.Shop.Modal";
private const string EditingLayer = "UI.Shop.Editing";
private const string PermAdmin = "Shop.admin";
private const string PermFreeBypass = "Shop.free";
private const string PermSetVM = "Shop.setvm";
private const string PermSetNPC = "Shop.setnpc";
private const int _itemsPerTick = 10;
private readonly Dictionary<ulong, DataCart> _carts = new Dictionary<ulong, DataCart>();
private readonly Dictionary<ulong, Dictionary<string, DataCart>> _cartsNPC = new Dictionary<ulong, Dictionary<string, DataCart>>();
private readonly Dictionary<ulong, NPCShop> _openedShops = new Dictionary<ulong, NPCShop>();
private readonly Dictionary<ulong, Dictionary<string, object>> _itemEditing = new Dictionary<ulong, Dictionary<string, object>>();
private const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
private readonly Dictionary<ulong, Dictionary<string, object>> _categoryEditing = new Dictionary<ulong, Dictionary<string, object>>();
private Timer _updateController;
private readonly List<ulong> _showAllCategories = new List<ulong>();
#endregion
#region Colors
private string _firstColor;
private string _secondColor;
private string _thirdColor;
private string _fourthColor;
private string _fifthColor;
private string _sixthColor;
private string _seventhColor;
#endregion
#region Config
private static Configuration _config;
private class Configuration {
#region Fields
[JsonProperty(PropertyName = "Commands", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public string[] Commands = {
"shop", "shops"
}
;
[JsonProperty(PropertyName = "Enable money transfers between players??")]
public bool Transfer = true;
[JsonProperty(PropertyName = "Enable logging to the console?")]
public bool LogToConsole = true;
[JsonProperty(PropertyName = "Enable logging to the file?")]
public bool LogToFile = true;
[JsonProperty(PropertyName = "Load images when logging into the server?")]
public bool LoginImages = true;
[JsonProperty(PropertyName = "Work with Notify?")]
public bool UseNotify = true;
[JsonProperty(PropertyName = "Can admins edit? (by flag)")]
public bool FlagAdmin = true;
[JsonProperty(PropertyName = "Block (NoEscape)")]
public bool BlockNoEscape = false;
[JsonProperty(PropertyName = "Wipe Block")]
public bool WipeCooldown = false;
[JsonProperty(PropertyName = "Wipe Cooldown")]
public float WipeCooldownTimer = 3600;
[JsonProperty(PropertyName = "Respawn Block")]
public bool RespawnCooldown = true;
[JsonProperty(PropertyName = "Respawn Cooldown")]
public float RespawnCooldownTimer = 60;
[JsonProperty(PropertyName = "Blocking the opening in duels?")]
public bool UseDuels = false;
[JsonProperty(PropertyName = "Delay between loading images")]
public float ImagesDelay = 1f;
[JsonProperty(PropertyName = "Economy")]
public EconomyConf Economy = new EconomyConf {
Type = EconomyType.Plugin, AddHook = "Deposit", BalanceHook = "Balance", RemoveHook = "Withdraw", Plug = "Economics", ShortName = "scrap", DisplayName = string.Empty, Skin = 0, TitleLangKey = "LangTitle", BalanceLangKey = "BalanceTitle"
}
;
[JsonProperty(PropertyName = "Additional Economics", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<AdditionalEconomy> AdditionalEconomics = new List<AdditionalEconomy> {
new AdditionalEconomy {
ID = 1, Enabled = true, Type = EconomyType.Plugin, AddHook = "AddPoints", BalanceHook = "CheckPoints", RemoveHook = "TakePoints", Plug = "ServerRewards", ShortName = "scrap", DisplayName = string.Empty, Skin = 0, TitleLangKey = "sr_title", BalanceLangKey = "sr_balance"
}
}
;
[JsonProperty(PropertyName = "Shop", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ShopCategory> Shop = new List<ShopCategory>();
[JsonProperty(PropertyName = "First Color")]
public string FirstColor = "#161617";
[JsonProperty(PropertyName = "Second Color")]
public string SecondColor = "#4B68FF";
[JsonProperty(PropertyName = "Third Color")]
public string ThirdColor = "#0E0E10";
[JsonProperty(PropertyName = "Fourth Color")]
public string FourthColor = "#A0A935";
[JsonProperty(PropertyName = "Fifth Color")]
public string FifthColor = "#FF4B4B";
[JsonProperty(PropertyName = "Sixth Color")]
public string SixthColor = "#324192";
[JsonProperty(PropertyName = "Seventh Color")]
public string SeventhColor = "#CD3838";
[JsonProperty(PropertyName = "NPC Shops (NPC ID - shop categories)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, NPCShop> NPCs = new Dictionary<string, NPCShop> {
["1234567"]
= new NPCShop {
Permission = string.Empty, Shops = new List<string> {
"Tool", "Food"
}
}
, ["7654321"] = new NPCShop {
Permission = string.Empty, Shops = new List<string> {
"Weapon", "Ammunition"
}
}
, ["4644687478"] = new NPCShop {
Permission = "shop.usenpc", Shops = new List<string> {
"*"
}
}
}
;
[JsonProperty(PropertyName = "Interface")]
public UserInterface UI = new UserInterface {
DisplayType = "Overlay", Width = 770, Height = 500, CategoriesOnString = 9, CategoriesMargin = 7.5f, CategoriesHeight = 40, ItemsOnString = 4, Strings = 2, ItemWidth = 150, ItemHeight = 165, Margin = 35, UseScrollCategories = true, EnableSearch = true, RoundDigits = 5, SelectCurrency = new SelectCurrencyUI {
Title = new LabelSettings {
Align = TextAnchor.MiddleCenter, Font = "robotocondensed-bold.ttf", FontSize = 14, Color = new IColor("#FFFFFF")
}
, TitlePosition = new InterfacePosition {
AnchorMin = "0 1", AnchorMax = "1 1", OffsetMin = "0 -30", OffsetMax = "0 0"
}
, EconomyTitle = new LabelSettings {
Align = TextAnchor.MiddleCenter, Font = "robotocondensed-regular.ttf", FontSize = 12, Color = new IColor("#FFFFFF")
}
, SelectedEconomyColor = new IColor("#4B68FF"), UnselectedEconomyColor = new IColor("#4B68FF", 33), EconomyWidth = 105f, EconomyHeight = 25f, EconomyMargin = 5f, EconomyIndent = 5f, FrameWidth = 10, FrameIndent = 15, FrameHeader = 35, CloseAfterChange = true
}
}
;
[JsonProperty(PropertyName = "Blocked skins for sell", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, List<ulong>> BlockedSkins = new Dictionary<string, List<ulong>> {
["short name"]
= new List<ulong> {
52, 25
}
, ["short name 2"] = new List<ulong> {
52, 25
}
}
;
[JsonProperty(PropertyName = "Auto-Wipe Settings")]
public WipeSettings Wipe = new WipeSettings {
Cooldown = true, Players = true, Limits = true
}
;
[JsonProperty(PropertyName = "Custom Vending Machines (Entity ID - settings)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<ulong, CustomVendingConf> CustomVending = new Dictionary<ulong, CustomVendingConf> {
[123343941]
= new CustomVendingConf {
Permission = string.Empty, Categories = new List<string> {
"Cars", "Misc"
}
}
}
;
[JsonProperty(PropertyName = "Settings available containers for selling item")]
public SellContainers SellContainers = new SellContainers {
Enabled = true, Containers = new List<string> {
"main", "belt"
}
}
;
[JsonProperty(PropertyName = "Buy Again Settings")]
public BuyAgainConf BuyAgain = new BuyAgainConf {
Enabled = false, Permission = string.Empty, Image = "assets/icons/history_servers.png"
}
;
public VersionNumber Version;
#endregion
#region Classes
public class BuyAgainConf {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Permission (ex: shop.buyagain)")]
public string Permission;
[JsonProperty(PropertyName = "Image")]
public string Image;
public bool HasAccess(BasePlayer player) {
return Enabled && (string.IsNullOrEmpty(Permission) || _instance.permission.UserHasPermission(player.UserIDString, Permission));
}
}
public enum SortType {
None, Name, Amount, PriceDecrease, PriceIncrease
}
#endregion
}
private class Localization {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Text (language - text)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, string> Messages = new Dictionary<string, string>();
public string GetMessage(BasePlayer player = null) {
if (Messages.Count == 0) throw new Exception("The use of localization is enabled, but there are no messages!");
var userLang = "en";
if (player != null) userLang = _instance.lang.GetLanguage(player.UserIDString);
string message;
if (Messages.TryGetValue(userLang, out message)) return message;
if (Messages.TryGetValue("en", out message)) return message;
return Messages.ElementAt(0).Value;
}
}
private class SellContainers {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Available Containers (main, belt, wear)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> Containers = new List<string>();
public List<ItemContainer> GetContainers(BasePlayer player) {
if (player == null || player.inventory == null) return new List<ItemContainer>();
var list = new List<ItemContainer>();
Containers.ForEach(cont => {
switch (cont) {
case "main" : {
list.Add(player.inventory.containerMain);
break;
}
case "belt" : {
list.Add(player.inventory.containerBelt);
break;
}
case "wear" : {
list.Add(player.inventory.containerWear);
break;
}
}
}
);
return list;
}
public Item[] AllItems(BasePlayer player) {
return GetContainers(player).SelectMany(cont => cont.itemList).ToArray();
}
}
private class SelectCurrencyUI {
[JsonProperty(PropertyName = "Title")]
public LabelSettings Title;
[JsonProperty(PropertyName = "Title Position")]
public InterfacePosition TitlePosition;
[JsonProperty(PropertyName = "Economy Title")]
public LabelSettings EconomyTitle;
[JsonProperty(PropertyName = "Selected Economy Color")]
public IColor SelectedEconomyColor;
[JsonProperty(PropertyName = "Unselected Economy Color")]
public IColor UnselectedEconomyColor;
[JsonProperty(PropertyName = "Economy Width")]
public float EconomyWidth;
[JsonProperty(PropertyName = "Economy Height")]
public float EconomyHeight;
[JsonProperty(PropertyName = "Economy Margin")]
public float EconomyMargin;
[JsonProperty(PropertyName = "Economy Indent")]
public float EconomyIndent;
[JsonProperty(PropertyName = "Frame Width")]
public float FrameWidth;
[JsonProperty(PropertyName = "Frame Indent")]
public float FrameIndent;
[JsonProperty(PropertyName = "Frame Header")]
public float FrameHeader;
[JsonProperty(PropertyName = "Close the menu after a currency change?")]
public bool CloseAfterChange;
}
private class InterfacePosition {
public string AnchorMin;
public string AnchorMax;
public string OffsetMin;
public string OffsetMax;
}
private class LabelSettings {
[JsonProperty(PropertyName = "FontSize")]
public int FontSize;
[JsonProperty(PropertyName = "Align")]
[JsonConverter(typeof(StringEnumConverter))]
public TextAnchor Align;
[JsonProperty(PropertyName = "Color")]
public IColor Color;
[JsonProperty(PropertyName = "Font")]
public string Font;
}
private class IColor {
[JsonProperty(PropertyName = "HEX")]
public string Hex;
[JsonProperty(PropertyName = "Opacity (0 - 100)")]
public float Alpha;
[JsonIgnore]
private string _color;
[JsonIgnore]
public string Get {
get {
if (string.IsNullOrEmpty(_color)) _color = GetColor();
return _color;
}
}
private string GetColor() {
if (string.IsNullOrEmpty(Hex)) Hex = "#FFFFFF";
var str = Hex.Trim('#');
if (str.Length != 6) throw new Exception(Hex);
var r = byte.Parse(str.Substring(0, 2), NumberStyles.HexNumber);
var g = byte.Parse(str.Substring(2, 2), NumberStyles.HexNumber);
var b = byte.Parse(str.Substring(4, 2), NumberStyles.HexNumber);
return $"{(double) r / 255} {(double) g / 255} {(double) b / 255} {Alpha / 100}";
}
public IColor() {
}
public IColor(string hex, float alpha = 100) {
Hex = hex;
Alpha = alpha;
}
}
private class CustomVendingConf {
[JsonProperty(PropertyName = "Permissions")]
public string Permission;
[JsonProperty(PropertyName = "Categories (Titles) [* - all]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> Categories;
}
private class WipeSettings {
[JsonProperty(PropertyName = "Wipe Cooldowns?")]
public bool Cooldown;
[JsonProperty(PropertyName = "Wipe Players?")]
public bool Players;
[JsonProperty(PropertyName = "Wipe Limits?")]
public bool Limits;
}
private class UserInterface {
[JsonProperty(PropertyName = "Display type (Overlay/Hud)")]
public string DisplayType;
[JsonProperty(PropertyName = "Height")]
public float Height;
[JsonProperty(PropertyName = "Width")]
public float Width;
[JsonProperty(PropertyName = "Categories On Page")]
public int CategoriesOnString;
[JsonProperty(PropertyName = "Categories Margin")]
public float CategoriesMargin;
[JsonProperty(PropertyName = "Categories Height")]
public float CategoriesHeight;
[JsonProperty(PropertyName = "Items On String")]
public int ItemsOnString;
[JsonProperty(PropertyName = "Strings")]
public int Strings;
[JsonProperty(PropertyName = "Item Height")]
public float ItemHeight;
[JsonProperty(PropertyName = "Item Width")]
public float ItemWidth;
[JsonProperty(PropertyName = "Margin")]
public float Margin;
[JsonProperty(PropertyName = "Use scroll in categories?")]
public bool UseScrollCategories;
[JsonProperty(PropertyName = "Enable search?")]
public bool EnableSearch;
[JsonProperty(PropertyName = "Number of digits after decimal point for rounding prices")]
public int RoundDigits;
[JsonProperty(PropertyName = "Select Currency Settings")]
public SelectCurrencyUI SelectCurrency;
}
private class NPCShop {
[JsonProperty(PropertyName = "Permission")]
public string Permission;
[JsonProperty(PropertyName = "Categories (Titles) [* - all]", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<string> Shops;
[JsonIgnore]
public string BotID;
}
private class ShopCategory : ICloneable, IDisposable {
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Title")]
public string Title;
[JsonProperty(PropertyName = "Permission")]
public string Permission;
[JsonProperty(PropertyName = "Sort Type")]
[JsonConverter(typeof(StringEnumConverter))]
[DefaultValue(Configuration.SortType.None)]
public Configuration.SortType SortType;
[JsonProperty(PropertyName = "Items", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ShopItem> Items;
[JsonProperty(PropertyName = "Localization")]
public Localization Localization;
public string GetTitle(BasePlayer player) {
if (Localization != null && Localization.Enabled) return Localization.GetMessage(player);
return Title;
}
[JsonIgnore]
private int _id = -1;
[JsonIgnore]
public int ID {
get {
if (_id == -1) _id = Random.Range(0, int.MaxValue);
return _id;
}
}
[JsonIgnore]
public List<ShopItem> SortedItems;
[JsonIgnore]
public List<ShopItem> GetItems {
get {
switch (SortType) {
case Configuration.SortType.None : return Items;
default : if (SortedItems == null) SortItems();
return SortedItems;
}
}
}
public void SortItems() {
switch (SortType) {
case Configuration.SortType.Name : {
SortedItems = Items.ToList();
SortedItems.Sort((x, y) => string.Compare(x.PublicTitle, y.PublicTitle, StringComparison.Ordinal));
break;
}
case Configuration.SortType.Amount : {
SortedItems = Items.ToList();
SortedItems.Sort((x, y) => x.Amount.CompareTo(y.Amount));
break;
}
case Configuration.SortType.PriceIncrease : {
SortedItems = Items.ToList();
SortedItems.Sort((x, y) => x.Amount.CompareTo(y.Price));
break;
}
case Configuration.SortType.PriceDecrease : {
SortedItems = Items.ToList();
SortedItems.Sort((x, y) => y.Amount.CompareTo(x.Price));
break;
}
default : {
SortedItems = Items.ToList();
break;
}
}
LoadIDs(true);
}
public void LoadIDs(bool sort = false) {
if (sort) Items.ForEach(item => _instance._shopItems.Remove(item.ID));
GetItems.ForEach(item => {
var id = item.ID;
if (_instance._shopItems.ContainsKey(item.ID)) id = _instance.GetId();
_instance._shopItems.Add(id, item);
if (item.Discount != null) foreach (var check in item.Discount) if (!string.IsNullOrEmpty(check.Key) && !_instance.permission.PermissionExists(check.Key)) _instance.permission.RegisterPermission(check.Key, _instance);
if (item.BuyCooldowns != null) foreach (var check in item.BuyCooldowns) if (!string.IsNullOrEmpty(check.Key) && !_instance.permission.PermissionExists(check.Key)) _instance.permission.RegisterPermission(check.Key, _instance);
if (item.SellCooldowns != null) foreach (var check in item.SellCooldowns) if (!string.IsNullOrEmpty(check.Key) && !_instance.permission.PermissionExists(check.Key)) _instance.permission.RegisterPermission(check.Key, _instance);
if (item.Type == ItemType.Item && item.Definition == null && !string.IsNullOrEmpty(item.ShortName)) item.Definition = !string.IsNullOrEmpty(item.ShortName) ? ItemManager.FindItemDefinition(item.ShortName) : null;
}
);
}
public object Clone() {
return MemberwiseClone();
}
public void Dispose() {
//null
}
}
private enum ItemType {
Item, Command, Plugin, Kit
}
private class ShopItem {
[JsonProperty(PropertyName = "Type")]
[JsonConverter(typeof(StringEnumConverter))]
public ItemType Type;
[JsonProperty(PropertyName = "ID")]
public int ID;
[JsonProperty(PropertyName = "Image")]
public string Image;
[JsonProperty(PropertyName = "Title")]
public string Title;
[JsonProperty(PropertyName = "Description")]
public string Description = string.Empty;
[JsonProperty(PropertyName = "Command (%steamid%)")]
public string Command;
[JsonProperty(PropertyName = "Kit")]
public string Kit = string.Empty;
[JsonProperty(PropertyName = "Plugin")]
public PluginItem Plugin;
[JsonProperty(PropertyName = "DisplayName (empty - default)")]
public string DisplayName;
[JsonProperty(PropertyName = "ShortName")]
public string ShortName;
[JsonProperty(PropertyName = "Skin")]
public ulong Skin;
[JsonProperty(PropertyName = "Is Blueprint")]
public bool Blueprint;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
[JsonProperty(PropertyName = "Enable item buying?")]
public bool CanBuy = true;
[JsonProperty(PropertyName = "Price")]
public double Price;
[JsonProperty(PropertyName = "Enable item selling?")]
public bool CanSell = true;
[JsonProperty(PropertyName = "Sell Price")]
public double SellPrice;
[JsonProperty(PropertyName = "Buy Cooldown (0 - disable)")]
public float BuyCooldown;
[JsonProperty(PropertyName = "Buy Cooldowns (0 - no limit)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> BuyCooldowns = new Dictionary<string, float>();
[JsonProperty(PropertyName = "Sell Cooldown (0 - disable)")]
public float SellCooldown;
[JsonProperty(PropertyName = "Sell Cooldowns (0 - no limit)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, float> SellCooldowns = new Dictionary<string, float>();
[JsonProperty(PropertyName = "Discount (%)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, int> Discount = new Dictionary<string, int>();
[JsonProperty(PropertyName = "Sell Limits (0 - no limit)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, int> SellLimits = new Dictionary<string, int>();
[JsonProperty(PropertyName = "Buy Limits (0 - no limit)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, int> BuyLimits = new Dictionary<string, int>();
[JsonProperty(PropertyName = "Daily Buy Limits (0 - no limit)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, int> DailyBuyLimits = new Dictionary<string, int>();
[JsonProperty(PropertyName = "Daily Sell Limits (0 - no limit)", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public Dictionary<string, int> DailySellLimits = new Dictionary<string, int>();
[JsonProperty(PropertyName = "Max Buy Amount (0 - disable)")]
public int BuyMaxAmount;
[JsonProperty(PropertyName = "Max Sell Amount (0 - disable)")]
public int SellMaxAmount;
[JsonProperty(PropertyName = "Force Buy")]
public bool ForceBuy;
[JsonProperty(PropertyName = "Prohibit splitting item into stacks?")]
public bool ProhibitSplit;
[JsonProperty(PropertyName = "Localization")]
public Localization Localization;
[JsonProperty(PropertyName = "Content")]
public ItemContent Content;
[JsonProperty(PropertyName = "Weapon")]
public ItemWeapon Weapon;
#region Utils
public float GetCooldown(string player, bool buy = true) {
var result = buy ? BuyCooldown : SellCooldown;
var dict = buy ? BuyCooldowns : SellCooldowns;
dict.Where(check => player.HasPermission(check.Key)).ForEach(check => {
if (check.Value < result) result = check.Value;
}
);
return result;
}
[JsonIgnore]
private int _itemId = -1;
[JsonIgnore]
public int itemId {
get {
if (_itemId == -1) _itemId = ItemManager.FindItemDefinition(ShortName)?.itemid ?? -1;
return _itemId;
}
}
[JsonIgnore]
private string _publicTitle;
[JsonIgnore]
public string PublicTitle {
get {
if (string.IsNullOrEmpty(_publicTitle)) _publicTitle = GetName();
return _publicTitle;
}
}
[JsonIgnore]
private ICuiComponent _image;
public CuiElement GetImage(string aMin, string aMax, string oMin, string oMax, string parent, string name = null) {
if (_image == null) {
if (_instance._enabledImageLibrary && !string.IsNullOrEmpty(Image)) _image = new CuiRawImageComponent {
Png = _instance.ImageLibrary.Call<string>("GetImage", Image)
}
;
else _image = new CuiImageComponent {
ItemId = itemId, SkinId = Skin
}
;
}
return new CuiElement {
Name = string.IsNullOrEmpty(name) ? CuiHelper.GetGuid() : name, Parent = parent, Components = {
_image, new CuiRectTransformComponent {
AnchorMin = aMin, AnchorMax = aMax, OffsetMin = oMin, OffsetMax = oMax
}
}
}
;
}
public string GetPublicTitle(BasePlayer player) {
if (Localization != null && Localization.Enabled) {
var msg = Localization.GetMessage(player);
if (!string.IsNullOrEmpty(msg)) return msg;
}
return GetName();
}
public string GetName() {
if (!string.IsNullOrEmpty(Title)) return Title;
if (!string.IsNullOrEmpty(DisplayName)) return DisplayName;
var def = ItemManager.FindItemDefinition(ShortName);
if (!string.IsNullOrEmpty(ShortName) && def != null) return def.displayName.translated;
return string.Empty;
}
[JsonIgnore]
public ItemDefinition Definition;
public Dictionary<string, object> ToDictionary() {
return new Dictionary<string, object> {
["Generated"]
= false, ["ID"] = ID, ["Type"] = Type, ["Image"] = Image, ["Title"] = Title, ["Command"] = Command, ["DisplayName"] = DisplayName, ["ShortName"] = ShortName, ["Skin"] = Skin, ["Blueprint"] = Blueprint, ["Buying"] = CanBuy, ["Selling"] = CanSell, ["Amount"] = Amount, ["Price"] = Price, ["SellPrice"] = SellPrice, ["Plugin_Hook"] = Plugin.Hook, ["Plugin_Name"] = Plugin.Plugin, ["Plugin_Amount"] = Plugin.Amount // ["Content_Enabled"] = Content?.Enabled ?? false,
// ["Weapon_Enabled"] = Weapon?.Enabled ?? false,
// ["Weapon_AmmoType"] = Weapon?.AmmoType ?? string.Empty,
// ["Weapon_AmmoAmount"] = Weapon?.AmmoAmount ?? 0
}
;
}
public double GetPrice(BasePlayer player) {
var discount = GetDiscount(player);
var price = Price;
return Math.Round(discount != 0 ? price * (1f - discount / 100f) : price, _config.UI.RoundDigits);
}
public int GetDiscount(BasePlayer player) {
var result = 0;
Discount.Where(check => player.HasPermission(check.Key)).ForEach(check => {
if (check.Value > result) result = check.Value;
}
);
return result;
}
public int GetLimit(BasePlayer player, bool buy = true, bool daily = false) {
var dict = daily ? buy ? DailyBuyLimits : DailySellLimits : buy ? BuyLimits : SellLimits;
if (dict.Count == 0) return 0;
var result = 0;
dict.Where(check => player.HasPermission(check.Key)).ForEach(check => {
if (check.Value > result) result = check.Value;
}
);
return result;
}
public void Get(BasePlayer player, int count = 1) {
switch (Type) {
case ItemType.Item : ToItem(player, count);
break;
case ItemType.Command : ToCommand(player, count);
break;
case ItemType.Plugin : Plugin.Get(player, count);
break;
case ItemType.Kit : ToKit(player, count);
break;
}
}
private void ToKit(BasePlayer player, int count) {
if (string.IsNullOrEmpty(Kit)) return;
for (var i = 0; i < count; i++) Interface.Oxide.CallHook("GiveKit", player, Kit);
}
[JsonIgnore]
private ItemDefinition _itemDefinition;
[JsonIgnore]
public ItemDefinition ItemDefinition {
get {
if (_itemDefinition == null) _itemDefinition = ItemManager.FindItemDefinition(ShortName);
return _itemDefinition;
}
}
private void ToItem(BasePlayer player, int count) {
if (ItemDefinition == null) {
Debug.LogError($"Error creating item with ShortName '{ShortName}'");
return;
}
if (Blueprint) {
GiveBlueprint(Amount * count, player);
}
else {
if (ProhibitSplit) GiveItem(Amount * count, player);
else GetStacks(count)?.ForEach(stack => GiveItem(stack, player));
}
}
private void GiveBlueprint(int count, BasePlayer player) {
for (var i = 0; i < count; i++) GiveBlueprint(player);
}
private void GiveBlueprint(BasePlayer player) {
var bp = ItemManager.CreateByName("blueprintbase");
if (bp == null) {
_instance?.PrintError("Error creating blueprintbase");
return;
}
bp.blueprintTarget = ItemManager.FindItemDefinition(ShortName).itemid;
if (!string.IsNullOrEmpty(DisplayName)) bp.name = DisplayName;
player.GiveItem(bp, BaseEntity.GiveItemReason.PickedUp);
}
private void GiveItem(int amount, BasePlayer player) {
var newItem = ItemManager.Create(ItemDefinition, amount, Skin);
if (newItem == null) {
_instance?.PrintError($"Error creating item with ShortName '{ShortName}'");
return;
}
if (!string.IsNullOrEmpty(DisplayName)) newItem.name = DisplayName;
if (Weapon != null && Weapon.Enabled) Weapon.Build(newItem);
if (Content != null && Content.Enabled) Content.Build(newItem);
player.GiveItem(newItem, BaseEntity.GiveItemReason.PickedUp);
}
private void ToCommand(BasePlayer player, int count) {
var pos = GetLookPoint(player);
for (var i = 0; i < count; i++) {
var command = Command.Replace("\n", "|").Replace("%steamid%", player.UserIDString, StringComparison.OrdinalIgnoreCase).Replace("%username%", player.displayName, StringComparison.OrdinalIgnoreCase).Replace("%player.z%", pos.z.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase).Replace("%player.x%", pos.x.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase).Replace("%player.y%", pos.y.ToString(CultureInfo.InvariantCulture), StringComparison.OrdinalIgnoreCase);
foreach (var check in command.Split('|')) if (check.Contains("chat.say")) {
var args = check.Split(' ');
player.SendConsoleCommand($"{args[0]} \" {string.Join(" ", args.ToList().GetRange(1, args.Length - 1))}\" 0");
}
else {
_instance?.Server.Command(check);
}
}
}
public List<int> GetStacks(int amount) {
amount *= Amount;
var maxStack = ItemDefinition.stackable;
var list = new List<int>();
if (maxStack == 0) maxStack = 1;
while (amount > maxStack) {
amount -= maxStack;
list.Add(maxStack);
}
list.Add(amount);
return list;
}
public override string ToString() {
switch (Type) {
case ItemType.Item : return $"[ITEM-{ID}] {ShortName}x{Amount}(DN: {DisplayName}, SKIN: {Skin})";
case ItemType.Command : return $"[COMMAND-{ID}] {Command}";
case ItemType.Plugin : return $"[PLUGIN-{ID}] Name: {Plugin?.Plugin}, Hook: {Plugin?.Hook}, Amount: {Plugin?.Amount ?? 0}";
case ItemType.Kit : return $"[KIT-{ID}] {Kit}";
default : return base.ToString();
}
}
#endregion
#region Constructor
public ShopItem() {
}
public ShopItem(Dictionary<string, object> dictionary) {
ID = (int) dictionary["ID"];
Type = (ItemType) dictionary["Type"];
Image = (string) dictionary["Image"];
Title = (string) dictionary["Title"];
Command = (string) dictionary["Command"];
DisplayName = (string) dictionary["DisplayName"];
ShortName = (string) dictionary["ShortName"];
Skin = (ulong) dictionary["Skin"];
Blueprint = (bool) dictionary["Blueprint"];
CanBuy = (bool) dictionary["Buying"];
CanSell = (bool) dictionary["Selling"];
Amount = (int) dictionary["Amount"];
Price = (double) dictionary["Price"];
SellPrice = (double) dictionary["SellPrice"];
Plugin = new PluginItem {
Hook = (string) dictionary["Plugin_Hook"], Plugin = (string) dictionary["Plugin_Name"], Amount = (int) dictionary["Plugin_Amount"]
}
;
Discount = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 10
}
;
SellLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
;
BuyLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
;
DailyBuyLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
;
DailySellLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
;
BuyCooldowns = new Dictionary<string, float> {
["shop.default"]
= 0f, ["shop.vip"] = 0f
}
;
SellCooldowns = new Dictionary<string, float> {
["shop.default"]
= 0f, ["shop.vip"] = 0f
}
;
Content = new ItemContent {
Enabled = false, Contents = new List<ItemContent.ContentInfo> {
new ItemContent.ContentInfo {
ShortName = string.Empty, Condition = 100, Amount = 1, Position = -1
}
}
}
;
Weapon = new ItemWeapon {
Enabled = false, AmmoType = string.Empty, AmmoAmount = 1
}
;
}
public static ShopItem GetDefault(int id, double itemCost, string shortName) {
return new ShopItem {
Type = ItemType.Item, ID = id, Price = itemCost, SellPrice = itemCost, Image = string.Empty, Title = string.Empty, Command = string.Empty, Plugin = new PluginItem(), DisplayName = string.Empty, ShortName = shortName, Skin = 0, Blueprint = false, Amount = 1, Discount = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 10
}
, SellLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
, BuyLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
, DailyBuyLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
, DailySellLimits = new Dictionary<string, int> {
["shop.default"]
= 0, ["shop.vip"] = 0
}
, BuyMaxAmount = 0, SellMaxAmount = 0, ForceBuy = false, ProhibitSplit = false, Localization = new Localization {
Enabled = false, Messages = new Dictionary<string, string> {
["en"]
= string.Empty, ["fr"] = string.Empty
}
}
, BuyCooldowns = new Dictionary<string, float> {
["shop.default"]
= 0f, ["shop.vip"] = 0f
}
, SellCooldowns = new Dictionary<string, float> {
["shop.default"]
= 0f, ["shop.vip"] = 0f
}
, Content = new ItemContent {
Enabled = false, Contents = new List<ItemContent.ContentInfo> {
new ItemContent.ContentInfo {
ShortName = string.Empty, Condition = 100, Amount = 1, Position = -1
}
}
}
, Weapon = new ItemWeapon {
Enabled = false, AmmoType = string.Empty, AmmoAmount = 1
}
}
;
}
#endregion
}
private class ItemContent {
#region Fields
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Contents", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<ContentInfo> Contents = new List<ContentInfo>();
#endregion
#region Utils
public void Build(Item item) {
Contents?.ForEach(content => content?.Build(item));
}
#endregion
#region Classes
public class ContentInfo {
[JsonProperty(PropertyName = "ShortName")]
public string ShortName;
[JsonProperty(PropertyName = "Condition")]
public float Condition;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
[JsonProperty(PropertyName = "Position")]
public int Position = -1;
#region Utils
public void Build(Item item) {
var content = ItemManager.CreateByName(ShortName, Mathf.Max(Amount, 1));
if (content == null) return;
content.condition = Condition;
content.MoveToContainer(item.contents, Position);
}
#endregion
}
#endregion
}
private class ItemWeapon {
#region Fields
[JsonProperty(PropertyName = "Enabled")]
public bool Enabled;
[JsonProperty(PropertyName = "Ammo Type")]
public string AmmoType;
[JsonProperty(PropertyName = "Ammo Amount")]
public int AmmoAmount;
#endregion
#region Utils
public void Build(Item item) {
var heldEntity = item.GetHeldEntity();
if (heldEntity != null) {
heldEntity.skinID = item.skin;
var baseProjectile = heldEntity as BaseProjectile;
if (baseProjectile != null && !string.IsNullOrEmpty(AmmoType)) {
baseProjectile.primaryMagazine.contents = Mathf.Max(AmmoAmount, 0);
baseProjectile.primaryMagazine.ammoType = ItemManager.FindItemDefinition(AmmoType);
}
heldEntity.SendNetworkUpdate();
}
}
#endregion
}
private class PluginItem {
[JsonProperty(PropertyName = "Hook")]
public string Hook = string.Empty;
[JsonProperty(PropertyName = "Plugin Name")]
public string Plugin = string.Empty;
[JsonProperty(PropertyName = "Amount")]
public int Amount;
public void Get(BasePlayer player, int count = 1) {
va
// ... [Code preview truncated due to length. Full source in attached file] ...