diff --git a/pom.xml b/pom.xml
index 910dc7c..35284df 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,7 +32,7 @@
de.iani.cubeside
PlayerUUIDCache
- 1.4.0
+ 1.5.1-SNAPSHOT
provided
diff --git a/src/main/java/de/iani/treasurechest/ChestInventoryListener.java b/src/main/java/de/iani/treasurechest/ChestInventoryListener.java
index 4f3aa1b..958daef 100644
--- a/src/main/java/de/iani/treasurechest/ChestInventoryListener.java
+++ b/src/main/java/de/iani/treasurechest/ChestInventoryListener.java
@@ -1,8 +1,10 @@
package de.iani.treasurechest;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -24,6 +26,8 @@
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
+import de.iani.treasurechest.database.DatabaseTreasureChestItem;
+
public class ChestInventoryListener implements Listener {
private TreasureChest plugin;
@@ -58,7 +62,7 @@
OpenInventoryData openInventory = new OpenInventoryData(b.getLocation(), inventory);
int pos = 0;
- for (TreasureChestItem item : content.getItems()) {
+ for (DatabaseTreasureChestItem item : content.getItems()) {
if (pos < 9 * 6) {
ItemStack di = item.getDisplayItem().clone();
ItemMeta meta = di.getItemMeta();
@@ -90,7 +94,7 @@
meta.setLore(lore);
di.setItemMeta(meta);
inventory.setItem(pos, di);
- openInventory.setItemAtPosition(pos, pos);
+ openInventory.setItemAtPosition(pos, item.getId());
}
pos += 1;
}
@@ -124,7 +128,10 @@
clonedPlayerInventory.setContents(playerInv);
PlayerTreasureChestContent content = plugin.getData().getChestContent(player.getUniqueId());
- int entryId = openInventory.getEntryAtPosition(event.getRawSlot());
+ Integer entryId = openInventory.getEntryAtPosition(event.getRawSlot());
+ if (entryId == null) {
+ return;
+ }
TreasureChestItem selectedItem = content.getItem(entryId);
if (selectedItem != null) {
ItemStack[] priceList = selectedItem.getPriceItems();
@@ -136,10 +143,18 @@
}
if (!clonedPlayerInventory.addItem(temp).isEmpty()) {
plugin.sendMessage(player, "Du hast nicht genügend Platz in deinem Inventar!", true);
- player.updateInventory();
return;
}
}
+ try {
+ if (!plugin.getDatabase().deleteItem(player.getUniqueId(), entryId)) {
+ return;
+ }
+ } catch (SQLException e) {
+ plugin.sendMessage(player, ChatColor.DARK_RED + "Datenbankfehler");
+ plugin.getLogger().log(Level.SEVERE, "Could not delete item " + entryId + " for " + player.getUniqueId() + ": " + e.getMessage(), e);
+ return;
+ }
plugin.sendMessage(player, ChatColor.GRAY + "Du hast folgende Items erhalten:");
if (priceCount > 0) {
ItemStack[] temp = new ItemStack[priceCount];
@@ -174,7 +189,7 @@
player.playSound(event.getWhoClicked().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1f, 1f);
content.removeItem(entryId);
openInventory.getInventory().setItem(event.getRawSlot(), null);
- openInventory.removeEntryAtPositionAndShift(event.getRawSlot());
+ openInventory.removeEntryAtPosition(event.getRawSlot());
player.updateInventory();
}
}
diff --git a/src/main/java/de/iani/treasurechest/ListedItemsData.java b/src/main/java/de/iani/treasurechest/ListedItemsData.java
new file mode 100644
index 0000000..ef60208
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/ListedItemsData.java
@@ -0,0 +1,26 @@
+package de.iani.treasurechest;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+public class ListedItemsData {
+ private UUID owner;
+ private HashMap items;
+
+ public ListedItemsData(UUID owner) {
+ this.owner = owner;
+ this.items = new HashMap<>();
+ }
+
+ public void addItem(int listPos, int databaseKey) {
+ items.put(listPos, databaseKey);
+ }
+
+ public Integer getItemDatabaseKey(int listPos) {
+ return items.get(listPos);
+ }
+
+ public UUID getOwner() {
+ return owner;
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/OpenInventoryData.java b/src/main/java/de/iani/treasurechest/OpenInventoryData.java
index 2574f61..03fb34b 100644
--- a/src/main/java/de/iani/treasurechest/OpenInventoryData.java
+++ b/src/main/java/de/iani/treasurechest/OpenInventoryData.java
@@ -1,59 +1,50 @@
-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;
- }
- }
- }
- }
-}
+package de.iani.treasurechest;
+
+import java.util.Arrays;
+
+import org.bukkit.Location;
+import org.bukkit.inventory.Inventory;
+
+public class OpenInventoryData {
+ private Location location;
+
+ private Inventory inventory;
+
+ private Integer[] 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 Integer[inventoryPosition + 1];
+ } else if (itemAtLocation.length <= inventoryPosition) {
+ itemAtLocation = Arrays.copyOf(itemAtLocation, inventoryPosition + 1);
+ }
+ itemAtLocation[inventoryPosition] = itemListPosition;
+ }
+
+ public Integer getEntryAtPosition(int inventoryPosition) {
+ if (itemAtLocation == null || itemAtLocation.length <= inventoryPosition || inventoryPosition < 0) {
+ return null;
+ }
+ return itemAtLocation[inventoryPosition];
+ }
+
+ public void removeEntryAtPosition(int inventoryPosition) {
+ if (itemAtLocation == null || itemAtLocation.length <= inventoryPosition || inventoryPosition < 0) {
+ return;
+ }
+ itemAtLocation[inventoryPosition] = null;
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/PlayerEventListener.java b/src/main/java/de/iani/treasurechest/PlayerEventListener.java
index c4a6be1..36beaec 100644
--- a/src/main/java/de/iani/treasurechest/PlayerEventListener.java
+++ b/src/main/java/de/iani/treasurechest/PlayerEventListener.java
@@ -1,19 +1,27 @@
-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());
- }
-
-}
+package de.iani.treasurechest;
+
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+public class PlayerEventListener implements Listener {
+ private TreasureChest plugin;
+
+ public PlayerEventListener(TreasureChest plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ plugin.getData().loadTreasureChest(event.getPlayer().getUniqueId());
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ plugin.getData().removeActiveItem(event.getPlayer().getUniqueId());
+ plugin.getData().unloadTreasureChest(event.getPlayer().getUniqueId());
+ plugin.getData().removeListedItems(event.getPlayer().getUniqueId());
+ }
+
+}
diff --git a/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java b/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java
index 15d892a..769ed37 100644
--- a/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java
+++ b/src/main/java/de/iani/treasurechest/PlayerTreasureChestContent.java
@@ -1,114 +1,170 @@
package de.iani.treasurechest;
-import java.io.File;
-import java.io.IOException;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.UUID;
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;
+import org.bukkit.scheduler.BukkitRunnable;
+
+import de.iani.treasurechest.database.DatabaseTreasureChestItem;
+import de.iani.treasurechest.database.TreasureChestDatabase;
+import de.iani.treasurechest.worker.WorkEntry;
public class PlayerTreasureChestContent {
- private TreasureChest plugin;
+ private final TreasureChest plugin;
+ private final UUID owner;
- private File file;
+ private LoadState loadState = LoadState.NOT_LOADED;
- private ArrayList items;
+ private ArrayList items;
+ private HashMap itemsById;
+ private ArrayList loadCallbacks;
- private long online;
-
- public PlayerTreasureChestContent(TreasureChest plugin, File file) {
+ public PlayerTreasureChestContent(UUID owner, TreasureChest plugin) {
this.plugin = plugin;
- this.file = file;
- try {
- if (file.exists()) {
- YamlConfiguration conf = YamlConfiguration.loadConfiguration(file);
+ this.owner = owner;
+ }
- 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);
+ public void loadAsync(Runnable loadCallback) {
+ if (loadCallback != null) {
+ if (loadState == LoadState.LOADED) {
+ loadCallback.run();
+ return;
+ }
+ if (loadCallbacks == null) {
+ loadCallbacks = new ArrayList<>();
+ }
+ loadCallbacks.add(loadCallback);
+ }
+ loadAsync();
+ }
+
+ public void loadAsync() {
+ if (loadState != LoadState.NOT_LOADED) {
+ return;
+ }
+ loadState = LoadState.LOADING;
+ plugin.getWorkerThread().addWork(new WorkEntry() {
+ @Override
+ public void process(TreasureChestDatabase database) {
+ try {
+ ArrayList loadedItems = plugin.getDatabase().getPlayerItems(owner);
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ items = loadedItems;
+ itemsById = new HashMap<>();
+ for (DatabaseTreasureChestItem i : items) {
+ itemsById.put(i.getId(), i);
}
- 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);
- }
+ loadState = LoadState.LOADED;
+
+ if (loadCallbacks != null) {
+ for (Runnable r : loadCallbacks) {
+ r.run();
}
+ loadCallbacks = null;
}
- if (items == null) {
- items = new ArrayList<>();
- }
- items.add(new TreasureChestItem(display, priceItems.toArray(new ItemStack[priceItems.size()]), priceMoney));
}
- }
+ }.runTask(plugin);
+ } catch (SQLException e) {
+ plugin.getLogger().log(Level.SEVERE, "Could not load treasure chest data for " + owner + ": " + e, e);
}
}
- } 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 PlayerTreasureChestContent(UUID owner, 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);
+ // }
+ // }
- public void addItem(TreasureChestItem item) {
+ // 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);
+ // }
+ // }
+
+ void addItem(DatabaseTreasureChestItem item) {
item = item.clone();
if (items == null) {
items = new ArrayList<>();
+ itemsById = new HashMap<>();
}
- items.add(item);
- save();
+ items.add(0, item);
+ itemsById.put(item.getId(), item);
}
- public boolean removeItem(int pos) {
- if (items == null || items.size() <= pos || pos < 0) {
+ public boolean removeItem(int id) {
+ if (itemsById == null) {
return false;
}
- items.remove(pos);
- if (items.size() == 0) {
- items = null;
+ DatabaseTreasureChestItem removed = itemsById.remove(id);
+ if (removed != null) {
+ items.remove(removed);
}
- save();
return true;
}
@@ -116,22 +172,23 @@
return items == null || items.isEmpty();
}
- public List getItems() {
+ public List getItems() {
return items == null ? Collections.emptyList() : Collections.unmodifiableList(items);
}
- public TreasureChestItem getItem(int pos) {
- if (items == null || items.size() <= pos || pos < 0) {
- return null;
- }
- return items.get(pos);
+ public DatabaseTreasureChestItem getItem(int id) {
+ return itemsById.get(id);
}
- public void setOnline(long t) {
- online = t;
+ public LoadState getLoadState() {
+ return loadState;
}
- public boolean isOnline(long t) {
- return online == t;
+ public UUID getOwner() {
+ return owner;
+ }
+
+ public enum LoadState {
+ NOT_LOADED, LOADING, LOADED
}
}
diff --git a/src/main/java/de/iani/treasurechest/TreasureChest.java b/src/main/java/de/iani/treasurechest/TreasureChest.java
index ddcaeff..4b69993 100644
--- a/src/main/java/de/iani/treasurechest/TreasureChest.java
+++ b/src/main/java/de/iani/treasurechest/TreasureChest.java
@@ -1,5 +1,6 @@
package de.iani.treasurechest;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Random;
import java.util.UUID;
@@ -18,10 +19,16 @@
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitRunnable;
import de.iani.playerUUIDCache.CachedPlayer;
import de.iani.playerUUIDCache.PlayerUUIDCache;
-import de.iani.playerUUIDCache.SQLConfig;
+import de.iani.treasurechest.PlayerTreasureChestContent.LoadState;
+import de.iani.treasurechest.database.DatabaseTreasureChestItem;
+import de.iani.treasurechest.database.SQLConfig;
+import de.iani.treasurechest.database.TreasureChestDatabase;
+import de.iani.treasurechest.worker.WorkEntry;
+import de.iani.treasurechest.worker.WorkerThread;
import net.milkbowl.vault.economy.Economy;
public class TreasureChest extends JavaPlugin implements TreasureChestAPI {
@@ -31,8 +38,6 @@
private Random random;
- // private PlayerUUIDTools uuidTools;
-
private boolean hasEconomy;
private Economy economy;
@@ -41,17 +46,28 @@
private SQLConfig sqlConfig;
+ private TreasureChestDatabase database;
+ private WorkerThread workerThread;
+
@Override
public void onEnable() {
saveDefaultConfig();
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);
+ try {
+ database = new TreasureChestDatabase(sqlConfig);
+ } catch (SQLException e) {
+ getLogger().log(Level.SEVERE, "Could not connect to database: " + e.getMessage(), e);
+ setEnabled(false);
+ return;
+ }
+
+ workerThread = new WorkerThread(this);
data = new TreasureChestData(this);
+
getCommand("treasurechest").setExecutor(new TreasureChestCommandExecutor(this));
getServer().getPluginManager().registerEvents(new ChestInventoryListener(this), this);
@@ -66,7 +82,7 @@
getServer().getScheduler().runTaskTimer(this, new Runnable() {
@Override
public void run() {
- doGC();
+ data.doGC();
}
}, 8456, 140000);
}
@@ -107,15 +123,31 @@
}
items = copied.toArray(new ItemStack[copied.size()]);
- PlayerTreasureChestContent content = getData().getChestContent(player);
- content.addItem(new TreasureChestItem(displayItem, items, money));
+ TreasureChestItem item = new TreasureChestItem(displayItem, items, money);
+ workerThread.addWork(new WorkEntry() {
+ @Override
+ public void process(TreasureChestDatabase database) {
+ try {
+ DatabaseTreasureChestItem added = database.addItem(player, item);
+ if (added != null) {
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ PlayerTreasureChestContent cc = getData().getChestContent(player);
+ if (cc != null && cc.getLoadState() == LoadState.LOADED) {
+ cc.addItem(added);
+ }
+ }
+ };
+ }
+ } catch (SQLException e) {
+ getLogger().log(Level.SEVERE, "Could not add treasure chest item to database: " + e.getMessage(), e);
+ }
+ }
+ });
return true;
}
- protected void doGC() {
- data.doGC();
- }
-
private void readConfig() {
// saveDefaultConfig();
FileConfiguration config = getConfig();
@@ -153,11 +185,6 @@
super.saveConfig();
}
- // public PlayerUUIDTools getUUIDTools()
- // {
- // return uuidTools;
- // }
-
public TreasureChestData getData() {
return data;
}
@@ -177,8 +204,12 @@
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);
+ PlayerTreasureChestContent playerData = data.getChestContent(player.getUniqueId());
+ if (playerData != null) {
+ playerData.loadAsync();
+ if (!playerData.isEmpty()) {
+ player.playEffect(chestLocation, Effect.MOBSPAWNER_FLAMES, null);
+ }
}
}
}
@@ -265,4 +296,11 @@
return new String(cap);
}
+ public TreasureChestDatabase getDatabase() {
+ return database;
+ }
+
+ public WorkerThread getWorkerThread() {
+ return workerThread;
+ }
}
diff --git a/src/main/java/de/iani/treasurechest/TreasureChestCommandExecutor.java b/src/main/java/de/iani/treasurechest/TreasureChestCommandExecutor.java
index 08c10d4..368e210 100644
--- a/src/main/java/de/iani/treasurechest/TreasureChestCommandExecutor.java
+++ b/src/main/java/de/iani/treasurechest/TreasureChestCommandExecutor.java
@@ -1,265 +1,294 @@
-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 TreasureChestCommandExecutor implements CommandExecutor {
- private TreasureChest plugin;
-
- public TreasureChestCommandExecutor(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, "treasurechest.setchest")) {
- return true;
- }
- Player player = ((Player) sender);
- Block target = player.getTargetBlock((Set) null, 5);
- plugin.setChestLocation(target == null ? null : target.getLocation());
- if (target != null) {
- 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 {
- plugin.sendMessage(sender, "Treasurechest location removed!");
- }
- } else if (subcommand.equals("create")) {
- if (!checkPlayer(sender) || !checkPermission(sender, "treasurechest.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, "treasurechest.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, "treasurechest.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, "treasurechest.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, "treasurechest.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, "treasurechest.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, "treasurechest.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, "treasurechest.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, "treasurechest.give", true)) {
- plugin.sendMessage(sender, "/" + label + " give ");
- plugin.sendMessage(sender, ChatColor.GREEN + " Gives a price to a player.");
- }
- if (checkPermission(sender, "treasurechest.list")) {
- plugin.sendMessage(sender, "/" + label + " list ");
- plugin.sendMessage(sender, ChatColor.GREEN + " Gives price for a player.");
- }
- if (checkPermission(sender, "treasurechest.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;
- }
-}
+package de.iani.treasurechest;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.logging.Level;
+
+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;
+import de.iani.treasurechest.PlayerTreasureChestContent.LoadState;
+import de.iani.treasurechest.database.DatabaseTreasureChestItem;
+
+public class TreasureChestCommandExecutor implements CommandExecutor {
+ private TreasureChest plugin;
+
+ public TreasureChestCommandExecutor(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, "treasurechest.setchest")) {
+ return true;
+ }
+ Player player = ((Player) sender);
+ Block target = player.getTargetBlock((Set) null, 5);
+ plugin.setChestLocation(target == null ? null : target.getLocation());
+ if (target != null) {
+ 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 {
+ plugin.sendMessage(sender, "Treasurechest location removed!");
+ }
+ } else if (subcommand.equals("create")) {
+ if (!checkPlayer(sender) || !checkPermission(sender, "treasurechest.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, "treasurechest.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, "treasurechest.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, "treasurechest.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();
+ CachedPlayer target = plugin.getPlayerUUIDCache().getPlayerFromNameOrUUID(nameOrId);
+ if (target == null) {
+ plugin.sendMessage(sender, "Unknown player!", true);
+ } else {
+ plugin.addItem(target, activeItem.getDisplayItem(), activeItem.getPriceItems(), activeItem.getPriceMoney());
+ plugin.sendMessage(sender, "Item given to: " + target.getName() + " (" + target.getUUID() + ")");
+ }
+ }
+ return true;
+ } else if (subcommand.equals("list")) {
+ if (!checkPermission(sender, "treasurechest.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 {
+ ListedItemsData lid = new ListedItemsData(targetuuid);
+ int nr = 1;
+ for (DatabaseTreasureChestItem i : items) {
+ plugin.sendMessage(sender, nr + ": " + i.getDisplayItem().getItemMeta().getDisplayName());
+ lid.addItem(nr, i.getId());
+ nr++;
+ }
+ if (sender instanceof Player) {
+ Player player = ((Player) sender);
+ plugin.getData().setListedItems(player.getUniqueId(), lid);
+ } else {
+ plugin.getData().setListedItems(null, lid);
+ }
+ }
+ } else if (subcommand.equals("remove")) {
+ if (!checkPermission(sender, "treasurechest.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);
+
+ ListedItemsData lid;
+ if (sender instanceof Player) {
+ Player player = ((Player) sender);
+ lid = plugin.getData().getListedItems(player.getUniqueId());
+ } else {
+ lid = plugin.getData().getListedItems(null);
+ }
+ if (lid == null || !lid.getOwner().equals(targetuuid)) {
+ plugin.sendMessage(sender, "Nicht der gelistete Spieler", true);
+ return true;
+ }
+ Integer key = lid.getItemDatabaseKey(nr);
+ if (key == null) {
+ plugin.sendMessage(sender, "Ungültige ID", true);
+ return true;
+ }
+ try {
+ if (plugin.getDatabase().deleteItem(targetuuid, key)) {
+ PlayerTreasureChestContent content = plugin.getData().getChestContent(targetuuid);
+ if (content != null && content.getLoadState() == LoadState.LOADED) {
+ content.removeItem(key);
+ }
+ } else {
+ plugin.sendMessage(sender, "Ungültige ID", true);
+ return true;
+ }
+ } catch (SQLException e) {
+ plugin.sendMessage(sender, ChatColor.DARK_RED + "Datenbankfehler");
+ plugin.getLogger().log(Level.SEVERE, "Could not delete item " + key + " for " + targetuuid + ": " + e.getMessage(), e);
+ 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, "treasurechest.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, "treasurechest.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, "treasurechest.give", true)) {
+ plugin.sendMessage(sender, "/" + label + " give ");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Gives a price to a player.");
+ }
+ if (checkPermission(sender, "treasurechest.list")) {
+ plugin.sendMessage(sender, "/" + label + " list ");
+ plugin.sendMessage(sender, ChatColor.GREEN + " Gives price for a player.");
+ }
+ if (checkPermission(sender, "treasurechest.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/TreasureChestData.java b/src/main/java/de/iani/treasurechest/TreasureChestData.java
index c38e0ff..3c5cc6a 100644
--- a/src/main/java/de/iani/treasurechest/TreasureChestData.java
+++ b/src/main/java/de/iani/treasurechest/TreasureChestData.java
@@ -1,84 +1,77 @@
-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 TreasureChestData {
- private HashMap namedItems;
-
- private HashMap activeItems;
-
- private HashMap loadedChests;
-
- private TreasureChest plugin;
-
- private File chestContentFolder;
-
- public TreasureChestData(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();
- }
- }
- }
-}
+package de.iani.treasurechest;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.UUID;
+
+public class TreasureChestData {
+ private HashMap activeItems;
+
+ private HashMap loadedChests;
+
+ private HashMap listedItems;
+
+ private TreasureChest plugin;
+
+ private File chestContentFolder;
+
+ public TreasureChestData(TreasureChest plugin) {
+ activeItems = new HashMap<>();
+ loadedChests = new HashMap<>();
+ listedItems = new HashMap<>();
+
+ this.plugin = plugin;
+ chestContentFolder = new File(this.plugin.getDataFolder(), "content");
+ chestContentFolder.mkdirs();
+ }
+
+ 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 getChestContent(UUID playerUUID) {
+ return loadedChests.get(playerUUID);
+ }
+
+ public void loadTreasureChest(UUID owner) {
+ loadedChests.put(owner, new PlayerTreasureChestContent(owner, plugin));
+ }
+
+ public void unloadTreasureChest(UUID owner) {
+ loadedChests.remove(owner);
+ }
+
+ public ListedItemsData getListedItems(UUID owner) {
+ return listedItems.get(owner);
+ }
+
+ public void setListedItems(UUID owner, ListedItemsData data) {
+ listedItems.put(owner, data);
+ }
+
+ public void removeListedItems(UUID owner) {
+ listedItems.remove(owner);
+ }
+
+ public void doGC() {
+ Iterator it = loadedChests.values().iterator();
+ while (it.hasNext()) {
+ PlayerTreasureChestContent c = it.next();
+ if (plugin.getServer().getPlayer(c.getOwner()) == null) {
+ it.remove();
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/database/DatabaseTreasureChestItem.java b/src/main/java/de/iani/treasurechest/database/DatabaseTreasureChestItem.java
new file mode 100644
index 0000000..b36ebfd
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/database/DatabaseTreasureChestItem.java
@@ -0,0 +1,30 @@
+package de.iani.treasurechest.database;
+
+import org.bukkit.inventory.ItemStack;
+
+import de.iani.treasurechest.TreasureChestItem;
+
+public class DatabaseTreasureChestItem extends TreasureChestItem {
+
+ private final long time;
+ private final int id;
+
+ public DatabaseTreasureChestItem(ItemStack displayItem, ItemStack[] priceItems, int priceMoney, long time, int id) {
+ super(displayItem, priceItems, priceMoney);
+ this.time = time;
+ this.id = id;
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ @Override
+ public DatabaseTreasureChestItem clone() {
+ return (DatabaseTreasureChestItem) super.clone();
+ }
+}
diff --git a/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java b/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java
index 23b056f..94a5b99 100644
--- a/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java
+++ b/src/main/java/de/iani/treasurechest/database/TreasureChestDatabase.java
@@ -8,8 +8,12 @@
import java.util.ArrayList;
import java.util.UUID;
-import de.iani.playerUUIDCache.CachedPlayer;
-import de.iani.playerUUIDCache.PlayerUUIDCache;
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.inventory.ItemStack;
+
import de.iani.treasurechest.TreasureChestItem;
import de.iani.treasurechest.util.sql.MySQLConnection;
import de.iani.treasurechest.util.sql.SQLConnection;
@@ -21,20 +25,17 @@
private final String tableName;
private final String insertContent;
-
private final String selectContent;
-
private final String removeContent;
-
private final String removeOldContent;
public TreasureChestDatabase(SQLConfig config) throws SQLException {
connection = new MySQLConnection(config.getHost(), config.getDatabase(), config.getUser(), config.getPassword());
this.tableName = config.getTablePrefix() + "_content";
- insertContent = "INSERT INTO " + tableName + " (uuid, time, displayItem, content) VALUES (?, ?, ?, ?)";
+ insertContent = "INSERT INTO " + tableName + " (uuid, time, content) VALUES (?, ?, ?)";
- selectContent = "SELECT id, uuid, time, displayItem, content FROM " + tableName + " WHERE uuid = ?";
+ selectContent = "SELECT id, uuid, time, content FROM " + tableName + " WHERE uuid = ? ORDER BY time DESC";
removeContent = "DELETE FROM " + tableName + " WHERE id = ? AND uuid = ?";
@@ -46,12 +47,11 @@
if (!sqlConnection.hasTable(tableName)) {
Statement smt = connection.createStatement();
smt.executeUpdate("CREATE TABLE `" + tableName + "` ("//
- + "`id` INT NOT NULL,"//
+ + "`id` INT NOT NULL AUTO_INCREMENT,"//
+ "`uuid` CHAR( 36 ) NOT NULL,"//
+ "`time` BIGINT NOT NULL,"//
- + "`displayItem` MEDIUMTEXT ,"//
- + "`content` MEDIUMTEXT ,"//
- + "PRIMARY KEY ( `id` ), INDEX ( `uuid` ) ) ENGINE = innodb");
+ + "`content` LONGTEXT,"//
+ + "PRIMARY KEY ( `id` ), INDEX ( `uuid`, `time` ) ) ENGINE = innodb");
smt.close();
}
return null;
@@ -63,79 +63,105 @@
connection.disconnect();
}
- public void addItem(final UUID owner, final String displayItem, final String content) throws SQLException {
- this.connection.runCommands(new SQLRunnable() {
+ public DatabaseTreasureChestItem addItem(UUID owner, TreasureChestItem item) throws SQLException {
+ return this.connection.runCommands(new SQLRunnable() {
@Override
- public Void execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
- PreparedStatement smt = sqlConnection.getOrCreateStatement(insertContent);
+ public DatabaseTreasureChestItem execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
+ PreparedStatement smt = sqlConnection.getOrCreateStatement(insertContent, Statement.RETURN_GENERATED_KEYS);
smt.setString(1, owner.toString());
- smt.setLong(2, System.currentTimeMillis());
- smt.setString(3, displayItem);
- smt.setString(4, content);
- smt.executeUpdate();
- return null;
- }
- });
-
- }
-
- public ArrayList getPlayerItems(final UUID uuid) throws SQLException {
- return this.connection.runCommands(new SQLRunnable>() {
- @Override
- public ArrayList execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
- PreparedStatement smt = sqlConnection.getOrCreateStatement(selectContent);
- smt.setString(1, uuid.toString());
- ResultSet rs = smt.executeQuery();
- while (rs.next()) {
- // TODO
- }
- rs.close();
- return null;
- }
- });
- }
-
- public CachedPlayer getPlayer(final String name) throws SQLException {
- return this.connection.runCommands(new SQLRunnable() {
- @Override
- public CachedPlayer execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
- String realName = name;
- PreparedStatement smt = sqlConnection.getOrCreateStatement(selectPlayerByName);
- smt.setString(1, name);
- ResultSet rs = smt.executeQuery();
-
- UUID uuid = null;
- long time = Long.MIN_VALUE;
- while (rs.next()) {
- long thisTime = rs.getLong(3);
- if (thisTime > time) {
- try {
- uuid = UUID.fromString(rs.getString(1));
- realName = rs.getString(2);
- time = thisTime;
- } catch (IllegalArgumentException e) {
- // ignore invalid uuid
- }
+ long time = System.currentTimeMillis();
+ smt.setLong(2, time);
+ YamlConfiguration conf = new YamlConfiguration();
+ conf.set("display", item.getDisplayItem());
+ ConfigurationSection itemsSection = conf.createSection("items");
+ ItemStack[] items = item.getPriceItems();
+ if (items != null) {
+ for (int i = 0; i < items.length; i++) {
+ ItemStack stack = items[i];
+ itemsSection.set(Integer.toString(i), stack);
}
}
- rs.close();
- if (uuid != null) {
- return new CachedPlayer(uuid, realName, time, System.currentTimeMillis());
+ conf.set("money", item.getPriceMoney());
+ smt.setString(3, conf.saveToString());
+ smt.executeUpdate();
+ ResultSet genKeys = smt.getGeneratedKeys();
+ Integer id = null;
+ if (genKeys.next()) {
+ id = genKeys.getInt(1);
}
- return null;
+ genKeys.close();
+ if (id == null) {
+ throw new SQLException("No id was generated!");
+ }
+ return new DatabaseTreasureChestItem(item.getDisplayItem(), item.getPriceItems(), item.getPriceMoney(), time, id);
+ }
+ });
+
+ }
+
+ public ArrayList getPlayerItems(UUID owner) throws SQLException {
+ return this.connection.runCommands(new SQLRunnable>() {
+ @Override
+ public ArrayList execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
+ ArrayList result = new ArrayList<>();
+ PreparedStatement smt = sqlConnection.getOrCreateStatement(selectContent);
+ smt.setString(1, owner.toString());
+ ResultSet rs = smt.executeQuery();
+ while (rs.next()) {
+ int id = rs.getInt("id");
+ long time = rs.getLong("time");
+ String content = rs.getString("content");
+ YamlConfiguration conf = new YamlConfiguration();
+ try {
+ conf.loadFromString(content);
+ } catch (InvalidConfigurationException e) {
+ e.printStackTrace();
+ }
+ ItemStack displayItem = conf.getItemStack("display");
+ if (displayItem == null || displayItem.getAmount() == 0 || displayItem.getType() == Material.AIR) {
+ displayItem = new ItemStack(Material.BEDROCK);
+ }
+ ArrayList stacks = new ArrayList<>();
+ ConfigurationSection itemsSection = conf.getConfigurationSection("items");
+ for (String key : itemsSection.getKeys(false)) {
+ ItemStack stack = itemsSection.getItemStack(key);
+ if (stack != null && stack.getAmount() > 0 && stack.getType() != Material.AIR) {
+ stacks.add(stack);
+ }
+ }
+ ItemStack[] priceItems = stacks.toArray(new ItemStack[stacks.size()]);
+ int priceMoney = conf.getInt("money");
+ result.add(new DatabaseTreasureChestItem(displayItem, priceItems, priceMoney, time, id));
+ }
+ rs.close();
+ return result;
}
});
}
- public void deleteOldPlayerProfiles() throws SQLException {
- this.connection.runCommands(new SQLRunnable() {
+ public boolean deleteItem(UUID owner, int id) throws SQLException {
+ return this.connection.runCommands(new SQLRunnable() {
@Override
- public Void execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
- PreparedStatement smt = sqlConnection.getOrCreateStatement(deleteOldPlayerProfiles);
- smt.setLong(1, System.currentTimeMillis() - PlayerUUIDCache.PROFILE_PROPERTIES_CACHE_EXPIRATION_TIME);
- smt.executeUpdate();
- return null;
+ public Boolean execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
+ PreparedStatement smt = sqlConnection.getOrCreateStatement(removeContent);
+ smt.setInt(1, id);
+ smt.setString(2, owner.toString());
+ boolean updated = smt.executeUpdate() > 0;
+ return updated;
+ }
+ });
+ }
+
+ public int deleteOldItems(long days) throws SQLException {
+ return this.connection.runCommands(new SQLRunnable() {
+ @Override
+ public Integer execute(Connection connection, SQLConnection sqlConnection) throws SQLException {
+ PreparedStatement smt = sqlConnection.getOrCreateStatement(removeOldContent);
+ long minTime = System.currentTimeMillis() - days * 24 * 60 * 60 * 1000;
+ smt.setLong(1, minTime);
+ int updated = smt.executeUpdate();
+ return updated;
}
});
}
diff --git a/src/main/java/de/iani/treasurechest/worker/WorkEntry.java b/src/main/java/de/iani/treasurechest/worker/WorkEntry.java
new file mode 100644
index 0000000..7c1566a
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/worker/WorkEntry.java
@@ -0,0 +1,7 @@
+package de.iani.treasurechest.worker;
+
+import de.iani.treasurechest.database.TreasureChestDatabase;
+
+public interface WorkEntry {
+ void process(TreasureChestDatabase database);
+}
\ No newline at end of file
diff --git a/src/main/java/de/iani/treasurechest/worker/WorkerThread.java b/src/main/java/de/iani/treasurechest/worker/WorkerThread.java
new file mode 100644
index 0000000..5504eaf
--- /dev/null
+++ b/src/main/java/de/iani/treasurechest/worker/WorkerThread.java
@@ -0,0 +1,79 @@
+package de.iani.treasurechest.worker;
+
+import java.util.ArrayDeque;
+import java.util.logging.Level;
+
+import de.iani.treasurechest.TreasureChest;
+import de.iani.treasurechest.database.TreasureChestDatabase;
+
+public class WorkerThread extends Thread {
+
+ private TreasureChest plugin;
+ private TreasureChestDatabase database;
+ private boolean stopping;
+ private ArrayDeque work;
+
+ public WorkerThread(TreasureChest plugin) {
+ this.plugin = plugin;
+ this.work = new ArrayDeque();
+ this.database = plugin.getDatabase();
+ setName("TreasureChest worker");
+ start();
+ }
+
+ public void addWork(WorkEntry e) {
+ synchronized (work) {
+ work.addLast(e);
+ work.notify();
+ }
+ }
+
+ public void shutdown() {
+ synchronized (work) {
+ stopping = true;
+ work.notify();
+ }
+ boolean interrupt = false;
+ while (isAlive()) {
+ try {
+ join();
+ } catch (InterruptedException e) {
+ interrupt = true;
+ }
+ }
+ if (interrupt) {
+ Thread.currentThread().interrupt();
+ }
+ if (database != null) {
+ database.disconnect();
+ database = null;
+ }
+ }
+
+ @Override
+ public void run() {
+ WorkEntry e;
+ while (true) {
+ synchronized (work) {
+ e = work.pollFirst();
+ if (e == null) {
+ if (stopping) {
+ return;
+ }
+ try {
+ work.wait();
+ } catch (InterruptedException e1) {
+ Thread.currentThread().interrupt();
+ }
+ }
+ }
+ if (e != null && database != null) {
+ try {
+ e.process(database);
+ } catch (Exception er) {
+ plugin.getLogger().log(Level.SEVERE, "Error in TreasureChest worker thread", er);
+ }
+ }
+ }
+ }
+}