diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2e975ff
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/.classpath
+/.project
+/.settings
+/target
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..1b88a99
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,53 @@
+
+ 4.0.0
+ de.iani.cubeside
+ TreasureChest
+ 1.1
+
+ UTF-8
+ DEV
+
+
+
+ spigotmc-repo
+ https://hub.spigotmc.org/nexus/content/groups/public
+
+
+ vault-repo
+ http://nexus.hc.to/content/repositories/pub_releases
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.12-R0.1-SNAPSHOT
+ provided
+
+
+ de.iani.cubeside
+ PlayerUUIDCache
+ 1.4.0
+ provided
+
+
+ net.milkbowl.vault
+ VaultAPI
+ 1.6
+ provided
+
+
+
+
+
+ maven-compiler-plugin
+ 3.6.1
+
+
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/iani/treasurechest/ChestInventoryListener.java b/src/main/java/de/iani/treasurechest/ChestInventoryListener.java
new file mode 100644
index 0000000..139e2a2
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/ChestInventoryListener.java
@@ -0,0 +1,214 @@
+package de.iani.treasurechest;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Sound;
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.inventory.InventoryAction;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.event.inventory.InventoryCloseEvent;
+import org.bukkit.event.inventory.InventoryDragEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class ChestInventoryListener implements Listener {
+ private TreasureChest plugin;
+
+ HashMap openInventories = new HashMap();
+
+ public ChestInventoryListener(TreasureChest plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
+ public void onChestOpen(PlayerInteractEvent e) {
+ if (plugin.getChestLocation() == null) {
+ return;
+ }
+ Block b = e.getClickedBlock();
+ if (e.getAction() == Action.RIGHT_CLICK_BLOCK && b != null && b.getLocation().equals(plugin.getChestLocation())) {
+ e.setCancelled(true);
+ if (!e.getPlayer().hasPermission("pricechest.access")) {
+ plugin.sendMessage(e.getPlayer(), "Du hast keinen Zugriff auf die Schatztruhe!");
+ return;
+ }
+ if (openInventories.containsKey(e.getPlayer())) {
+ return;// ist schon offen?
+ }
+
+ PlayerTreasureChestContent content = plugin.getData().getChestContent(e.getPlayer().getUniqueId());
+ if (content == null || content.isEmpty()) {
+ plugin.sendMessage(e.getPlayer(), "Deine Schatztruhe ist leer!");
+ return;
+ }
+ Inventory inventory = plugin.getServer().createInventory(null, 9 * 6, "Schatztruhe");
+ OpenInventoryData openInventory = new OpenInventoryData(b.getLocation(), inventory);
+
+ int pos = 0;
+ for (TreasureChestItem item : content.getItems()) {
+ if (pos < 9 * 6) {
+ ItemStack di = item.getDisplayItem().clone();
+ ItemMeta meta = di.getItemMeta();
+ ItemStack[] priceList = item.getPriceItems();
+ ArrayList lore = new ArrayList<>();
+ if (priceList != null) {
+ for (ItemStack stack : priceList) {
+ StringBuilder t = new StringBuilder();
+ if (stack.getAmount() > 1) {
+ t.append(stack.getAmount()).append(" ");
+ }
+ t.append(TreasureChest.capitalize(stack.getType().name(), true));
+ if (stack.getDurability() > 0) {
+ t.append(':').append(stack.getDurability());
+ }
+ if (stack.getItemMeta().hasDisplayName()) {
+ t.append(" (benanntes Item)");
+ }
+ lore.add(t.toString());
+ }
+ }
+ if (item.getPriceMoney() > 0) {
+ lore.add(plugin.formatMoney(item.getPriceMoney()));
+ }
+ meta.setLore(lore);
+ di.setItemMeta(meta);
+ inventory.setItem(pos, di);
+ openInventory.setItemAtPosition(pos, pos);
+ }
+ pos += 1;
+ }
+
+ e.getPlayer().openInventory(inventory);
+ openInventories.put(e.getPlayer(), openInventory);
+ e.getPlayer().playSound(b.getLocation(), Sound.BLOCK_CHEST_OPEN, 0.5f, 0.9f);
+ }
+ }
+
+ @EventHandler(priority = EventPriority.HIGH)
+ public void onInventoryClick(InventoryClickEvent event) {
+ OpenInventoryData openInventory = openInventories.get(event.getWhoClicked());
+ if (openInventory == null) {
+ return;
+ }
+
+ InventoryAction action = event.getAction();
+ switch (action) {
+ case PICKUP_ALL:
+ case PICKUP_HALF:
+ case PICKUP_SOME:
+ case PICKUP_ONE: {
+ event.setCancelled(true);
+ if (event.getRawSlot() < event.getView().getTopInventory().getSize() && event.getWhoClicked() instanceof Player) {
+ Player player = (Player) event.getWhoClicked();
+
+ ItemStack[] playerInv = player.getInventory().getContents();
+ playerInv = Arrays.copyOf(playerInv, 36);
+ Inventory clonedPlayerInventory = Bukkit.createInventory(null, 36);
+ clonedPlayerInventory.setContents(playerInv);
+
+ PlayerTreasureChestContent content = plugin.getData().getChestContent(player.getUniqueId());
+ int entryId = openInventory.getEntryAtPosition(event.getRawSlot());
+ TreasureChestItem selectedItem = content.getItem(entryId);
+ if (selectedItem != null) {
+ ItemStack[] priceList = selectedItem.getPriceItems();
+ int priceCount = priceList == null ? 0 : priceList.length;
+ if (priceCount > 0) {
+ ItemStack[] temp = new ItemStack[priceCount];
+ for (int i = 0; i < priceCount; i++) {
+ temp[i] = priceList[i].clone();
+ }
+ if (!clonedPlayerInventory.addItem(temp).isEmpty()) {
+ plugin.sendMessage(player, "Du hast nicht genügend Platz in deinem Inventar!", true);
+ player.updateInventory();
+ return;
+ }
+ }
+ plugin.sendMessage(player, ChatColor.GRAY + "Hole Preis ab:");
+
+ if (priceCount > 0) {
+ ItemStack[] temp = new ItemStack[priceCount];
+ for (int i = 0; i < priceCount; i++) {
+ temp[i] = priceList[i].clone();
+ }
+ player.getInventory().addItem(temp);
+ for (ItemStack stack : priceList) {
+ StringBuilder t = new StringBuilder(" ");
+ if (stack.getAmount() > 1) {
+ t.append(stack.getAmount()).append(" ");
+ }
+ t.append(TreasureChest.capitalize(stack.getType().name(), true));
+ if (stack.getDurability() > 0) {
+ t.append(':').append(stack.getDurability());
+ }
+ ItemMeta meta = stack.getItemMeta();
+ if (meta.hasDisplayName()) {
+ t.append(" (").append(meta.getDisplayName()).append(ChatColor.YELLOW).append(")");
+ }
+ plugin.sendMessage(player, t.toString());
+ }
+ }
+ if (selectedItem.getPriceMoney() > 0) {
+ plugin.giveMoney(player, selectedItem.getPriceMoney());
+ plugin.sendMessage(player, " " + plugin.formatMoney(selectedItem.getPriceMoney()));
+ }
+
+ plugin.sendMessage(player, ChatColor.GRAY + "Du hast einen Preis abgeholt!");
+
+ player.playSound(event.getWhoClicked().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1f);
+ content.removeItem(entryId);
+ openInventory.getInventory().setItem(event.getRawSlot(), null);
+ openInventory.removeEntryAtPositionAndShift(event.getRawSlot());
+ player.updateInventory();
+ }
+ }
+ }
+ case CLONE_STACK:
+ case COLLECT_TO_CURSOR:
+ case DROP_ALL_CURSOR:
+ case DROP_ALL_SLOT:
+ case DROP_ONE_CURSOR:
+ case DROP_ONE_SLOT:
+ case HOTBAR_MOVE_AND_READD:
+ case HOTBAR_SWAP:
+ case UNKNOWN:
+ default: {
+ Player player = (Player) event.getWhoClicked();
+ player.updateInventory();
+ event.setCancelled(true);
+ return;
+ }
+ }
+ }
+
+ @EventHandler(priority = EventPriority.HIGH)
+ public void onInventoryDrag(InventoryDragEvent event) {
+ if (openInventories.containsKey(event.getWhoClicked())) {
+ event.setCancelled(true);
+ }
+ }
+
+ @EventHandler
+ public void onInventoryClose(InventoryCloseEvent e) {
+ OpenInventoryData data = openInventories.remove(e.getPlayer());
+ if (data != null) {
+ ((Player) e.getPlayer()).playSound(data.getLocation(), Sound.BLOCK_CHEST_CLOSE, 0.5f, 0.9f);
+ }
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ openInventories.remove(event.getPlayer());
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/OpenInventoryData.java b/src/main/java/de/iani/treasurechest/OpenInventoryData.java
new file mode 100644
index 0000000..2574f61
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/OpenInventoryData.java
@@ -0,0 +1,59 @@
+package de.iani.treasurechest;
+
+import org.bukkit.Location;
+import org.bukkit.inventory.Inventory;
+
+public class OpenInventoryData {
+ private Location location;
+
+ private Inventory inventory;
+
+ private int[] itemAtLocation;
+
+ public OpenInventoryData(Location location, Inventory inventory) {
+ this.location = location;
+ this.inventory = inventory;
+ }
+
+ public Inventory getInventory() {
+ return inventory;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public void setItemAtPosition(int inventoryPosition, int itemListPosition) {
+ if (itemAtLocation == null) {
+ itemAtLocation = new int[inventoryPosition + 1];
+ } else if (itemAtLocation.length <= inventoryPosition) {
+ int[] temp = itemAtLocation;
+ itemAtLocation = new int[inventoryPosition + 1];
+ System.arraycopy(temp, 0, itemAtLocation, 0, temp.length);
+ }
+ itemAtLocation[inventoryPosition] = itemListPosition + 1;
+ }
+
+ public int getEntryAtPosition(int inventoryPosition) {
+ if (itemAtLocation == null || itemAtLocation.length <= inventoryPosition || inventoryPosition < 0) {
+ return -1;
+ }
+ return itemAtLocation[inventoryPosition] - 1;
+ }
+
+ public void removeEntryAtPositionAndShift(int inventoryPosition) {
+ if (itemAtLocation == null || itemAtLocation.length <= inventoryPosition || inventoryPosition < 0) {
+ return;
+ }
+ int old = itemAtLocation[inventoryPosition];
+ if (old >= 0) {
+ itemAtLocation[inventoryPosition] = -1;
+ for (int i = 0; i < itemAtLocation.length; i++) {
+ int oldHere = itemAtLocation[i];
+ if (oldHere > old) {
+ itemAtLocation[i] = oldHere - 1;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/PlayerEventListener.java b/src/main/java/de/iani/treasurechest/PlayerEventListener.java
new file mode 100644
index 0000000..c4a6be1
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/PlayerEventListener.java
@@ -0,0 +1,19 @@
+package de.iani.treasurechest;
+
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+public class PlayerEventListener implements Listener {
+ private TreasureChest plugin;
+
+ public PlayerEventListener(TreasureChest plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ plugin.getData().removeActiveItem(event.getPlayer().getUniqueId());
+ }
+
+}
diff --git a/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java b/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java
new file mode 100644
index 0000000..0d9d715
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java
@@ -0,0 +1,137 @@
+package de.iani.treasurechest;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+public class PlayerTreasureChestContent {
+ private TreasureChest plugin;
+
+ private File file;
+
+ private ArrayList items;
+
+ private long online;
+
+ public PlayerTreasureChestContent(TreasureChest plugin, File file) {
+ this.plugin = plugin;
+ this.file = file;
+ try {
+ if (file.exists()) {
+ YamlConfiguration conf = YamlConfiguration.loadConfiguration(file);
+
+ ConfigurationSection prices = conf.getConfigurationSection("prices");
+ if (prices != null) {
+ for (String e : prices.getKeys(false)) {
+ ConfigurationSection price = prices.getConfigurationSection(e);
+ if (price != null) {
+ ItemStack display = price.getItemStack("displayItem");
+ if (display == null) {
+ display = new ItemStack(Material.BEDROCK);
+ ItemMeta meta = display.getItemMeta();
+ meta.setDisplayName("Unset displayitem");
+ display.setItemMeta(meta);
+ }
+ int priceMoney = price.getInt("priceMoney");
+ ArrayList priceItems = new ArrayList<>();
+ ConfigurationSection itemPricesSection = price.getConfigurationSection("itemPrices");
+ if (itemPricesSection != null) {
+ for (String pricee : itemPricesSection.getKeys(false)) {
+ ItemStack priceItem = itemPricesSection.getItemStack(pricee);
+ if (priceItem != null) {
+ priceItems.add(priceItem);
+ }
+ }
+ }
+ if (items == null) {
+ items = new ArrayList<>();
+ }
+ items.add(new TreasureChestItem(display, priceItems.toArray(new ItemStack[priceItems.size()]), priceMoney));
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ plugin.getLogger().log(Level.SEVERE, "Could not load user chest file: " + file.getName(), e);
+ }
+ }
+
+ private void save() {
+ file.getParentFile().mkdirs();
+ YamlConfiguration conf = new YamlConfiguration();
+ ConfigurationSection prices = conf.createSection("prices");
+ if (items != null) {
+ int nr = 0;
+ for (TreasureChestItem i : items) {
+ ConfigurationSection price = prices.createSection(Integer.toString(nr++));
+ price.set("displayItem", i.getDisplayItem().clone());
+ price.set("priceMoney", i.getPriceMoney());
+ ConfigurationSection itemsSec = price.createSection("itemPrices");
+ if (i.getPriceItems() != null) {
+ int nr2 = 0;
+ for (ItemStack st : i.getPriceItems()) {
+ itemsSec.set(Integer.toString(nr2++), st.clone());
+ }
+ }
+ }
+ }
+ try {
+ conf.save(file);
+ } catch (IOException e) {
+ plugin.getLogger().log(Level.SEVERE, "Could not save user chest file: " + file.getName(), e);
+ }
+ }
+
+ public void addItem(TreasureChestItem item) {
+ item = item.clone();
+ if (items == null) {
+ items = new ArrayList<>();
+ }
+ items.add(item);
+ save();
+ }
+
+ public boolean removeItem(int pos) {
+ if (items == null || items.size() <= pos || pos < 0) {
+ return false;
+ }
+ items.remove(pos);
+ if (items.size() == 0) {
+ items = null;
+ }
+ save();
+ return true;
+ }
+
+ public boolean isEmpty() {
+ return items == null || items.isEmpty();
+ }
+
+ public List getItems() {
+ return items == null ? Collections.EMPTY_LIST : Collections.unmodifiableList(items);
+ }
+
+ public TreasureChestItem getItem(int pos) {
+ if (items == null || items.size() <= pos || pos < 0) {
+ return null;
+ }
+ return items.get(pos);
+ }
+
+ public void setOnline(long t) {
+ online = t;
+ }
+
+ public boolean isOnline(long t) {
+ return online == t;
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/PriceChestCommandExecutor.java b/src/main/java/de/iani/treasurechest/PriceChestCommandExecutor.java
new file mode 100644
index 0000000..5e55480
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/PriceChestCommandExecutor.java
@@ -0,0 +1,261 @@
+package de.iani.treasurechest;
+
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Effect;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+
+import de.iani.playerUUIDCache.CachedPlayer;
+
+public class PriceChestCommandExecutor implements CommandExecutor {
+ private TreasureChest plugin;
+
+ public PriceChestCommandExecutor(TreasureChest plugin) {
+ this.plugin = plugin;
+ }
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (args.length == 0) {
+ displayHelp(sender, label);
+ } else {
+ String subcommand = args[0].toLowerCase();
+ if (subcommand.equals("setchest")) {
+ if (!checkPlayer(sender) || !checkPermission(sender, "pricechest.setchest")) {
+ return true;
+ }
+ Player player = ((Player) sender);
+ Block target = player.getTargetBlock((Set) null, 5);
+ plugin.setChestLocation(target.getLocation());
+ player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null);
+ player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null);
+ player.playEffect(target.getLocation(), Effect.MOBSPAWNER_FLAMES, null);
+ plugin.sendMessage(sender, "Treasurechest location set!");
+ } else if (subcommand.equals("create")) {
+ if (!checkPlayer(sender) || !checkPermission(sender, "pricechest.create")) {
+ return true;
+ }
+ Player player = ((Player) sender);
+ ItemStack inHand = player.getInventory().getItemInMainHand();
+ if (inHand == null || inHand.getType() == Material.AIR || inHand.getAmount() == 0) {
+ plugin.sendMessage(sender, "You have to hold the display item in hand!", true);
+ return true;
+ }
+ TreasureChestItem newItem = new TreasureChestItem(inHand.clone(), null, 0);
+ plugin.getData().setActiveItem(player.getUniqueId(), newItem);
+ plugin.sendMessage(sender, "Created a new Treasurechest item!");
+ } else if (subcommand.equals("addmoney")) {
+ if (!checkPlayer(sender) || !checkPermission(sender, "pricechest.create")) {
+ return true;
+ }
+ if (args.length < 2) {
+ plugin.sendMessage(sender, "/" + label + " addmoney ", true);
+ return true;
+ }
+ int amount = getIntArgument(args[1], 0);
+ Player player = ((Player) sender);
+ TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId());
+ if (activeItem == null) {
+ plugin.sendMessage(sender, "You have no active item!", true);
+ return true;
+ }
+ activeItem.setPriceMoney(activeItem.getPriceMoney() + amount);
+ plugin.sendMessage(sender, "Set the money to " + activeItem.getPriceMoney());
+ } else if (subcommand.equals("additem")) {
+ if (!checkPlayer(sender) || !checkPermission(sender, "pricechest.create")) {
+ return true;
+ }
+ Player player = ((Player) sender);
+ ItemStack inHand = player.getInventory().getItemInMainHand();
+ if (inHand == null || inHand.getType() == Material.AIR || inHand.getAmount() == 0) {
+ plugin.sendMessage(sender, "You have to hold the item in hand!", true);
+ return true;
+ }
+ TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId());
+ if (activeItem == null) {
+ plugin.sendMessage(sender, "You have no active item!", true);
+ return true;
+ }
+ activeItem.addPriceItem(inHand.clone());
+ plugin.sendMessage(sender, "Item added: " + inHand.getAmount() + " " + TreasureChest.capitalize(inHand.getType().name(), true));
+ } else if (subcommand.equals("give")) {
+ if (!checkPlayer(sender) || !checkPermission(sender, "pricechest.give")) {
+ return true;
+ }
+ if (args.length < 2) {
+ plugin.sendMessage(sender, "/" + label + " give ", true);
+ return true;
+ }
+ Player player = ((Player) sender);
+ TreasureChestItem activeItem = plugin.getData().getActiveItem(player.getUniqueId());
+ if (activeItem == null) {
+ plugin.sendMessage(sender, "You have no active item!", true);
+ return true;
+ }
+
+ for (int arg = 1; arg < args.length; arg++) {
+ String nameOrId = args[arg].replace(",", "").trim();
+ UUID targetuuid = null;
+ try {
+ targetuuid = UUID.fromString(nameOrId);
+ } catch (Exception e) {
+ CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(nameOrId, true);
+ if (target != null) {
+ targetuuid = target.getUUID();
+ nameOrId = target.getName();
+ }
+ }
+ if (targetuuid == null) {
+ plugin.sendMessage(sender, "Unknown player!", true);
+ } else {
+ PlayerTreasureChestContent content = plugin.getData().getChestContent(targetuuid);
+ content.addItem(activeItem);
+ plugin.sendMessage(sender, "Item given to: " + nameOrId + " (" + targetuuid.toString() + ")");
+ }
+ }
+ return true;
+ } else if (subcommand.equals("list")) {
+ if (!checkPermission(sender, "pricechest.list")) {
+ return true;
+ }
+ if (args.length < 2) {
+ plugin.sendMessage(sender, "/" + label + " list ", true);
+ return true;
+ }
+ String nameOrId = args[1];
+ UUID targetuuid = null;
+ try {
+ targetuuid = UUID.fromString(nameOrId);
+ } catch (Exception e) {
+ CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(nameOrId, true);
+ if (target != null) {
+ targetuuid = target.getUUID();
+ nameOrId = target.getName();
+ }
+ }
+ if (targetuuid == null) {
+ plugin.sendMessage(sender, "Unknown player!", true);
+ return true;
+ }
+
+ PlayerTreasureChestContent content = plugin.getData().getChestContent(targetuuid);
+ plugin.sendMessage(sender, ChatColor.GRAY + "Preise von " + nameOrId + " (" + targetuuid.toString() + "):");
+ List items = content.getItems();
+ if (items.isEmpty()) {
+ plugin.sendMessage(sender, "keine Preise vorhanden");
+ } else {
+ int nr = 1;
+ for (TreasureChestItem i : items) {
+ plugin.sendMessage(sender, nr + ": " + i.getDisplayItem().getItemMeta().getDisplayName());
+ nr++;
+ }
+ }
+ } else if (subcommand.equals("remove")) {
+ if (!checkPermission(sender, "pricechest.remove")) {
+ return true;
+ }
+ if (args.length < 3) {
+ plugin.sendMessage(sender, "/" + label + " remove ", true);
+ return true;
+ }
+
+ String nameOrId = args[1];
+ UUID targetuuid = null;
+ try {
+ targetuuid = UUID.fromString(nameOrId);
+ } catch (Exception e) {
+ CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(nameOrId, true);
+ if (target != null) {
+ targetuuid = target.getUUID();
+ nameOrId = target.getName();
+ }
+ }
+ if (targetuuid == null) {
+ plugin.sendMessage(sender, "Unknown player!", true);
+ return true;
+ }
+ int nr = getIntArgument(args[2], -1);
+ PlayerTreasureChestContent content = plugin.getData().getChestContent(targetuuid);
+ if (!content.removeItem(nr - 1)) {
+ plugin.sendMessage(sender, "Ungültige ID", true);
+ return true;
+ }
+ plugin.sendMessage(sender, "Der Preis wurde entfernt!");
+ } else {
+ plugin.sendMessage(sender, "Unknown subcommand!", true);
+ return true;
+ }
+ }
+ return true;
+ }
+
+ private void displayHelp(CommandSender sender, String label) {
+ plugin.sendMessage(sender, ChatColor.GREEN + "Commands");
+ if (checkPlayer(sender, true) && checkPermission(sender, "pricechest.setchest", true)) {
+ plugin.sendMessage(sender, "/" + label + " setchest");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Set the treasure chest location to the location you are looking at.");
+ }
+ if (checkPlayer(sender, true) && checkPermission(sender, "pricechest.create", true)) {
+ plugin.sendMessage(sender, "/" + label + " create");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Creates a price with the item in hand as display item.");
+ plugin.sendMessage(sender, "/" + label + " additem");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Adds the item in hand to the price.");
+ plugin.sendMessage(sender, "/" + label + " addmoney ");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Adds money to a price.");
+ }
+ if (checkPlayer(sender, true) && checkPermission(sender, "pricechest.give", true)) {
+ plugin.sendMessage(sender, "/" + label + " give ");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Gives a price to a player.");
+ }
+ if (checkPermission(sender, "pricechest.list")) {
+ plugin.sendMessage(sender, "/" + label + " list ");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Gives price for a player.");
+ }
+ if (checkPermission(sender, "pricechest.remove")) {
+ plugin.sendMessage(sender, "/" + label + " remove ");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Removes a price from a players chest.");
+ }
+ }
+
+ private int getIntArgument(String value, int defaultValue) {
+ try {
+ return Integer.parseInt(value);
+ } catch (Exception e) {
+ // ignore - return default
+ }
+ return defaultValue;
+ }
+
+ private boolean checkPermission(CommandSender sender, String perm) {
+ return checkPermission(sender, perm, false);
+ }
+
+ private boolean checkPermission(CommandSender sender, String perm, boolean silent) {
+ boolean hasPermission = sender.hasPermission(perm);
+ if (!silent && !hasPermission) {
+ plugin.sendMessage(sender, "No permission!", true);
+ }
+ return hasPermission;
+ }
+
+ private boolean checkPlayer(CommandSender sender) {
+ return checkPlayer(sender, false);
+ }
+
+ private boolean checkPlayer(CommandSender sender, boolean silent) {
+ boolean isPlayer = sender instanceof Player;
+ if (!isPlayer && !silent) {
+ plugin.sendMessage(sender, "You must be a player!", true);
+ }
+ return isPlayer;
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/PriceChestData.java b/src/main/java/de/iani/treasurechest/PriceChestData.java
new file mode 100644
index 0000000..1ba6432
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/PriceChestData.java
@@ -0,0 +1,84 @@
+package de.iani.treasurechest;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.UUID;
+
+import org.bukkit.entity.Player;
+
+public class PriceChestData {
+ private HashMap namedItems;
+
+ private HashMap activeItems;
+
+ private HashMap loadedChests;
+
+ private TreasureChest plugin;
+
+ private File chestContentFolder;
+
+ public PriceChestData(TreasureChest plugin) {
+ namedItems = new HashMap<>();
+ activeItems = new HashMap<>();
+ loadedChests = new HashMap<>();
+
+ this.plugin = plugin;
+ chestContentFolder = new File(this.plugin.getDataFolder(), "content");
+ chestContentFolder.mkdirs();
+ }
+
+ public TreasureChestItem getNamedItem(String name) {
+ return namedItems.get(name.toLowerCase().trim());
+ }
+
+ public TreasureChestItem getActiveItem(UUID playerUUID) {
+ return activeItems.get(playerUUID);
+ }
+
+ public TreasureChestItem setActiveItem(UUID playerUUID, TreasureChestItem item) {
+ if (item == null) {
+ return removeActiveItem(playerUUID);
+ }
+ return activeItems.put(playerUUID, item);
+ }
+
+ public TreasureChestItem removeActiveItem(UUID playerUUID) {
+ return activeItems.remove(playerUUID);
+ }
+
+ public PlayerTreasureChestContent getChestContentIfLoaded(UUID playerUUID) {
+ return loadedChests.get(playerUUID);
+ }
+
+ public PlayerTreasureChestContent getChestContent(UUID playerUUID) {
+ PlayerTreasureChestContent loaded = getChestContentIfLoaded(playerUUID);
+ if (loaded != null) {
+ return loaded;
+ }
+ return loadOrCreateChestContent(playerUUID);
+ }
+
+ private PlayerTreasureChestContent loadOrCreateChestContent(UUID playerUUID) {
+ File playerData = new File(chestContentFolder, playerUUID.toString() + ".yml");
+ PlayerTreasureChestContent content = new PlayerTreasureChestContent(plugin, playerData);
+ loadedChests.put(playerUUID, content);
+ return content;
+ }
+
+ public void doGC() {
+ long t = System.currentTimeMillis();
+ for (Player player : plugin.getServer().getOnlinePlayers()) {
+ PlayerTreasureChestContent content = loadedChests.get(player.getUniqueId());
+ if (content != null) {
+ content.setOnline(t);
+ }
+ }
+ Iterator it = loadedChests.values().iterator();
+ while (it.hasNext()) {
+ if (!it.next().isOnline(t)) {
+ it.remove();
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/TreasureChest.java b/src/main/java/de/iani/treasurechest/TreasureChest.java
new file mode 100644
index 0000000..33a2401
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/TreasureChest.java
@@ -0,0 +1,258 @@
+package de.iani.treasurechest;
+
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.UUID;
+import java.util.logging.Level;
+
+import net.milkbowl.vault.economy.Economy;
+
+import org.bukkit.ChatColor;
+import org.bukkit.Effect;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.plugin.RegisteredServiceProvider;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import de.iani.playerUUIDCache.CachedPlayer;
+import de.iani.playerUUIDCache.PlayerUUIDCache;
+
+public class TreasureChest extends JavaPlugin implements TreasureChestAPI {
+ private PriceChestData data;
+
+ private Location chestLocation;
+
+ private Random random;
+
+ // private PlayerUUIDTools uuidTools;
+
+ private boolean hasEconomy;
+
+ private Economy economy;
+
+ private PlayerUUIDCache playerUUIDCache;
+
+ @Override
+ public void onEnable() {
+ random = new Random();
+ setupEconomy();
+ // uuidTools = new PlayerUUIDTools(this);
+ playerUUIDCache = (PlayerUUIDCache) getServer().getPluginManager().getPlugin("PlayerUUIDCache");
+ readConfig();
+ // chestLocation = new Location(getServer().getWorlds().get(0), 308, 127, -879);
+ data = new PriceChestData(this);
+ getCommand("pricechest").setExecutor(new PriceChestCommandExecutor(this));
+
+ getServer().getPluginManager().registerEvents(new ChestInventoryListener(this), this);
+ getServer().getPluginManager().registerEvents(new PlayerEventListener(this), this);
+ getServer().getScheduler().runTaskTimer(this, new Runnable() {
+ @Override
+ public void run() {
+ createParticles();
+ }
+ }, 1, 1);
+
+ getServer().getScheduler().runTaskTimer(this, new Runnable() {
+ @Override
+ public void run() {
+ doGC();
+ }
+ }, 8456, 140000);
+ }
+
+ public PlayerUUIDCache getPlayerUUIDCache() {
+ return playerUUIDCache;
+ }
+
+ @Override
+ public boolean addItem(String player, ItemStack displayItem, ItemStack[] items, int money) {
+ if (!getServer().isPrimaryThread()) {
+ return false;
+ }
+ CachedPlayer id = playerUUIDCache.getPlayerFromNameOrUUID(player, true);
+ if (id == null) {
+ return false;
+ }
+ return addItem(id.getUUID(), displayItem, items, money);
+ }
+
+ @Override
+ public boolean addItem(OfflinePlayer player, ItemStack displayItem, ItemStack[] items, int money) {
+ if (!getServer().isPrimaryThread()) {
+ return false;
+ }
+ return addItem(player.getUniqueId(), displayItem, items, money);
+ }
+
+ private boolean addItem(UUID player, ItemStack displayItem, ItemStack[] items, int money) {
+ if (displayItem == null || displayItem.getAmount() == 0 || displayItem.getType() == Material.AIR) {
+ return false;
+ }
+ ArrayList copied = new ArrayList<>();
+ for (ItemStack is : items) {
+ if (is != null && is.getAmount() > 0 && is.getType() != Material.AIR) {
+ copied.add(is);
+ }
+ }
+ items = copied.toArray(new ItemStack[copied.size()]);
+
+ PlayerTreasureChestContent content = getData().getChestContent(player);
+ content.addItem(new TreasureChestItem(displayItem, items, money));
+ return true;
+ }
+
+ protected void doGC() {
+ data.doGC();
+ }
+
+ private void readConfig() {
+ // saveDefaultConfig();
+ FileConfiguration config = getConfig();
+ ConfigurationSection section = config.getConfigurationSection("chestLocation");
+ if (section != null) {
+ String worldName = section.getString("world");
+ int x = section.getInt("x");
+ int y = section.getInt("y");
+ int z = section.getInt("z");
+ if (worldName != null) {
+ World world = getServer().getWorld(worldName);
+ if (world != null) {
+ chestLocation = new Location(world, x, y, z);
+ }
+ }
+ }
+ }
+
+ public void saveConfig() {
+ FileConfiguration config = getConfig();
+ if (chestLocation == null || chestLocation.getWorld() == null) {
+ config.set("chestLocation", null);
+ } else {
+ ConfigurationSection section = config.getConfigurationSection("chestLocation");
+ if (section == null) {
+ section = config.createSection("chestLocation");
+ }
+ section.set("world", chestLocation.getWorld().getName());
+ section.set("x", chestLocation.getBlockX());
+ section.set("y", chestLocation.getBlockY());
+ section.set("z", chestLocation.getBlockZ());
+ }
+ super.saveConfig();
+ }
+
+ // public PlayerUUIDTools getUUIDTools()
+ // {
+ // return uuidTools;
+ // }
+
+ public PriceChestData getData() {
+ return data;
+ }
+
+ public Location getChestLocation() {
+ return chestLocation;
+ }
+
+ protected void createParticles() {
+ if (random.nextInt(10) == 0 && chestLocation != null) {
+ Location playerLocation = new Location(null, 0, 0, 0);
+ for (Player player : getServer().getOnlinePlayers()) {
+ player.getLocation(playerLocation);
+ if (playerLocation.getWorld() == chestLocation.getWorld()) {
+ double dx = playerLocation.getX() - chestLocation.getX();
+ double dy = playerLocation.getY() - chestLocation.getY();
+ double dz = playerLocation.getZ() - chestLocation.getZ();
+ double dsquared = dx * dx + dy * dy + dz * dz;
+ if (dsquared < 16 * 16) {
+ if (!data.getChestContent(player.getUniqueId()).isEmpty()) {
+ player.playEffect(chestLocation, Effect.MOBSPAWNER_FLAMES, null);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void sendMessage(CommandSender p, String text) {
+ sendMessage(p, text, false);
+ }
+
+ public void sendMessage(CommandSender p, String text, boolean error) {
+ p.sendMessage(ChatColor.BLUE + "[TC] " + (error ? ChatColor.DARK_RED : ChatColor.YELLOW) + text);
+ }
+
+ public void setChestLocation(Location location) {
+ chestLocation = location;
+ saveConfig();
+ }
+
+ private void setupEconomy() {
+ try {
+ RegisteredServiceProvider economyProvider = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
+ if (economyProvider != null) {
+ economy = economyProvider.getProvider();
+ hasEconomy = true;
+ } else {
+ getLogger().severe("Kein Economy-Plugin! Es können keine Preisgelder ausgezahlt werden!");
+ }
+ } catch (Throwable e) {
+ getLogger().severe("Vault nicht gefunden! Es können keine Preisgelder ausgezahlt werden!");
+ }
+ }
+
+ public boolean hasEconomy() {
+ return hasEconomy;
+ }
+
+ public void giveMoney(Player player, int amount) {
+ if (hasEconomy) {
+ try {
+ economy.depositPlayer(player, amount);
+ } catch (Throwable e) {
+ getLogger().log(Level.SEVERE, "Error paying money", e);
+ }
+ }
+ }
+
+ public String formatMoney(int amount) {
+ if (hasEconomy) {
+ try {
+ return economy.format(amount);
+ } catch (Throwable e) {
+ getLogger().log(Level.SEVERE, "Error formating money", e);
+ }
+ }
+ return Integer.toString(amount);
+ }
+
+ public static String capitalize(String s, boolean replaceUnderscores) {
+ char[] cap = s.toCharArray();
+ boolean lastSpace = true;
+ for (int i = 0; i < cap.length; i++) {
+ if (cap[i] == '_') {
+ if (replaceUnderscores) {
+ cap[i] = ' ';
+ }
+ lastSpace = true;
+ } else if (cap[i] >= '0' && cap[i] <= '9') {
+ lastSpace = true;
+ } else {
+ if (lastSpace) {
+ cap[i] = Character.toUpperCase(cap[i]);
+ } else {
+ cap[i] = Character.toLowerCase(cap[i]);
+ }
+ lastSpace = false;
+ }
+ }
+ return new String(cap);
+ }
+
+}
diff --git a/src/main/java/de/iani/treasurechest/TreasureChestAPI.java b/src/main/java/de/iani/treasurechest/TreasureChestAPI.java
new file mode 100644
index 0000000..a41e45e
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/TreasureChestAPI.java
@@ -0,0 +1,10 @@
+package de.iani.treasurechest;
+
+import org.bukkit.OfflinePlayer;
+import org.bukkit.inventory.ItemStack;
+
+public interface TreasureChestAPI {
+ public abstract boolean addItem(OfflinePlayer player, ItemStack displayItem, ItemStack[] items, int money);
+
+ public abstract boolean addItem(String player, ItemStack displayItem, ItemStack[] items, int money);
+}
diff --git a/src/main/java/de/iani/treasurechest/TreasureChestItem.java b/src/main/java/de/iani/treasurechest/TreasureChestItem.java
new file mode 100644
index 0000000..04bb03c
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/TreasureChestItem.java
@@ -0,0 +1,67 @@
+package de.iani.treasurechest;
+
+import org.bukkit.inventory.ItemStack;
+
+public class TreasureChestItem implements Cloneable {
+ private ItemStack displayItem;
+
+ private ItemStack[] priceItems;
+
+ private int priceMoney;
+
+ public TreasureChestItem(ItemStack displayItem) {
+ this.displayItem = displayItem;
+ }
+
+ public TreasureChestItem(ItemStack displayItem, ItemStack[] priceItems, int priceMoney) {
+ this.displayItem = displayItem;
+ this.priceItems = priceItems;
+ this.priceMoney = priceMoney;
+ }
+
+ public ItemStack getDisplayItem() {
+ return displayItem;
+ }
+
+ public ItemStack[] getPriceItems() {
+ return priceItems;
+ }
+
+ public int getPriceMoney() {
+ return priceMoney;
+ }
+
+ public void setPriceMoney(int amount) {
+ priceMoney = amount;
+ }
+
+ public void addPriceItem(ItemStack item) {
+ if (priceItems == null) {
+ priceItems = new ItemStack[] { item };
+ } else {
+ ItemStack[] temp = priceItems;
+ priceItems = new ItemStack[temp.length + 1];
+ System.arraycopy(temp, 0, priceItems, 0, temp.length);
+ priceItems[temp.length] = item;
+ }
+ }
+
+ @Override
+ public TreasureChestItem clone() {
+ try {
+ TreasureChestItem el = (TreasureChestItem) super.clone();
+ if (displayItem != null) {
+ el.displayItem = displayItem.clone();
+ }
+ if (priceItems != null) {
+ el.priceItems = new ItemStack[priceItems.length];
+ for (int i = 0; i < priceItems.length; i++) {
+ el.priceItems[i] = priceItems[i] != null ? priceItems[i].clone() : null;
+ }
+ }
+ return el;
+ } catch (CloneNotSupportedException e) {
+ throw new Error(e);
+ }
+ }
+}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..d560ec3
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,44 @@
+name: ${project.artifactId}
+main: de.iani.treasurechest.TreasureChest
+version: ${project.version}-${build.number}
+author: Brokkonaut
+description: Treasure Chests for Events
+softdepend: [Vault]
+depend: [PlayerUUIDCache]
+
+commands:
+ prizechest:
+ description: Prizechest/Treasurechest
+ aliases: [prize, pc, treasurechest, tc]
+
+permissions:
+ treasurechest.admin:
+ description: Gives access to all commands
+ default: op
+ children:
+ treasurechest.setchest: true
+ treasurechest.create: true
+ treasurechest.give: true
+ treasurechest.list: true
+ treasurechest.remove: true
+ treasurechest.staff:
+ description: Gives access to most commands
+ default: op
+ children:
+ treasurechest.create: true
+ treasurechest.give: true
+ treasurechest.list: true
+ treasurechest.remove: true
+ treasurechest.access:
+ description: Access your treasure chest
+ default: true
+ treasurechest.setchest:
+ description: Change the chest location
+ treasurechest.create:
+ description: Creates a treasure
+ treasurechest.give:
+ description: Gives a treasure to a player
+ treasurechest.list:
+ description: Lists treasures for a player
+ treasurechest.remove:
+ description: Removes a treasure from a player
\ No newline at end of file