diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/Donum.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/Donum.java index f46f5a90d..f8d5eebf9 100644 --- a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/Donum.java +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/Donum.java @@ -1,6 +1,9 @@ package com.github.civcraft.donum; -import com.github.civcraft.donum.commands.CustomCommandHandler; +import org.bukkit.Bukkit; + +import com.github.civcraft.donum.commands.DonumCommandHandler; +import com.github.civcraft.donum.listeners.PlayerListener; import vg.civcraft.mc.civmodcore.ACivMod; @@ -8,14 +11,15 @@ public class Donum extends ACivMod { private static Donum instance; private static DonumManager manager; + private static DonumConfiguration config; public void onEnable() { super.onEnable(); instance = this; manager = new DonumManager(); - handle = new CustomCommandHandler(); + handle = new DonumCommandHandler(); handle.registerCommands(); - + Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); } public void onDisable() { @@ -34,5 +38,9 @@ public class Donum extends ACivMod { public static DonumManager getManager() { return manager; } + + public static DonumConfiguration getConfiguration() { + return config; + } } diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/DonumConfiguration.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/DonumConfiguration.java new file mode 100644 index 000000000..886e783a5 --- /dev/null +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/DonumConfiguration.java @@ -0,0 +1,60 @@ +package com.github.civcraft.donum; + +import org.apache.commons.lang.RandomStringUtils; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; + +public class DonumConfiguration { + + private String complaintURL; + private boolean isMercuryEnabled; + + private String host; + private String database; + private int port; + private String user; + private String password; + + + public void parse() { + Donum plugin = Donum.getInstance(); + plugin.saveDefaultConfig(); + plugin.reloadConfig(); + FileConfiguration config = plugin.getConfig(); + this.isMercuryEnabled = Bukkit.getPluginManager().isPluginEnabled("Mercury"); + this.complaintURL = config.getString("complaintURL",""); + this.host= config.getString("database.host", "localhost"); + this.database = config.getString("database.database", "global"); + this.port = config.getInt("database.port",3306); + this.user = config.getString("database.user", "global"); + this.password = config.getString("database.password", RandomStringUtils.random(16)); + } + + public String getComplaintURL() { + return complaintURL; + } + + public boolean isMercuryEnabled() { + return isMercuryEnabled; + } + + public String getHost() { + return host; + } + + public String getDatabaseName() { + return database; + } + + public int getPort() { + return port; + } + + public String getUser() { + return user; + } + + public String getPassword() { + return password; + } +} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/DonumManager.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/DonumManager.java index 4a49cb277..903f68d25 100644 --- a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/DonumManager.java +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/DonumManager.java @@ -2,12 +2,14 @@ package com.github.civcraft.donum; import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.PlayerInventory; import org.bukkit.scheduler.BukkitRunnable; +import com.github.civcraft.donum.database.Database; import com.github.civcraft.donum.database.DonumDAO; +import com.github.civcraft.donum.inventories.DeliveryInventory; import com.github.civcraft.donum.misc.ItemMapBlobHandling; import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; @@ -16,6 +18,16 @@ public class DonumManager { private DonumDAO database; private Map deliveryInventories; + + public DonumManager() { + DonumConfiguration config = Donum.getConfiguration(); + this.database = new DonumDAO(config.getHost(), config.getPort(), config.getDatabaseName(), config.getUser(), config.getPassword()); + this.deliveryInventories = new ConcurrentHashMap(); + } + + public DeliveryInventory getDeliveryInventory(UUID player) { + return deliveryInventories.get(player); + } public void loadPlayerData(UUID uuid, Inventory i) { Donum.getInstance().debug("Loading data for " + uuid.toString()); @@ -32,6 +44,15 @@ public class DonumManager { } } }.runTaskAsynchronously(Donum.getInstance()); + + new BukkitRunnable() { + + @Override + public void run() { + ItemMap delivery = database.getDeliveryInventory(uuid); + deliveryInventories.put(uuid, new DeliveryInventory(uuid, delivery)); + } + }.runTaskAsynchronously(Donum.getInstance()); } public void savePlayerData(UUID uuid, Inventory inventory) { @@ -46,7 +67,8 @@ public class DonumManager { @Override public void run() { - database.updateDeliveryInventory(uuid, del.getContent()); + database.updateDeliveryInventory(uuid, del.getInventory(), true); + deliveryInventories.remove(uuid); } }.runTaskAsynchronously(Donum.getInstance()); @@ -61,6 +83,17 @@ public class DonumManager { } }.runTaskAsynchronously(Donum.getInstance()); } + + public void saveDeathInventory(UUID uuid, ItemMap inventory) { + Donum.getInstance().debug("Saving death inventory for " + uuid.toString()); + new BukkitRunnable() { + + @Override + public void run() { + database.insertDeathInventory(uuid, inventory); + } + }; + } private void handleInventoryInconsistency(UUID player, ItemMap oldInventory, ItemMap newInventory) { Donum.getInstance().info("Creating diff of lost items for " + player); @@ -68,33 +101,4 @@ public class DonumManager { Donum.getInstance().debug("New inventory: " + newInventory.toString()); // TODO } - - private class DeliveryInventory { - private UUID owner; - private ItemMap content; - private boolean isDirty; - - private DeliveryInventory(UUID owner, ItemMap content) { - this.owner = owner; - this.content = content; - this.isDirty = false; - } - - private void setDirty() { - isDirty = true; - } - - private UUID getOwner() { - return owner; - } - - private ItemMap getContent() { - return content; - } - - private boolean isDirty() { - return isDirty; - } - } - } diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/CustomCommandHandler.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/CustomCommandHandler.java deleted file mode 100644 index b66653888..000000000 --- a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/CustomCommandHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.civcraft.donum.commands; -import vg.civcraft.mc.civmodcore.command.CommandHandler; - -public class CustomCommandHandler extends CommandHandler { - - //renaming this class to avoid conflicts with other plugins made based on this dummy is recommended, but not mandatory - - @Override - public void registerCommands() { - //register commands here like: - //addCommands(new YourCommand("commandToRunYourCommand")); - //YourCommand must be extending CivModCores PlayerCommand - } - - -} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/DonumCommandHandler.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/DonumCommandHandler.java new file mode 100644 index 000000000..48448ee3c --- /dev/null +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/DonumCommandHandler.java @@ -0,0 +1,14 @@ +package com.github.civcraft.donum.commands; +import com.github.civcraft.donum.commands.commands.OpenDeliveries; + +import vg.civcraft.mc.civmodcore.command.CommandHandler; + +public class DonumCommandHandler extends CommandHandler { + + @Override + public void registerCommands() { + addCommands(new OpenDeliveries("openDeliveries")); + } + + +} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/commands/OpenDeliveries.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/commands/OpenDeliveries.java new file mode 100644 index 000000000..1aa7a4245 --- /dev/null +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/commands/OpenDeliveries.java @@ -0,0 +1,48 @@ +package com.github.civcraft.donum.commands.commands; + +import java.util.List; +import java.util.UUID; + +import net.md_5.bungee.api.ChatColor; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.github.civcraft.donum.Donum; +import com.github.civcraft.donum.gui.DeliveryGUI; +import com.github.civcraft.donum.inventories.DeliveryInventory; + +import vg.civcraft.mc.civmodcore.command.PlayerCommand; + +public class OpenDeliveries extends PlayerCommand { + + public OpenDeliveries(String name) { + super(name); + setIdentifier("present"); + setDescription("Opens your delivery inventory"); + setUsage("/present"); + setArguments(0, 0); + } + + @Override + public boolean execute(CommandSender sender, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.RED + "Please no"); + return true; + } + UUID uuid = ((Player) sender).getUniqueId(); + DeliveryInventory delInv = Donum.getManager().getDeliveryInventory(uuid); + if (delInv == null) { + sender.sendMessage(ChatColor.RED + "Your inventory isnt loaded yet, try again in a few seconds"); + return true; + } + DeliveryGUI delGUI = new DeliveryGUI(uuid, delInv); + delGUI.showScreen(); + return true; + } + + @Override + public List tabComplete(CommandSender arg0, String[] arg1) { + return null; + } +} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/commands/TemplateCommand.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/commands/TemplateCommand.java deleted file mode 100644 index 509921a93..000000000 --- a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/commands/commands/TemplateCommand.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.github.civcraft.donum.commands.commands; - -import java.util.List; - -import org.bukkit.command.CommandSender; - -import vg.civcraft.mc.civmodcore.command.PlayerCommand; - -/** - * Template for new commands - * - */ -public class TemplateCommand extends PlayerCommand { - - public TemplateCommand(String name) { - super(name); - // internal identifier used, this has to be unique for the plugin - setIdentifier("exampleTemplate0815"); - // description displayed when the player runs the command wrong - setDescription("This command doesnt even exist"); - // Correct usage of this command with [optional] and - // parameters - setUsage("/examplecommand [parameter2]"); - // minimum and maximum amount of arguments this command takes. If the - // entered parameter amount is not within the range, the command will - // error to the player and show the correct usage - setArguments(0, 10); - } - - @Override - public boolean execute(CommandSender sender, String[] args) { - // code to run if the command is executed. Note that sender may be - // console, so casting it to player right away is not safe - // returning false will display the command description and usage to the - // player - // returning true will do nothing - return true; - } - - @Override - public List tabComplete(CommandSender arg0, String[] arg1) { - // Sets custom auto complete functionality for this command. The strings - // in the list returned will be suggested to the player in alphabetical - // order, not the order of the list. Additionally returning null will - // leave the autocompletion to minecrafts default behavior, which - // attempts to complete the last word as the name of a player currently - // online on the server - return null; - } - -} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/database/DonumDAO.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/database/DonumDAO.java index 51520e7f0..11321b3a2 100644 --- a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/database/DonumDAO.java +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/database/DonumDAO.java @@ -4,6 +4,9 @@ import java.sql.Blob; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; import java.util.UUID; import javax.sql.rowset.serial.SerialBlob; @@ -13,13 +16,14 @@ import org.bukkit.Bukkit; import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; import com.github.civcraft.donum.Donum; +import com.github.civcraft.donum.inventories.DeathInventory; import com.github.civcraft.donum.misc.ItemMapBlobHandling; public class DonumDAO { private Database db; - public DonumDAO(String username, String host, int port, String password, String dbname) { + public DonumDAO(String host, int port, String dbname, String username, String password) { db = new Database(host, port, dbname, username, password, Donum.getInstance().getLogger()); if (!db.connect()) { Donum.getInstance().severe("Could not establish database connection, shutting down"); @@ -36,10 +40,23 @@ public class DonumDAO { db.execute("create table if not exists db_version (db_version int(11), plugin_name varchar(40), timestamp datetime default now());"); int version = getVersion(); if (version == 0) { - db.execute("create table if not exists deliveryInventories (uuid varchar(36), inventory blob not null, lastUpdate datetime not null default now(), primary key (uuid));"); - db.execute("create table if not exists logoutInventories (uuid varchar(36), inventory blob not null, hash int, lastUpdate datetime not null default now(),primary key(uuid));"); + db.execute("create table if not exists deliveryInventories (uuid varchar(36), inventory blob not null, " + + "lastUpdate datetime not null default now(), primary key (uuid));"); + db.execute("create table if not exists deliveryAdditions (deliveryId int not null auto_increment, uuid varchar(36) not null, " + + "inventory blob not null, creationTime datetime not null default now(), index deliveryAdditionsUuidIndex (uuid), " + + "primary key(deliveryId), foreign key (uuid) references deliveryInventories(uuid));"); + db.execute("create table if not exists deliveryInventoryLocks (uuid varchar(36) not null, creationTime datetime not null default now(), " + + "primary key(uuid), foreign key (uuid) references deliveryInventories(uuid));"); + db.execute("create table if not exists logoutInventories (uuid varchar(36), inventory blob not null, hash int, " + + "creationTime datetime not null default now(), index logOutInventoryLastUpdateIndex (lastUpdate), primary key(uuid, creationTime));"); + db.execute("create domain if not exists donumHandlingState as varchar(20) default 'NEW' " + + "constraint validValues check (value in ('NEW','ITEMS_RETURNED','IGNORED')) not deferrable;"); + db.execute("create table if not exists loggedInconsistencies (uuid varchar(36), inventory blob not null, state donumHandlingState not null, " + + "creationTime datetime not null default now(), lastUpdate datetime not null default now(), index loggedInconsistenciesUuidIndex (uuid)," + + "index loggedInconsistenciesState (state));"); + db.execute("create table if not exists deathInventories (uuid varchar(36), inventory blob not null, returned boolean not null default false, " + + "creationTime datetime not null default now(), index deathInventoriesUuidIndex (uuid));"); } - } /** @@ -75,6 +92,25 @@ public class DonumDAO { } } + public synchronized boolean getLock(UUID uuid) { + try (PreparedStatement getLock = db.prepareStatement("insert into deliveryInventoryLocks (uuid) values(?);")) { + getLock.setString(1, uuid.toString()); + getLock.execute(); + return true; + } catch (SQLException e) { + return false; + } + } + + public synchronized void freeLock(UUID uuid) { + try (PreparedStatement freeLock = db.prepareStatement("delete from deliveryInventoryLocks where uuid=?;")) { + freeLock.setString(1, uuid.toString()); + freeLock.execute(); + } catch (SQLException e) { + Donum.getInstance().warning("Failed to free lock for " + uuid.toString() + ": " + e); + } + } + /** * Gets the delivery inventory stored for the given player. If a players * delivery inventory is empty, no data on it will be in the database, in @@ -86,6 +122,12 @@ public class DonumDAO { * @return ItemMap representing the players delivery inventory */ public ItemMap getDeliveryInventory(UUID uuid) { + while (!getLock(uuid)) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } try (PreparedStatement ps = db.prepareStatement("select inventory from deliveryInventories where uuid=?;")) { ps.setString(1, uuid.toString()); ResultSet rs = ps.executeQuery(); @@ -96,10 +138,48 @@ public class DonumDAO { int blobLength = (int) blob.length(); byte[] blobAsBytes = blob.getBytes(1, blobLength); blob.free(); - return ItemMapBlobHandling.turnBlobIntoItemMap(blobAsBytes); + ItemMap loadedMap = ItemMapBlobHandling.turnBlobIntoItemMap(blobAsBytes); + try (PreparedStatement loadToProcess = db + .prepareStatement("select deliveryId, inventory from deliveryAdditions where uuid=?;")) { + loadToProcess.setString(1, uuid.toString()); + ResultSet toProcess = loadToProcess.executeQuery(); + boolean changes = false; + while (toProcess.next()) { + changes = true; + int id = toProcess.getInt(1); + Blob addBlob = toProcess.getBlob(2); + int blobLengthInner = (int) addBlob.length(); + byte[] blobInnerAsBytes = addBlob.getBytes(1, blobLengthInner); + addBlob.free(); + ItemMap mapToAdd = ItemMapBlobHandling.turnBlobIntoItemMap(blobInnerAsBytes); + Donum.getInstance().info("Adding " + mapToAdd + " to delivery inventory for " + uuid.toString()); + loadedMap.addAll(mapToAdd.getItemStackRepresentation()); + try (PreparedStatement cleanPendingAdditions = db + .prepareStatement("delete from deliveryAdditions where deliveryId=?;")) { + cleanPendingAdditions.setInt(1, id); + cleanPendingAdditions.execute(); + } + } + if (changes) { + updateDeliveryInventory(uuid, loadedMap, false); + } + } + return loadedMap; } catch (SQLException e) { Donum.getInstance().warning("Failed to get delivery inventory for player " + uuid + " ; " + e); return new ItemMap(); + } finally { + freeLock(uuid); + } + } + + public void stageDeliveryAddition(UUID uuid, ItemMap addition) { + try (PreparedStatement ps = db.prepareStatement("insert into deliveryAdditions (uuid,inventory) values(?,?);")) { + ps.setString(1, uuid.toString()); + ps.setBlob(2, new SerialBlob(ItemMapBlobHandling.turnItemMapIntoBlob(addition))); + ps.execute(); + } catch (SQLException e) { + Donum.getInstance().warning("Failed to stage delivery inventory addition for player " + uuid + " ; " + e); } } @@ -112,20 +192,12 @@ public class DonumDAO { * @param im * DeliveryInventory to save */ - public void updateDeliveryInventory(UUID uuid, ItemMap im) { - if (im.getTotalItemAmount() == 0) { - // no items in the inventory, we can just remove its entry completly - // from the db - try (PreparedStatement ps = db.prepareStatement("delete from deliveryInventories where uuid=?;")) { - Donum.getInstance().debug( - "Delivery inventory for " + uuid.toString() + " is empty, removing any records from the db"); - ps.setString(1, uuid.toString()); - ps.execute(); - } catch (SQLException e) { - Donum.getInstance().warning( - "Error deleting record of delivery inventory for player " + uuid + " ; " + e); + public void updateDeliveryInventory(UUID uuid, ItemMap im, boolean acquireLock) { + while (acquireLock && !getLock(uuid)) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { } - return; } try (PreparedStatement ps = db .prepareStatement("insert into deliveryInventories (uuid,inventory) values(?,?) on duplicate key update inventory=values(inventory);")) { @@ -135,6 +207,8 @@ public class DonumDAO { ps.execute(); } catch (SQLException e) { Donum.getInstance().warning("Error updating record of delivery inventory for player " + uuid + " ; " + e); + } finally { + freeLock(uuid); } } @@ -155,8 +229,10 @@ public class DonumDAO { * they dont and there was an issue */ public ItemMap checkForInventoryInconsistency(UUID uuid, int hash) { - try (PreparedStatement ps = db.prepareStatement("select inventory, hash from logoutInventories where uuid=?;")) { + try (PreparedStatement ps = db + .prepareStatement("select inventory, hash from logoutInventories where uuid=? and creationTime=(select max(creationTime) from logoutInventories where uuid=?);")) { ps.setString(1, uuid.toString()); + ps.setString(2, uuid.toString()); ResultSet rs = ps.executeQuery(); if (!rs.next()) { Donum.getInstance().debug("Found no logout inventory for " + uuid + ", login hash: " + hash); @@ -188,13 +264,64 @@ public class DonumDAO { */ public void insertLogoutInventory(UUID uuid, ItemMap items) { try (PreparedStatement ps = db - .prepareStatement("insert into logoutInventories (uuid,inventory,hash) values(?,?,?) on duplicate key update inventory=values(inventory), hash = values(hash);")) { + .prepareStatement("insert into logoutInventories (uuid,inventory,hash) values(?,?,?);")) { ps.setString(1, uuid.toString()); ps.setBlob(2, new SerialBlob(ItemMapBlobHandling.turnItemMapIntoBlob(items))); ps.setInt(3, items.hashCode()); ps.execute(); } catch (SQLException e) { - Donum.getInstance().warning("Failed to insert logout inventor for player " + uuid + " ; " + e); + Donum.getInstance().warning("Failed to insert logout inventory for player " + uuid + " ; " + e); } } + + /** + * Saves the given ItemMap for the given UUID as death inventory + * + * @param uuid + * UUID of the player + * @param items + * ItemMap representing the players inventory when dying + */ + public void insertDeathInventory(UUID uuid, ItemMap inventory) { + try (PreparedStatement ps = db.prepareStatement("insert into deathInventories (uuid,inventory) values(?,?);")) { + ps.setString(1, uuid.toString()); + ps.setBlob(2, new SerialBlob(ItemMapBlobHandling.turnItemMapIntoBlob(inventory))); + ps.execute(); + } catch (SQLException e) { + Donum.getInstance().warning("Failed to insert death inventory for player " + uuid + " ; " + e); + } + } + + /** + * Loads death inventories saved for the given players, sorted from newest + * to oldest + * + * @param uuid + * UUID of the player of which we want the death inventories + * @param limit + * How many inventories to load + * @return Deathinventories of the player + */ + public List getLastDeathInventories(UUID uuid, int limit) { + List inventories = new LinkedList(); + try (PreparedStatement ps = db + .prepareStatement("select inventory, creationTime, returned from deathInventories where uuid=? order by creationTime desc limit ?);")) { + ps.setString(1, uuid.toString()); + ps.setInt(2, limit); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + Blob blob = rs.getBlob(1); + Date date = rs.getDate(2); + boolean returned = rs.getBoolean(3); + int blobLength = (int) blob.length(); + byte[] blobAsBytes = blob.getBytes(1, blobLength); + blob.free(); + ItemMap im = ItemMapBlobHandling.turnBlobIntoItemMap(blobAsBytes); + inventories.add(new DeathInventory(uuid, im, returned, date)); + } + } catch (SQLException e) { + Donum.getInstance().warning("Failed to load death inventores for player " + uuid + " ; " + e); + } + return inventories; + } } diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/gui/DeliveryGUI.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/gui/DeliveryGUI.java new file mode 100644 index 000000000..2b7268156 --- /dev/null +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/gui/DeliveryGUI.java @@ -0,0 +1,142 @@ +package com.github.civcraft.donum.gui; + +import java.util.List; +import java.util.UUID; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import com.github.civcraft.donum.Donum; +import com.github.civcraft.donum.inventories.DeliveryInventory; + +import vg.civcraft.mc.civmodcore.inventorygui.Clickable; +import vg.civcraft.mc.civmodcore.inventorygui.ClickableInventory; +import vg.civcraft.mc.civmodcore.itemHandling.ISUtils; +import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; + +public class DeliveryGUI { + + private UUID viewer; + private int currentPage; + private DeliveryInventory inventory; + + public DeliveryGUI(UUID viewer, DeliveryInventory inventory) { + this.inventory = inventory; + this.viewer = viewer; + this.currentPage = 0; + } + + public void showScreen() { + Player p = Bukkit.getPlayer(viewer); + if (p == null) { + return; + } + ClickableInventory.forceCloseInventory(p); + ClickableInventory ci = new ClickableInventory(54, "Delivery inventory"); + List stacks = inventory.getInventory().getItemStackRepresentation(); + if (stacks.size() < 45 * currentPage) { + // would show an empty page, so go to previous + currentPage--; + showScreen(); + } + for (int i = 45 * currentPage; i < 45 * (currentPage + 1) && i < stacks.size(); i++) { + ci.setSlot(createRemoveItemClickable(stacks.get(i)), i - (45 * currentPage)); + } + // previous button + if (currentPage > 0) { + ItemStack back = new ItemStack(Material.ARROW); + ISUtils.setName(back, ChatColor.GOLD + "Go to previous page"); + Clickable baCl = new Clickable(back) { + + @Override + public void clicked(Player arg0) { + if (currentPage > 0) { + currentPage--; + } + showScreen(); + } + }; + ci.setSlot(baCl, 45); + } + // next button + if ((45 * (currentPage + 1)) <= stacks.size()) { + ItemStack forward = new ItemStack(Material.ARROW); + ISUtils.setName(forward, ChatColor.GOLD + "Go to next page"); + Clickable forCl = new Clickable(forward) { + + @Override + public void clicked(Player arg0) { + if ((45 * (currentPage + 1)) <= stacks.size()) { + currentPage++; + } + showScreen(); + } + }; + ci.setSlot(forCl, 53); + } + // exit button + ItemStack backToOverview = new ItemStack(Material.WOOD_DOOR); + ISUtils.setName(backToOverview, ChatColor.GOLD + "Close"); + ci.setSlot(new Clickable(backToOverview) { + + @Override + public void clicked(Player arg0) { + // just let it close, dont do anything + } + }, 49); + + // complain button + ItemStack gibStuffBack = new ItemStack(Material.SIGN); + ISUtils.setName(gibStuffBack, ChatColor.GOLD + "Request item return"); + ISUtils.addLore(gibStuffBack, ChatColor.AQUA + "If you think you lost items due to a glitch", ChatColor.AQUA + + "you can send us a message", ChatColor.AQUA + "to get your items back", ChatColor.GREEN + + "Click here to do so"); + Clickable openComplaintForm = new Clickable(gibStuffBack) { + + @Override + public void clicked(Player p) { + TextComponent link = new TextComponent( + "Click this message to write the admins a message about lost items. This will open a new tab in your default browser!"); + link.setColor(ChatColor.GREEN); + link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, Donum.getConfiguration() + .getComplaintURL())); + link.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("Open link") + .create())); + p.spigot().sendMessage(link); + } + }; + ci.setSlot(openComplaintForm, 47); + + ci.showInventory(p); + } + + private Clickable createRemoveItemClickable(final ItemStack is) { + return new Clickable(is) { + + @Override + public void clicked(Player p) { + PlayerInventory pInv = p.getInventory(); + if (new ItemMap(is).fitsIn(pInv)) { + Donum.getInstance().debug(p.getName() + " took " + is.toString() + " from delivery inventory"); + inventory.getInventory().removeItemStack(is); + pInv.addItem(is); + inventory.setDirty(true); + } else { + p.sendMessage(ChatColor.RED + "There is not enough space in your inventory"); + } + p.updateInventory(); + showScreen(); + } + }; + } + +} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/AbstractInventoryStorage.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/AbstractInventoryStorage.java new file mode 100644 index 000000000..cc7c7a927 --- /dev/null +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/AbstractInventoryStorage.java @@ -0,0 +1,25 @@ +package com.github.civcraft.donum.inventories; + +import java.util.UUID; + +import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; + +public class AbstractInventoryStorage { + + private UUID owner; + protected ItemMap inventory; + + public AbstractInventoryStorage(UUID owner, ItemMap inventory) { + this.owner = owner; + this.inventory = inventory; + } + + public UUID getOwner() { + return owner; + } + + public ItemMap getInventory() { + return inventory; + } + +} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/DeathInventory.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/DeathInventory.java new file mode 100644 index 000000000..050851961 --- /dev/null +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/DeathInventory.java @@ -0,0 +1,27 @@ +package com.github.civcraft.donum.inventories; + +import java.util.Date; +import java.util.UUID; + +import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; + +public class DeathInventory extends AbstractInventoryStorage { + + private boolean returned; + private Date deathTime; + + public DeathInventory(UUID owner, ItemMap inventory, boolean returned, Date deathTime) { + super(owner, inventory); + this.returned = returned; + this.deathTime = deathTime; + } + + public boolean wasReturned() { + return returned; + } + + public Date getDeathTime() { + return deathTime; + } + +} diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/DeliveryInventory.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/DeliveryInventory.java new file mode 100644 index 000000000..9a58f706f --- /dev/null +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/inventories/DeliveryInventory.java @@ -0,0 +1,23 @@ +package com.github.civcraft.donum.inventories; + +import java.util.UUID; + +import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; + +public class DeliveryInventory extends AbstractInventoryStorage { + + private boolean dirty; + + public DeliveryInventory(UUID owner, ItemMap content) { + super(owner, content); + this.dirty = false; + } + + public void setDirty(boolean dirty) { + this.dirty = dirty; + } + + public boolean isDirty() { + return dirty; + } +} \ No newline at end of file diff --git a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/listeners/LogInOutListener.java b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/listeners/PlayerListener.java similarity index 67% rename from plugins/donum-paper/src/main/java/com/github/civcraft/donum/listeners/LogInOutListener.java rename to plugins/donum-paper/src/main/java/com/github/civcraft/donum/listeners/PlayerListener.java index b936e21d3..ba814164d 100644 --- a/plugins/donum-paper/src/main/java/com/github/civcraft/donum/listeners/LogInOutListener.java +++ b/plugins/donum-paper/src/main/java/com/github/civcraft/donum/listeners/PlayerListener.java @@ -3,12 +3,15 @@ package com.github.civcraft.donum.listeners; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import vg.civcraft.mc.civmodcore.itemHandling.ItemMap; + import com.github.civcraft.donum.Donum; -public class LogInOutListener implements Listener { +public class PlayerListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void playerJoin(PlayerJoinEvent e) { @@ -19,4 +22,9 @@ public class LogInOutListener implements Listener { public void playerQuit(PlayerQuitEvent e) { Donum.getManager().savePlayerData(e.getPlayer().getUniqueId(), e.getPlayer().getInventory()); } + + @EventHandler + public void playerWasStupid(PlayerDeathEvent e) { + Donum.getManager().saveDeathInventory(e.getEntity().getUniqueId(), new ItemMap(e.getDrops())); + } } diff --git a/plugins/donum-paper/src/main/resources/config.yml b/plugins/donum-paper/src/main/resources/config.yml index e69de29bb..ee4156d7e 100644 --- a/plugins/donum-paper/src/main/resources/config.yml +++ b/plugins/donum-paper/src/main/resources/config.yml @@ -0,0 +1,3 @@ +complaintURL: https://www.reddit.com/message/compose?to=%2Fr%2FCivcraft +database: + \ No newline at end of file diff --git a/plugins/donum-paper/src/main/resources/plugin.yml b/plugins/donum-paper/src/main/resources/plugin.yml index ae4056c50..9a9cc1298 100644 --- a/plugins/donum-paper/src/main/resources/plugin.yml +++ b/plugins/donum-paper/src/main/resources/plugin.yml @@ -5,4 +5,5 @@ version: ${project.version} depend: [CivModCore] softdepend: [] commands: + present: permissions: