mirror of
https://github.com/CivMC/Civ.git
synced 2026-07-18 00:20:44 +00:00
Done with core stuff
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<UUID, DeliveryInventory> 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<UUID, DeliveryInventory>();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<String> tabComplete(CommandSender arg0, String[] arg1) {
|
||||
return 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 <mandatory>
|
||||
// parameters
|
||||
setUsage("/examplecommand <parameter1> [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<String> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<DeathInventory> getLastDeathInventories(UUID uuid, int limit) {
|
||||
List<DeathInventory> inventories = new LinkedList<DeathInventory>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<ItemStack> 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();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
complaintURL: https://www.reddit.com/message/compose?to=%2Fr%2FCivcraft
|
||||
database:
|
||||
|
||||
@@ -5,4 +5,5 @@ version: ${project.version}
|
||||
depend: [CivModCore]
|
||||
softdepend: []
|
||||
commands:
|
||||
present:
|
||||
permissions:
|
||||
|
||||
Reference in New Issue
Block a user