From 1a1b1bde879db2103c2192f6ccdace72f3daad7f Mon Sep 17 00:00:00 2001 From: OllieJW <71931263+OllieJW@users.noreply.github.com> Date: Mon, 12 Jul 2021 20:40:32 +0100 Subject: [PATCH] Added 2.0 files --- .../olliejw/oremarket/Chat/ValueUpdates.java | 44 ++++++++ .../olliejw/oremarket/Commands/Reload.java | 17 +++ .../oremarket/Listeners/InventoryEvents.java | 103 ++++++++++++++++++ .../java/com/olliejw/oremarket/OreMarket.java | 90 +++++++++++++++ .../com/olliejw/oremarket/Utils/AddItem.java | 80 ++++++++++++++ src/main/resources/config.yml | 22 ++++ src/main/resources/gui.yml | 67 ++++++++++++ src/main/resources/plugin.yml | 15 +++ 8 files changed, 438 insertions(+) create mode 100644 src/main/java/com/olliejw/oremarket/Chat/ValueUpdates.java create mode 100644 src/main/java/com/olliejw/oremarket/Commands/Reload.java create mode 100644 src/main/java/com/olliejw/oremarket/Listeners/InventoryEvents.java create mode 100644 src/main/java/com/olliejw/oremarket/OreMarket.java create mode 100644 src/main/java/com/olliejw/oremarket/Utils/AddItem.java create mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/gui.yml create mode 100644 src/main/resources/plugin.yml diff --git a/src/main/java/com/olliejw/oremarket/Chat/ValueUpdates.java b/src/main/java/com/olliejw/oremarket/Chat/ValueUpdates.java new file mode 100644 index 0000000..f228ccb --- /dev/null +++ b/src/main/java/com/olliejw/oremarket/Chat/ValueUpdates.java @@ -0,0 +1,44 @@ +package com.olliejw.oremarket.Chat; + +import com.olliejw.oremarket.OreMarket; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.ConfigurationSection; + +import java.text.DecimalFormat; +import java.text.Format; +import java.util.Objects; + +public class ValueUpdates { + public void announceValue() { + Bukkit.getScheduler().scheduleSyncRepeatingTask(OreMarket.main(), new Runnable() { + @Override + public void run() { + for (String oreItem : Objects.requireNonNull(OreMarket.main().getGuiConfig().getConfigurationSection("items")).getKeys(false)) { + ConfigurationSection keySection = Objects.requireNonNull(OreMarket.main().getGuiConfig().getConfigurationSection("items")).getConfigurationSection(oreItem); + + assert keySection != null; + String name = Objects.requireNonNull(keySection.getString("name")); + int stock = keySection.getInt("stock"); + double value = keySection.getDouble("value"); + double cost = keySection.getDouble("cost"); + double difference = (value-cost); + double change = (value/cost); + double percent = (change*100); + + final Format DECIMAL_FORMAT = new DecimalFormat("#0.0#"); + String format = ChatColor.translateAlternateColorCodes('&', Objects.requireNonNull(OreMarket.main().getConfig().getString("valueupdates.format")) + .replace("[name]", name) + .replace("[stock]", String.valueOf(stock)) + .replace("[value]", DECIMAL_FORMAT.format(value)) + .replace("[cost]", DECIMAL_FORMAT.format(cost)) + .replace("[change]", DECIMAL_FORMAT.format(difference)) + .replace("[percent]", DECIMAL_FORMAT.format(percent)) + ); + Bukkit.broadcastMessage(format); + } + + } + }, 0L, (OreMarket.main().getConfig().getInt("valueupdates.time")* 20L*60)); + } +} diff --git a/src/main/java/com/olliejw/oremarket/Commands/Reload.java b/src/main/java/com/olliejw/oremarket/Commands/Reload.java new file mode 100644 index 0000000..ef85c98 --- /dev/null +++ b/src/main/java/com/olliejw/oremarket/Commands/Reload.java @@ -0,0 +1,17 @@ +package com.olliejw.oremarket.Commands; + +import com.olliejw.oremarket.OreMarket; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class Reload implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + OreMarket.main().reloadConfig(); + sender.sendMessage(ChatColor.GREEN + "Reloaded successfully"); + return true; + } +} diff --git a/src/main/java/com/olliejw/oremarket/Listeners/InventoryEvents.java b/src/main/java/com/olliejw/oremarket/Listeners/InventoryEvents.java new file mode 100644 index 0000000..25cfbfa --- /dev/null +++ b/src/main/java/com/olliejw/oremarket/Listeners/InventoryEvents.java @@ -0,0 +1,103 @@ +package com.olliejw.oremarket.Listeners; + +import com.olliejw.oremarket.OreMarket; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.HumanEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; + +import java.util.Objects; + +public class InventoryEvents implements Listener { + + public void message (String Message, HumanEntity Player) { + Player.sendMessage(ChatColor.translateAlternateColorCodes('&', OreMarket.main().getConfig().getString("prefix") + Message)); + } + public void addMoney (double Money, HumanEntity Player) { // Sold + OreMarket.getEconomy().depositPlayer((OfflinePlayer) Player, Money); + } + public void takeMoney (double Money, HumanEntity Player) { // Buy + double tax = OreMarket.main().getConfig().getDouble("tax"); + double total = (Money + (Money/tax)); + OreMarket.getEconomy().withdrawPlayer((OfflinePlayer) Player, total); + } + public double balance (HumanEntity Player) { + return OreMarket.getEconomy().getBalance((OfflinePlayer) Player); + } + public void valueChange (int Slot, double Current, boolean Positive) { + double multiplier = OreMarket.main().getConfig().getDouble("multiplier"); + double currentIncrease = ((Current / 100.0) * (100 + multiplier)); + double currentDecrease = ((Current / 100.0) * (100 - multiplier)); + if (Positive) { + OreMarket.main().getGuiConfig().set("items." + Slot + ".value", currentIncrease); + } else { + OreMarket.main().getGuiConfig().set("items." + Slot + ".value", currentDecrease); + } + OreMarket.main().saveGuiConfig(); + } + public void stockChange (int Slot, int Current, int Amount, boolean Add) { + if (OreMarket.main().getGuiConfig().getDouble("items." + Slot + ".stock") == -1) { + return; + } + if (Add) { + OreMarket.main().getGuiConfig().set("items." + Slot + ".stock", Current + Amount); + } + else { + OreMarket.main().getGuiConfig().set("items." + Slot + ".stock", Current - Amount); + } + OreMarket.main().saveGuiConfig(); + } + + String title = ChatColor.translateAlternateColorCodes('&', Objects.requireNonNull(OreMarket.main().getGuiConfig().getString("gui.title"))); + + @EventHandler + public void clickEvent (InventoryClickEvent event) { + org.bukkit.inventory.Inventory playerInventory = event.getWhoClicked().getInventory(); // Player's inventory + InventoryView playerView = event.getView(); // Player's inventory view + HumanEntity player = event.getWhoClicked(); // Player that clicked + + if (event.getCurrentItem() == null) { return; } // Null check. Prevents errors + if (playerView.getTitle().equals(ChatColor.translateAlternateColorCodes('&', title))) { event.setCancelled(true); // I know. Its a bad way of checking. + double value = OreMarket.main().getGuiConfig().getDouble("items." + event.getSlot() + ".value"); // Ore Value + int stock = OreMarket.main().getGuiConfig().getInt("items." + event.getSlot() + ".stock"); // Ore stock + String itemConfig = OreMarket.main().getGuiConfig().getString("items." + event.getSlot() + ".item"); // Config location of item + assert itemConfig != null; + ItemStack clickedItem = new ItemStack(Objects.requireNonNull(Material.matchMaterial(itemConfig))); // Item that user clicked + + if (event.getClick() == ClickType.LEFT) { // Sell Mode + if (playerInventory.containsAtLeast(clickedItem, 1)) { + playerInventory.removeItem(clickedItem); + addMoney(value, player); + valueChange(event.getSlot(), value, true); + stockChange(event.getSlot(), stock, 1, true); + } + } + if (event.getClick() == ClickType.RIGHT) { // Buy Mode + if (balance(player) > value) { + if (stock > 1 || stock == -1) { if (value < 1) { return; } + playerInventory.addItem(clickedItem); + takeMoney(value, player); + valueChange(event.getSlot(), value, false); + stockChange(event.getSlot(), stock, 1, false); + } + } + } + } + } + + @EventHandler + public void moveEvent (InventoryDragEvent event) { + InventoryView playerView = event.getView(); // Player's inventory view + if (playerView.getTitle().equals(ChatColor.translateAlternateColorCodes('&', title))) { // Using our GUI + event.setCancelled(true); + } + } +} diff --git a/src/main/java/com/olliejw/oremarket/OreMarket.java b/src/main/java/com/olliejw/oremarket/OreMarket.java new file mode 100644 index 0000000..62dbd56 --- /dev/null +++ b/src/main/java/com/olliejw/oremarket/OreMarket.java @@ -0,0 +1,90 @@ +package com.olliejw.oremarket; + +import com.olliejw.oremarket.Chat.ValueUpdates; +import com.olliejw.oremarket.Commands.Reload; +import com.olliejw.oremarket.Listeners.InventoryEvents; +import com.olliejw.oremarket.Utils.AddItem; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.File; +import java.io.IOException; +import java.util.Objects; +import java.util.logging.Logger; + +public final class OreMarket extends JavaPlugin { + ValueUpdates valueUpdates = new ValueUpdates(); + private static OreMarket instance; + private static final Logger log = Logger.getLogger("Minecraft"); + private static Economy econ = null; + + private File guiFile; + private FileConfiguration guiConfig; + + public void onEnable() { + instance = this; + saveDefaultConfig(); + createGuiConfig(); + + this.getServer().getPluginManager().registerEvents(new InventoryEvents(), this); + Objects.requireNonNull(this.getCommand("openmarket")).setExecutor(new AddItem()); + Objects.requireNonNull(this.getCommand("om-reload")).setExecutor(new Reload()); + + if (!setupEconomy() ) { + log.severe(String.format("[%s] - Disabled due to no Vault dependency found!", getDescription().getName())); + getServer().getPluginManager().disablePlugin(this); + } + + valueUpdates.announceValue(); + } + + public FileConfiguration getGuiConfig() { + return this.guiConfig; + } + + private void createGuiConfig() { + guiFile = new File(getDataFolder(), "gui.yml"); + if (!guiFile.exists()) { + guiFile.getParentFile().mkdirs(); + saveResource("gui.yml", false); + } + + guiConfig = new YamlConfiguration(); + try { + guiConfig.load(guiFile); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + } + } + + public void saveGuiConfig() { + try { + guiConfig.save(guiFile); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static OreMarket main(){ + return instance; + } + private boolean setupEconomy() { + if (getServer().getPluginManager().getPlugin("Vault") == null) { + return false; + } + RegisteredServiceProvider rsp = getServer().getServicesManager().getRegistration(Economy.class); + if (rsp == null) { + return false; + } + econ = rsp.getProvider(); + return true; + } + public static Economy getEconomy() { + return econ; + } +} + diff --git a/src/main/java/com/olliejw/oremarket/Utils/AddItem.java b/src/main/java/com/olliejw/oremarket/Utils/AddItem.java new file mode 100644 index 0000000..1efffb9 --- /dev/null +++ b/src/main/java/com/olliejw/oremarket/Utils/AddItem.java @@ -0,0 +1,80 @@ +package com.olliejw.oremarket.Utils; + +import com.olliejw.oremarket.OreMarket; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.text.DecimalFormat; +import java.text.Format; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class AddItem implements Listener, CommandExecutor { + String title = OreMarket.main().getGuiConfig().getString("gui.title"); + int rows = OreMarket.main().getGuiConfig().getInt("gui.rows"); + Inventory inv = Bukkit.createInventory(null, rows*9, ChatColor.translateAlternateColorCodes('&', title)); + + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (command.getName().equalsIgnoreCase("openmarket")) { + Player player = (Player) sender; + + for (String key : Objects.requireNonNull(OreMarket.main().getGuiConfig().getConfigurationSection("items")).getKeys(false)) { + ConfigurationSection keySection = Objects.requireNonNull(OreMarket.main().getGuiConfig().getConfigurationSection("items")).getConfigurationSection(key); + + assert keySection != null; + int stock = keySection.getInt("stock"); + + final Format DECIMAL_FORMAT = new DecimalFormat("#0.0#"); + double value = keySection.getDouble("value"); + double cost = keySection.getDouble("cost"); + double change = (value/cost); + double percent = (change*100); + + ItemStack item = new ItemStack(Objects.requireNonNull(Material.matchMaterial(Objects.requireNonNull(keySection.getString("item"))))); + ItemMeta meta = item.getItemMeta(); + + assert meta != null; + meta.setDisplayName(ChatColor.translateAlternateColorCodes('&', Objects.requireNonNull(keySection.getString("name"))) + .replace("[stock]", DECIMAL_FORMAT.format(stock)) + .replace("[percent]", DECIMAL_FORMAT.format(percent)) + .replace("[value]", DECIMAL_FORMAT.format(value)) + .replace("[cost]", DECIMAL_FORMAT.format(cost)) + ); + + List lore = new ArrayList<>(); + for (String loreItem : Objects.requireNonNull(keySection.getStringList("lore"))) { + String string = ChatColor.translateAlternateColorCodes('&', loreItem) + .replace("[stock]", DECIMAL_FORMAT.format(stock)) + .replace("[percent]", DECIMAL_FORMAT.format(percent)) + .replace("[value]", DECIMAL_FORMAT.format(value)) + .replace("[cost]", DECIMAL_FORMAT.format(cost)) + ; + lore.add(string); + } + + meta.setLore(lore); + + item.setItemMeta(meta); + inv.setItem(Integer.parseInt(key), item); + player.openInventory(inv); + + + } + } + return true; + } +} + diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..9b83dcf --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,22 @@ +# Cost = Initial cost of ore. (0% change) +# Value = Current cost of ore. (With % change) +# When adding a new ore make the cost and value to same + +prefix: '&bOreMarket ' + +valueupdates: + # Time (in minutes) to send this message + time: 5 + # The below will look like: (These values are just examples) + # "Diamond is now valued at $500 ($250 / 200% change from the original $250). 100 left in stock!" + format: > + [name] is now valued at $[value] ($[change] / [percent]% change from the original [cost]). [stock] left in stock! + +# Tax (%) is added to every purchase and sale +tax: 10 + +# Multiplier (%) amount ore value changes. (Example: If it is 5 multiplier, Value would go from $1000 -> $1050 if sold, or $1000 -> $950 if bought) +# Depending on the popularity of your server, you may want to lower this +# Default: 0.01 (RECOMMENDED) +multiplier: 0.01 + diff --git a/src/main/resources/gui.yml b/src/main/resources/gui.yml new file mode 100644 index 0000000..22df21b --- /dev/null +++ b/src/main/resources/gui.yml @@ -0,0 +1,67 @@ +# Example Item +#0: +# # Item to be shown in the GUI and given/taken +# item: DIAMOND +# # Item name (Buying this ore will not give the user an ore with this name!) +# name: '&bDiamond Ore' +# # Lore (Infinite lines). Find the placeholders here -> https://github.com/OllieJW/Ore-Market/wiki/Placeholders +# lore: +# - '&aValue: $[value]' +# - '&aOriginal: $[cost]' +# - '&aStock: [stock]' +# - '&aChange: [percent]%' +# - '&7Right-Click to buy' +# - '&7Left-Click to sell' +# # Starting cost of ore +# cost: 1000 +# # Current cost of ore (Changing this will edit the GUI value) +# value: 1000 +# # Stock of the ore (Set to -1 for infinite) +# stock: 100 + + +gui: + title: '&6OreMarket' + rows: 3 + +items: + 0: + item: DIAMOND + name: '&bDiamond Ore' + lore: + - '&aValue: $[value]' + - '&aOriginal: $[cost]' + - '&aStock: [stock]' + - '&aChange: [percent]%' + - '&7Right-Click to buy' + - '&7Left-Click to sell' + cost: 1000 + value: 1000 + stock: 100 + 1: + item: GOLD_INGOT + name: '&6Gold Ingot' + lore: + - '&aValue: $[value]' + - '&aOriginal: $[cost]' + - '&aStock: [stock]' + - '&aChange: [percent]%' + - '&7Right-Click to buy' + - '&7Left-Click to sell' + cost: 500 + value: 500 + stock: 100 + + 2: + item: IRON_INGOT + name: '&7Iron Ore' + lore: + - '&aValue: $[value]' + - '&aOriginal: $[cost]' + - '&aStock: [stock]' + - '&aChange: [percent]%' + - '&7Right-Click to buy' + - '&7Left-Click to sell' + cost: 250 + value: 250 + stock: 100 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..53e1eb6 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,15 @@ +name: OreMarket +version: ${project.version} +main: com.olliejw.oremarket.OreMarket +api-version: 1.16 +depend: [ Vault ] +authors: [ OllieJW ] +description: Realistic stock market for ores + +commands: + openmarket: + description: Opens OreMarket GUI + usage: / + om-reload: + description: Reloads OreMarket + usage: / \ No newline at end of file