C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using Rust;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Oxide.Core.Libraries.Covalence;
using Steamworks;
using WebSocketSharp;
using Physics = UnityEngine.Physics;
/********************************************************
* Follow the status on https://trello.com/b/BCm6PUwK/guishop __φ(..)
* Credits to Nogrod and Reneb for the original plugin.<Versions up to 1.4.6
* Thanks! to Default for maintaining and adding in feature updates over the years.<versions 1.4.65 to 1.5.9
* Current Maintainer: 8/14/2020 Khan#8615 discord ID.1.6.0 to Present.* Imported Auto Config Updater by WhiteThunder! ◝(⁰▿⁰)◜
* Thanks to Baz/Hockeygel/Whispers/Mr.Blue
* -----------------------------------------------------------
* TODO:
* Add Theme Switcher
* Add BLuePrint Generation option
* Add TC or Backpack option to store custom currency (seeking alternative)..* Update all Language Translations
* Add support for Prerequisite item
* Add Vending Machine Support
*******************************************************/
/*****
* This release Update 2.1.0
* Added NPC Checks
* Updated to latest kits support but hook reversed back to default so was pointless
* Added missing message response
* Added Discord Embed Logging for Buy & Sell + Error logging
*
* This Update 2.2.0
* Added SkinID support to custom currency
* Added Custom Name support to custom currency
* Added Shop Permissions
* Slight Load Balance tweak to fix possible reload issues
* Added Per shop currency options/else uses global defaults.* Updated German Lang file (Delete only the old Germ Lang file optional)
* Added GetCurrency Hook
* Updated OpenShop Hook
*
* This Update 2.2.1
* Added Per Shop color options for both Display Name and Shop Descriptions
* Added GUIShop Display Button on Left side.(Feature Request)
* Added Button Permission
* Right side config setting option
* "Offsets Min": "185 18",
* "Offsets Max": "245 78",
*
* This Update 2.2.2
* Converted GUIShop Button to RGBA format Hex is glitched..*
* This Update 2.2.3
* Fixed Custom Items with Skin ID issues not being able to be sold.*
* This Update 2.2.31
* Fixed Custom Commands Issues
* Added Null checks for custom shop currency id's being blank or null to prevent item/money loss!
*
* This update 2.2.40
* Fully repaired ImageLibrary bugs
* SkinId support is working properly now for Imagelibrary
* Added Blueprint support for buy only! Cannot sell.* Added manual update command to update the Image URL links accordingly.* Update Command Requires Admin permission.is in game command only.* Updated All Lang files to fix the Coal item name typo..*
* This update 2.2.41
* Added null check for items that cannot be made a blueprint.*
* This update 2.2.42
* This update fixes ImageLibrary Error on server reboot.*
* This update 2.2.43
* Patches multi command
* Slightly changed discord embed messages to fix multi command issues
* Added discord Logging feature update to show the spawn cords
* Added Old config option back {1, 10, 100, 1000} now is a global default setting if none of the others are set.* Now supports decimal numbers for economics.0.33 etc
* Added Command and Custom Item Buy support as the same item with a true/false toggle.* Added Toggle for creating the custom items as there DisplayNames
*
* This update 2.2.44 beta update
* Added a cooldown setting to prevent players from being able to shop right away until x time has passed after each server wipe occurs.* Separated buy/sell all buttons into individual config toggle options.*
* This update 2.2.45 beta update
* Added Limiter Feature for Buy/Sell
* Both will be enabled by default so set to false if you don't want them on!
* If you set a cooldown on the item and a limit the cooldown will run each time -
- they buy an item same for the sell-side they are both separate
* This update 2.2.47 released.* Added a cooldown setting to prevent players from being able to shop right away until x time has passed after each server wipe occurs.* Separated buy/sell all buttons into individual config toggle options.* Added Limiter Feature for Buy/Sell
* Both will be enabled by default so set to false if you don't want them on!
* If you set a cooldown on the item and a limit the cooldown will run each time -
- they buy an item same for the sell-side they are both separate
* Added Buy/Sell Limit Reset CoolDown options
* Fixed BUY All button problem caused from update 2.0.10 ( 7 months ago ).* Added limits.clear Console Command Requires Admin permission ( for guishop ).* clears entire data file for limits ( includes coodlown timers )
* Added transactions.clear Console Command Requires Admin permission ( for guishop ).* clears entire data file for buy/sell cooldowns
* This update 2.2.48
* Fixed Sell All button issues relating to custom items with skinid's
* Added Support for multiple npc's to be assigned to shops.*
* This update 2.3.0 / Major HotFix Update!
* Fixed item leak when taking items from players
* Fixed Reloading issues where ram usage would keep being taken up from Image Library calls.* No longer uses //requires ( due to issues with it )
* Updated Currency Systems
* Created Whole new Item Creation methods
* Created Whole new Item Give methods
* Updated/re-wrote Get and Take Methods to include new feature support + fix old feature support checks
* Fixed issues with buying commands when inventory was full
* Fixed issues with buying items when command strings were not null but empty
* Fixed Custom Item names not being applied to items bought correctly
* Updated permission name error response to catch other plugins that improperly code..* Preparations for the new HumanNPC plugin in development finished
* Preparations for the Nomad Shop Plugin NPC done
* Added Requested Hooks
* Added Condition Level Support - Condition levels that default to 0 are not supported.* Added Allow Or Not Allow selling of used Items
* All items that are broken are no longer counted for selling in guishop!
* All items are preset to max default condition values.( changing these to 0 will result in items being bought as broken items )
* Updated Updater Command please run it in-game and make sure you have the guishop.admin perm! /update
* ( Updater command now only checks for any item condition set to 0 and will auto add the correct value for it if it supports conditions )
* Added a /resetconditions command for those that need to reset only item config conditions back to defaults.* Added Missing Sunglasses to item generation list
* Adding pooling for UI creation for better performance and faster page switching
* Added LangAPI translation support for all 30 langs!
* Added Russian support
* Updated/fixed all 10 language translations
* Fixed All Button Error Response issues / limit triggers
* Added Full genetics support fer buyin' plants & seeds.* Added missing lang responses
* Fixed GUIShop permission issues
*
* Update 2.3.1
* Fixed Player Message Response not showing relating to npcs and shop permissions.* Fixed Transparency changer buttons when using NPC shops
*
* Update 2.3.2
* Added New config option and increased Library check count to 15.* Fixed players currency money not showing correctly specific to custom currencies per shop.* performance update on get method /
* Fixed message response for custom currencies
*
* From version 2.3.2 to 2.3.15, The following issues have been fixed.Note: If you have not yet updated to 2.3.1 or higher you need to run the /update
* command in-game so that your configs get updated with the latest feature additions/requests.* Fixed Button Feature update.( Was missing a page sometimes )
* Substantially reduced Image Library load order times.* Added a new page switching feature the forward/back buttons will only show
if there is more than 1 page and if you are not on the last page.* Fixed Economics bug when trying to use 0.01 as a currency amount for selling.* Fixed an issue when buying if a player's inventory is full
it would send the message response saying your inventory is full, not enough space.But it would still take the money and not give them anything.* Resolves Custom Stack Size issues
* when using Stack Size Controller ( would end up with more )
* when using stack modifier ( would end up with less sometimes ) etc
* Fixed Another Possible Item Leak problem / ( if an item was not null but failed )
* Fixed shops set to use "custom" and a player attempts to buy something
with 0 scrap outputting wrong msg response.* Updated /shop-specific command checks, in regards to permission-based shops.* Code Cleanup.* Fixed an issue that occurs specifically with odd server stack sizes.* Relating to buying items in bulk, players would end up with 1 or two extra sometimes.( IDK how this didn't get reported months ago as an issue )
* Fixed selling for items with 100% condition and only = 1
Complete list from 2.2.48 to latest release of changes/repairs can be found here
https://umod.org/community/gui-shop/40000-2248-to-2315-update-notes
* This Update 2.3.16
* Updated to ignore 3rd party plugin npcs trying to access the shops.*
* Update 2.3.17
* Added auto wipe for data files on new map saves.( default is true )
* Added Experimental Economics support for beta update pending.*
* Update 2.3.18
* Updated TryGiveChecks work around for fixing snowmobiles not spawning via commands
*
* update 2.3.191
* Fixed limit count starting wrong
* Fixed A Currency Bug
* Fixed msg
*
* update 2.3.192
* Fixed selling items that had condition values below 80% not being able to be sold when enabled true.*
* Update 2.3.193
* Fixed items with custom skin ids not updating / showing correctly inside the UI!
*
* Update 2.4.0
* Now Using Native Facepunch logic for fetching default images + skins for shop items
* Only using ImageLibrary for very limited things
* Massive performance boost!
* Fixed Shop Color Changing / Transparency Changing Bugs not remembering your last Shop TAB
* Fixed Some Images Not updating in very special use cases
* Fixed Image Library not loading the order properly after a server restarts
* Improved Message response outputs in console when / if image library is being waited on/for.* Huge performance improvements for when you first load onto a server && when reloading the plugin
* No longer causes performance/lag spikes on high pop servers when re-loading
*
* Update 2.4.2
* Added /updateold ( in game chat command requires guishop.admin)
for really old configs that did not follow the old update notes from like 11months back??
* Fixed Default shop to open not being displayed correctly, and just opening the first shop in the list to show player.*
* Update 2.4.3
* Updated UI Display for Limit Counts so players can see the counter values change now
* Updated Config support scenarios to expand deeper scenario settings
* Updated Limits code to support new features
* Updated UI Systems for showing players by caching as much as possible
* UI System no longer constantly free's up the pooling resulting in the pool having to be re-created each time increasing garbage collections etc.* Higher Pop server should notice some more performance gains the most.*
* Update 2.4.4
* Added New Experimental Config Options SwapLimitToQuantityBuyLimit & SwapLimitToQuantitySoldLimit
* Toggling True results in buy quantities subtracting from the total Limit Count instead of subtracting 1
* Updated all cooldown logic & limits again
* Added Emergency Hotfix for F1 Commands exploit!
*
* Update 2.4.41
* Now Double Checks Data file systems on Load & Unload
* Now Properly Checks NPC Ranges for F1 commands on shops with only NPCs setup on them
* Now Properly Handles F1 Commands and respects shop categories settings + shop item settings
* F1 Buy / Sell All Functions are now blocked
* F1 transaction amount support can be specified by the player & respects the currency values
* F1 Transactions should properly reset cooldowns on items as well without having to open the UI
* If all global shops are disabled & players have GUIShop.Button perm it will no longer show
*
* update 2.4.42
* fixed /shop command erroring in console if all shop categories have been disabled.* Added New config toggle [JsonProperty("Shop - GUIShop Enable Background Image")]
public bool BackgroundImage = true;
* Added up to 16 shop tabs in a single row now & supports 2 rows now totalling 32 shops
*
* Update 2.4.43
* Fixed an issue with 2 config toggle settings relating to SR & E
* Updated UI System to support 2 more shop fields & cleaned up generation code a bit
* Added up to 17 shop tabs in a single row now & supports 2 rows now totalling 34! shops
* Couple minor bug fixes where for the shop was null in a weird use case.* Fixed a msg response saying bought 0 even though you got the items & it took the money properly.*
* Update 2.4.44
* Fixed GUIShop button & updated some text.*
* Update 2.4.45
* Performance Update
* Fixed /shop NRE
* Other Tweaks / Fixes in regards to giving out currency specifically
* Updated for Staging changes
*
* Update 2.4.46
* permission guishop.blockbypass is now only for global /shop's ( to shop while at monuments etc )
* Fixed NPC shops from not being excluded in CanBuild Checks.* Removed redundant checks in console commands.* Lets noescape handle blocking if installed.*
* Update 2.4.47
* Updated method name facepunch changed from FindItemsByItemName to FindItemByItemName.*/
namespace Oxide.Plugins {
[Info("GUIShop", "Khan", "2.4.48")]
[Description("GUI Shop Supports all known Currency, with NPC support - Re-Write Edition 2")]
public class GUIShop : RustPlugin {
#region References
[PluginReference]
Plugin Economics, Kits, ImageLibrary, ServerRewards, LangAPI;
#endregion
#region Fields
private bool _isRestart = true;
private bool _isShopReady;
private bool _isLangAPIReady;
private bool _isEconomicsLimits;
private bool _isEconomicsDebt;
private KeyValuePair<int, int> _balanceLimits;
private Dictionary<string, string> _imageListGUIShop;
private List<KeyValuePair<string, ulong>> _guishopItemIcons;
private const string GUIShopOverlayName = "GUIShopOverlay";
private const string GUIShopContentName = "GUIShopContent";
private const string GUIShopDescOverlay = "GUIShopDescOverlay";
private const string GUIShopColorPicker = "GUIShopColorPicker";
private const string BlockAllow = "guishop.blockbypass";
private const string Use = "guishop.use";
private const string Admin = "guishop.admin";
//private const string Vip = "guishop.vip";
private const string Color = "guishop.color";
private const string Button = "guishop.button";
private int _imageLibraryCheck = 0;
private Hash<ulong, int> _shopPage = new Hash<ulong, int>();
private Dictionary<ulong, Dictionary<string, double>> _sellCoolDownData;
private Dictionary<ulong, Dictionary<string, double>> _buyCooldownData;
private Dictionary<ulong, Dictionary<string, double>> _buyLimitResetCoolDownData;
private Dictionary<ulong, Dictionary<string, double>> _sellLimitResetCoolDownData;
private Dictionary<string, ulong> _boughtData;
private Dictionary<string, ulong> _soldData;
private Dictionary<ulong, ItemLimit> _limitsData;
readonly Dictionary<string, string> _headers = new Dictionary<string, string> {
{
"Content-Type", "application/json"
}
}
;
private List<MonumentInfo> _monuments => TerrainMeta.Path.Monuments;
private bool _configChanged;
private int playersMask = LayerMask.GetMask("Player (Server)");
//Caching Shop Images.private const string GUIShopWelcomeImage = "GUIShopWelcome";
private const string GUIShopBackgroundImage = "GUIShopBackground";
private const string GUIShopAmount1Image = "GUIShopAmount1";
private const string GUIShopAmount2Image = "GUIShopAmount2";
private const string GUIShopBuyImage = "GUIShopBuy";
private const string GUIShopSellImage = "GUIShopSell";
private const string GUIShopBackArrowImage = "GUIShopBackArrow";
private const string GUIShopForwardArrowImage = "GUIShopForwardArrow";
private const string GUIShopCloseImage = "GUIShopClose";
private const string GUIShopShopButton = "GUIShopButton";
//Auto Close
private HashSet<string> playerGUIShopUIOpen = new HashSet<string>();
private Dictionary<string, PlayerUISetting> _playerUIData;
private string _uiSettingChange = "Text";
private bool _imageChanger;
private double Transparency = 0.95;
private PluginConfig _config;
private static GUIShop _instance;
//Shop Button
private HashSet<string> _playerDisabledButtonData;
private readonly Dictionary<string, string> _corrections = new Dictionary<string, string> {
{
"sunglasses02black", "Sunglasses Style 2"
}
, {
"sunglasses02camo", "Sunglasses Camo"
}
, {
"sunglasses02red", "Sunglasses Red"
}
, {
"sunglasses03black", "Sunglasses Style 3"
}
, {
"sunglasses03chrome", "Sunglasses Chrome"
}
, {
"sunglasses03gold", "Sunglasses Gold"
}
, {
"twitchsunglasses", "Sunglasses Purple"
}
, {
"innertube", "Inner Tube"
}
, {
"innertube.horse", "Inner Tube Horse"
}
, {
"innertube.unicorn", "Inner Tube Unicorn"
}
,
}
;
#endregion
#region Config
private readonly HashSet<string> _exclude = new HashSet<string> {
"vehicle.chassis", "vehicle.module"
}
;
internal class PluginConfig : SerializableConfiguration {
[JsonProperty("Carefully Edit This")]
public CarefullyEdit Time = new CarefullyEdit();
[JsonProperty("Wipe GUIShop Data files on Map Changes / Server Wipes & if server save file is deleted")]
public bool AutoWipe = true;
[JsonProperty("Sets the ImageLibrary Counter Check ( Set higher if needed for server restarts )")]
public int ImageLibraryCounter = 15;
[JsonProperty("Enable Discord Buy Transaction Logging")]
public bool EnableDiscordLogging;
[JsonProperty("Enable Discord Sell Transaction Logging")]
public bool EnableDiscordSellLogging;
[JsonProperty("Discord Webhook URL")]
public string DiscordWebHookURL = "";
[JsonProperty("Discord Embed Color")]
public string DiscordColor = "#483D8B";
[JsonProperty("Discord Author Image")]
public string DiscordAuthorImage = "https://assets.umod.org/images/icons/plugin/5f80fe12851f5.png";
[JsonProperty("Discord Embed Icon")]
public string DiscordAuthorName = "GUIShop";
[JsonProperty("Set Default Global Shop to open")]
public string DefaultShop = "Commands";
[JsonProperty("Sets shop command")]
public string shopcommand = "shop";
[JsonProperty("Sets Vehicle Spawn Distance")]
public float SpawnDistance = 15f;
[JsonProperty("Switches to Economics as default curency")]
public bool Economics = true;
[JsonProperty("Switches to ServerRewards as default curency")]
public bool ServerRewards = false;
[JsonProperty("Switches to Custom as default curency")]
public bool CustomCurrency = false;
[JsonProperty("Allow Custom Currency Sell Of Used Items")]
public bool CustomCurrencyAllowSellOfUsedItems;
[JsonProperty("Custom Currency Item ID")]
public int CustomCurrencyID = -932201673;
[JsonProperty("Custom Currency Skin ID")]
public ulong CustomCurrencySkinID = 0;
[JsonProperty("Custom Currency Name")]
public string CustomCurrencyName = "";
[JsonProperty("Allows you to specify which containers you can sell items from")]
public InventoryTypes AllowedSellContainers = InventoryTypes.ContainerAll;
[JsonProperty("Enable Shop Buy All Button")]
public bool BuyAllButton = true;
[JsonProperty("Enable Shop Sell All Button")]
public bool SellAllButton = true;
[JsonProperty("Sets the buy/Sell button amounts + how many buttons")]
public int[] steps = {
1, 10, 100, 1000
}
;
[JsonProperty("Player UI display")]
public bool PersonalUI = false;
[JsonProperty("Block Monuments")]
public bool BlockMonuments = false;
[JsonProperty("If true = Images, If False = Text Labels")]
public bool UIImageOption = false;
[JsonProperty("NPC Distance Check")]
public float NPCDistanceCheck = 2.5f;
[JsonProperty("Enable NPC Auto Open")]
public bool NPCAutoOpen = false;
[JsonProperty("Enable GUIShop NPC Msg's")]
public bool NPCLeaveResponse = false;
[JsonProperty("GUI Shop - Welcome MSG")]
public string WelcomeMsg = "WELCOME TO GUISHOP ◝(⁰▿⁰)◜";
[JsonProperty("Shop - Buy Price Label")]
public string BuyLabel = "Buy Price";
[JsonProperty("Shop - Amount1 Label1")]
public string AmountLabel = "Amount";
[JsonProperty("Shop - Sell $ Label")]
public string SellLabel = "Sell $";
[JsonProperty("Shop - Amount2 Label2")]
public string AmountLabel2 = "Amount";
[JsonProperty("Shop - Back Button Text")]
public string BackButtonText = "<<";
[JsonProperty("Shop - Forward Button Text")]
public string ForwardButtonText = ">>";
[JsonProperty("Shop - Close Label")]
public string CloseButtonlabel = "CLOSE";
[JsonProperty("Shop - GUIShop Welcome Url")]
public string GuiShopWelcomeUrl = "https://i.imgur.com/RcLdEly.png";
[JsonProperty("Shop - GUIShop Enable Background Image")]
public bool BackgroundImage = true;
[JsonProperty("Shop - GUIShop Background Image Url")]
public string BackgroundUrl = "https://i.imgur.com/Jej3cwR.png";
[JsonProperty("Shop - Sets any shop items to this image if image link does not exist.")]
public string IconUrl = "https://imgur.com/BPM9UR4.png";
[JsonProperty("Shop - Shop Buy Icon Url")]
public string BuyIconUrl = "https://imgur.com/oeVUwCy.png";
[JsonProperty("Shop - Shop Amount Left Url")]
public string AmountUrl = "https://imgur.com/EKtvylU.png";
[JsonProperty("Shop - Shop Amount Right Url")]
public string AmountUrl2 = "https://imgur.com/EKtvylU.png";
[JsonProperty("Shop - Shop Sell Icon Url")]
public string SellIconUrl = "https://imgur.com/jV3hEHy.png";
[JsonProperty("Shop - Shop Back Arrow Url")]
public string BackButtonUrl = "https://imgur.com/zNKprM1.png";
[JsonProperty("Shop - Shop Forward Arrow Url")]
public string ForwardButtonUrl = "https://imgur.com/qx9syT5.png";
[JsonProperty("Shop - Close Image Url")]
public string CloseButton = "https://imgur.com/IK5yVrW.png";
[JsonProperty("Shop GUI Button")]
public GUIButton GUI = new GUIButton();
[JsonProperty("GUIShop Configurable UI colors (First 8 Colors!)")]
public HashSet<string> ColorsUI = new HashSet<string>();
[JsonProperty("Set Default Shop Buy Color")]
public string BuyColor = "#FFFFFF";
[JsonProperty("Set Default Shop Sell Color")]
public string SellColor = "#FFFFFF";
[JsonProperty("Set Default Shop Text Color")]
public string TextColor = "#FFFFFF";
[JsonProperty("Was Saved Don't Touch!")]
public bool WasSaved;
[JsonProperty("Shop - Shop Categories")]
public Dictionary<string, ShopCategory> ShopCategories = new Dictionary<string, ShopCategory>();
[JsonProperty("Shop - Shop List")]
public Dictionary<string, ShopItem> ShopItems = new Dictionary<string, ShopItem>();
public string ToJson() => JsonConvert.SerializeObject(this);
public Dictionary<string, object> ToDictionary() => JsonConvert.DeserializeObject<Dictionary<string, object>>(ToJson());
}
public class ShopItem {
public string DisplayName;
public bool CraftAsDisplayName = false;
public string Shortname;
public int ItemId;
public bool MakeBlueprint = false;
public bool AllowSellOfUsedItems = false;
public float Condition;
public bool EnableBuy = true;
public bool EnableSell = true;
public string Image = "";
public double SellPrice;
public double BuyPrice;
public int BuyCooldown;
public int SellCooldown;
public int[] BuyQuantity = {
}
;
public int[] SellQuantity = {
}
;
//public string Prerequisite;
public int BuyLimit = 0;
public int BuyLimitResetCoolDown = 0;
public bool SwapLimitToQuantityBuyLimit;
public int SellLimit = 0;
public int SellLimitResetCoolDown = 0;
public bool SwapLimitToQuantitySoldLimit;
public string KitName = "";
public List<string> Command = new List<string>();
public bool RunCommandAndCustomShopItem = false;
public List<char> GeneTypes = new List<char>();
public ulong SkinId;
public double GetSellPrice(string playerId="") {
var hook = Interface.CallHook("GUIShopSellPrice", JObject.FromObject(this), (string)playerId);
return hook != null ? (double)hook : SellPrice;
}
public double GetBuyPrice(string playerId="") {
var hook = Interface.CallHook("GUIShopBuyPrice", JObject.FromObject(this), (string)playerId);
return hook != null ? (double)hook : BuyPrice;
}
}
public class ShopCategory {
public string DisplayName;
public string DisplayNameColor = null;
public string Description;
public string DescriptionColor = null;
public string Permission = "";
[JsonIgnore]
public string PrefixPermission => "guishop." + Permission;
public string Currency = "";
public bool CustomCurrencyAllowSellOfUsedItems;
public string CustomCurrencyNames = "";
public int CustomCurrencyIDs = -0;
public ulong CustomCurrencySkinIDs = 0;
public bool EnabledCategory;
//public bool BluePrints;
public bool EnableNPC;
public string NPCId = "";
public List<string> NpcIds = new List<string>();
public HashSet<string> Items = new HashSet<string>();
[JsonIgnore]
public HashSet<ShopItem> ShopItems;
}
public class ItemLimit {
public Dictionary<string, int> BLimit = new Dictionary<string, int>();
public Dictionary<string, int> SLimit = new Dictionary<string, int>();
public bool CheckSellLimit(string item, int amount) {
if (!SLimit.ContainsKey(item)) {
SLimit[item] = 0;
}
return SLimit[item] >= amount;
}
public void IncrementSell(string item, int amount, bool toggle) {
if (!toggle) SLimit[item]++;
else SLimit[item] += amount;
}
public bool CheckBuyLimit(string item, int amount) {
if (!BLimit.ContainsKey(item)) {
BLimit[item] = 0;
}
return BLimit[item] >= amount;
}
public void IncrementBuy(string item, int amount, bool toggle) {
if (!toggle) BLimit[item]++;
else BLimit[item] += amount;
}
}
private class PlayerUISetting {
public double Transparency;
public string SellBoxColors;
public string BuyBoxColors;
public string UITextColor;
public double RangeValue;
public bool ImageOrText;
public string ShopKey;
}
public class GUIButton {
[JsonProperty(PropertyName = "Image")]
public string Image = "https://i.imgur.com/hc0qPet.png";
[JsonProperty(PropertyName = "Background color (RGBA format)")]
public string Color = "1 0.96 0.88 0.15";
[JsonProperty(PropertyName = "GUI Button Position")]
public Position GUIButtonPosition = new Position();
public class Position {
[JsonProperty(PropertyName = "Anchors Min")]
public string AnchorsMin = "0.5 0.0";
[JsonProperty(PropertyName = "Anchors Max")]
public string AnchorsMax = "0.5 0.0";
[JsonProperty(PropertyName = "Offsets Min")]
public string OffsetsMin = "-265 18";
[JsonProperty(PropertyName = "Offsets Max")]
public string OffsetsMax = "-205 78";
}
}
public class CarefullyEdit {
public string WipeTime = DateTime.Now.ToString("u");
public string LastWipe = DateTime.Now.ToString("u");
[JsonProperty("Sets time before shops can be used after the server wipes")]
public float CanShopIn = 300f;
}
private void CheckConfig() {
if (!_config.ShopCategories.ContainsKey("Commands")) {
_config.ShopCategories.Add("Commands", new ShopCategory {
DisplayName = "Commands", DisplayNameColor = null, Description = "You currently have {0} coins to spend in the commands shop", DescriptionColor = null, Permission = "", Currency = "", CustomCurrencyNames = "", CustomCurrencyIDs = -0, CustomCurrencySkinIDs = 0, EnabledCategory = true, //BluePrints = false
}
);
//_configChanged = true;
}
if (_config.ShopCategories.ContainsKey("Commands") && !_config.ShopItems.ContainsKey("Minicopter") && !_config.ShopItems.ContainsKey("Sedan") && !_config.ShopItems.ContainsKey("Airdrop Call")) {
_config.ShopItems.Add("Minicopter", new ShopItem {
DisplayName = "Minicopter", Shortname = "minicopter", CraftAsDisplayName = false, MakeBlueprint = false, EnableBuy = true, EnableSell = false, Image = "https://i.imgur.com/vI6LwCZ.png", Condition = 0, BuyPrice = 1.0, SellPrice = 1.0, BuyCooldown = 0, SellCooldown = 0, BuyQuantity = {
}
, SellQuantity = {
}
, BuyLimit = 0, BuyLimitResetCoolDown = 0, SellLimit = 0, SellLimitResetCoolDown = 0, KitName = "", Command = new List<string> {
"spawn minicopter \"$player.x $player.y $player.z\""
}
, RunCommandAndCustomShopItem = false, SkinId = 0,
}
);
_config.ShopItems.Add("Sedan", new ShopItem {
DisplayName = "Sedan", Shortname = "sedan", CraftAsDisplayName = false, MakeBlueprint = false, EnableBuy = true, EnableSell = false, Image = "", Condition = 0, BuyPrice = 1.0, SellPrice = 1.0, BuyCooldown = 0, SellCooldown = 0, BuyQuantity = {
}
, SellQuantity = {
}
, BuyLimit = 0, BuyLimitResetCoolDown = 0, SellLimit = 0, SellLimitResetCoolDown = 0, KitName = "", Command = new List<string> {
"spawn sedan \"$player.x $player.y $player.z\""
}
, RunCommandAndCustomShopItem = false, SkinId = 0,
}
);
_config.ShopItems.Add("Airdrop Call", new ShopItem {
DisplayName = "Airdrop Call", Shortname = "airdrop.call", ItemId = 1397052267, CraftAsDisplayName = false, MakeBlueprint = false, EnableBuy = true, EnableSell = false, Image = "", Condition = 0, BuyPrice = 1.0, SellPrice = 1.0, BuyCooldown = 0, SellCooldown = 0, BuyQuantity = {
}
, SellQuantity = {
}
, BuyLimit = 0, BuyLimitResetCoolDown = 0, SellLimit = 0, SellLimitResetCoolDown = 0, KitName = "", Command = new List<string> {
"inventory.giveto $player.id supply.signal"
}
, RunCommandAndCustomShopItem = false, SkinId = 0,
}
);
_config.ShopCategories["Commands"].Items.Add("Minicopter");
_config.ShopCategories["Commands"].Items.Add("Sedan");
_config.ShopCategories["Commands"].Items.Add("Airdrop Call");
}
foreach (var item in _config.ShopItems.Values) {
if (item.ItemId == 0 && !string.IsNullOrEmpty(item.Shortname) && ItemManager.FindItemDefinition(item.Shortname) != null) {
item.ItemId = ItemManager.FindItemDefinition(item.Shortname).itemid;
_configChanged = true;
}
}
foreach (ItemDefinition item in ItemManager.itemList) {
string categoryName = item.category.ToString();
ShopCategory shopCategory;
if (!_config.ShopCategories.TryGetValue(categoryName, out shopCategory)) {
_config.ShopCategories[categoryName] = shopCategory = new ShopCategory {
DisplayName = item.category.ToString(), DisplayNameColor = null, Description = "You currently have {0} coins to spend in the " + item.category + " shop", DescriptionColor = null, Permission = "", Currency = "", CustomCurrencyAllowSellOfUsedItems = false, CustomCurrencyNames = "", CustomCurrencyIDs = -0, CustomCurrencySkinIDs = 0, EnabledCategory = true, //BluePrints = false
}
;
//_configChanged = true;
}
string displayname = _corrections.ContainsKey(item.shortname) ? _corrections[item.shortname] : item.displayName.english;
if (_exclude.Contains(item.shortname)) continue;
if (!shopCategory.Items.Contains(displayname) && !_config.WasSaved) {
shopCategory.Items.Add(displayname);
_configChanged = true;
}
if (_config.ShopItems.ContainsKey(displayname) && _config.ShopItems[displayname].ItemId == 0) {
_config.ShopItems[displayname].ItemId = item.itemid;
_configChanged = true;
}
if (!_config.ShopItems.ContainsKey(displayname)) {
_config.ShopItems.Add(displayname, new ShopItem {
DisplayName = displayname, CraftAsDisplayName = false, Shortname = item.shortname, MakeBlueprint = false, AllowSellOfUsedItems = false, Condition = item.condition.max, EnableBuy = true, EnableSell = true, Image = "", BuyPrice = 1.0, SellPrice = 1.0, BuyCooldown = 0, SellCooldown = 0, BuyQuantity = {
}
, SellQuantity = {
}
, BuyLimit = 0, BuyLimitResetCoolDown = 0, SellLimit = 0, SellLimitResetCoolDown = 0, KitName = "", Command = new List<string>(), RunCommandAndCustomShopItem = false, SkinId = 0, // Image = "https://rustlabs.com/img/items180/" + item.shortname + ".png"
}
);
_configChanged = true;
}
}
if (_config.ColorsUI.Count <= 0) {
_config.ColorsUI = new HashSet<string> {
"#A569BD", "#2ECC71", "#E67E22", "#3498DB", "#E74C3C", "#F1C40F", "#F4F6F7", "#00FFFF"
}
;
}
foreach (var key in _config.ShopCategories.Values) {
if (!string.IsNullOrEmpty(key.NPCId)) {
if (!key.NpcIds.Contains(key.NPCId)) key.NpcIds.Add(key.NPCId);
PrintWarning($"Auto Moved, Warning! This config option is being removed soon do not use! NPCId");
key.NPCId = String.Empty;
_configChanged = true;
}
}
if (_configChanged) {
_config.WasSaved = true;
SaveConfig();
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<PluginConfig>();
if (_config == null) {
PrintToConsole($"Generating Config File for GUIShop");
throw new JsonException();
}
if (MaybeUpdateConfig(_config)) {
PrintWarning("Configuration appears to be outdated; updating and saving");
SaveConfig();
}
}
catch (Exception ex) {
PrintWarning("Failed to load config file (is the config file corrupt?) (" + ex.Message + ")");
}
}
protected override void LoadDefaultConfig() => _config = new PluginConfig();
protected override void SaveConfig() {
PrintToConsole($"Configuration changes saved to {Name}.json");
Config.WriteObject(_config, true);
}
#region Updater
internal class SerializableConfiguration {
public string ToJson() => JsonConvert.SerializeObject(this);
public Dictionary<string, object> ToDictionary() => JsonHelper.Deserialize(ToJson()) as Dictionary<string, object>;
}
private static class JsonHelper {
public static object Deserialize(string json) => ToObject(JToken.Parse(json));
private static object ToObject(JToken token) {
switch (token.Type) {
case JTokenType.Object : return token.Children<JProperty>().ToDictionary(prop => prop.Name, prop => ToObject(prop.Value));
case JTokenType.Array : return token.Select(ToObject).ToList();
default : return ((JValue) token).Value;
}
}
}
private bool MaybeUpdateConfig(SerializableConfiguration config) {
var currentWithDefaults = config.ToDictionary();
var currentRaw = Config.ToDictionary(x => x.Key, x => x.Value);
return MaybeUpdateConfigDict(currentWithDefaults, currentRaw);
}
private bool MaybeUpdateConfigDict(Dictionary<string, object> currentWithDefaults, Dictionary<string, object> currentRaw) {
bool changed = false;
foreach (var key in currentWithDefaults.Keys) {
object currentRawValue;
if (currentRaw.TryGetValue(key, out currentRawValue)) {
var defaultDictValue = currentWithDefaults[key] as Dictionary<string, object>;
var currentDictValue = currentRawValue as Dictionary<string, object>;
if (defaultDictValue != null) {
if (currentDictValue == null) {
currentRaw[key] = currentWithDefaults[key];
changed = true;
}
else if (MaybeUpdateConfigDict(defaultDictValue, currentDictValue)) changed = true;
}
}
else {
currentRaw[key] = currentWithDefaults[key];
changed = true;
}
}
return changed;
}
#endregion
#endregion
#region Storage
private void LoadData() {
try {
_buyCooldownData = _buyCoolDowns.ReadObject<Dictionary<ulong, Dictionary<string, double>>>();
}
catch {
_buyCooldownData = new Dictionary<ulong, Dictionary<string, double>>();
}
try {
_sellCoolDownData = _sellCoolDowns.ReadObject<Dictionary<ulong, Dictionary<string, double>>>();
}
catch {
_sellCoolDownData = new Dictionary<ulong, Dictionary<string, double>>();
}
try {
_buyLimitResetCoolDownData = _buyLimitResetCoolDowns.ReadObject<Dictionary<ulong, Dictionary<string, double>>>();
}
catch {
_buyLimitResetCoolDownData = new Dictionary<ulong, Dictionary<string, double>>();
}
try {
_sellLimitResetCoolDownData = _sellLimitResetCoolDowns.ReadObject<Dictionary<ulong, Dictionary<string, double>>>();
}
catch {
_sellLimitResetCoolDownData = new Dictionary<ulong, Dictionary<string, double>>();
}
try {
_boughtData = _bought.ReadObject<Dictionary<string, ulong>>();
}
catch {
_boughtData = new Dictionary<string, ulong>();
}
try {
_soldData = _sold.ReadObject<Dictionary<string, ulong>>();
}
catch {
_soldData = new Dictionary<string, ulong>();
}
try {
_limitsData = _limits.ReadObject<Dictionary<ulong, ItemLimit>>();
}
catch {
_limitsData = new Dictionary<ulong, ItemLimit>();
}
try {
_playerUIData = _playerData.ReadObject<Dictionary<string, PlayerUISetting>>();
}
catch {
_playerUIData = new Dictionary<string, PlayerUISetting>();
}
try {
_playerDisabledButtonData = _buttonData.ReadObject<HashSet<string>>();
}
catch {
_playerDisabledButtonData = new HashSet<string>();
}
}
private void SaveData() {
_buyCoolDowns.WriteObject(_buyCooldownData);
_sellCoolDowns.WriteObject(_sellCoolDownData);
_buyLimitResetCoolDowns.WriteObject(_buyLimitResetCoolDownData);
_sellLimitResetCoolDowns.WriteObject(_sellLimitResetCoolDownData);
_bought.WriteObject(_boughtData);
_sold.WriteObject(_soldData);
_limits.WriteObject(_limitsData);
_playerData.WriteObject(_playerUIData);
_buttonData.WriteObject(_playerDisabledButtonData);
}
#endregion
#region Lang File Messages
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
{
"ShopInvalid", "This is not a shop <color=#32CD32>{0}</color> update default shop setting!\nAvailable Shops are:\n{1}"
}
, {
"Economics", "GUIShop did not recieve a response from the Economics plugin.Please ensure the Economics plugin is installed correctly."
}
, {
"EconomicsMaxDebt", "Transaction declined you are already at max economics debt"
}
, {
"EconomicsExceedsDebt", "Transaction declined this would exceed max economics debt limit of {0}"
}
, {
"CustomInvalidID", "Custom currency ID is not valid please update config for this shop {0}"
}
, {
"MaxEconomicsBalance", "Transaction declined your already at max economics limit"
}
, {
"EconomicsExceedsLimit", "Transaction declined this would exceed max earnable economics limit of {0}"
}
, {
"ServerRewards", "GUIShop did not recieve a response from the ServerRewards plugin.Please ensure the ServerRewards plugin is installed correctly."
}
, {
"TakeCurrency", "GUIShop has failed to take this currency upon purchase {0}"
}
, {
"Bought", "You've successfully bought {0} {1}."
}
, {
"Sold", "You've successfully sold {0} {1}."
}
, {
"Cooldown", "You can only purchase this item every {0} seconds."
}
, {
"InventoryFull", "Your inventory is full."
}
, {
"InventorySlots", "You need at least {0} free inventory slots."
}
, {
"ErrorShop", "There is something wrong with this shop.Please contact an admin."
}
, {
"GlobalShopsDisabled", "Global Shops are disabled.This server uses NPC vendors!"
}
, {
"DeniedActionInShop", "You are not allowed to {0} in this shop"
}
, {
"ShopItemItemInvalid", "WARNING: It seems like this sell item you have is not a valid item! Please contact an Admin!"
}
, {
"ItemNotValidbuy", "WARNING: It seems like it's not a valid item to buy, Please contact an Admin!"
}
, {
"ItemNotValidsell", "WARNING: It seems like it's not a valid item to sell, Please contact an Admin!"
}
, {
"RedeemKitFail", "WARNING: There was an error while giving you this kit, Please contact an Admin!"
}
, {
"NotKit", "
// ... [Code preview truncated due to length. Full source in attached file] ...