From 5a338937e7e76931b3dbac2784bf85b3b582a5af Mon Sep 17 00:00:00 2001 From: Trent Hensler Date: Sun, 24 Dec 2017 22:26:30 -0600 Subject: [PATCH] Base64 vault management --- pom.xml | 2 +- .../drtshock/playervaults/PlayerVaults.java | 46 +- .../playervaults/commands/VaultCommand.java | 13 +- .../converters/BackpackConverter.java | 7 +- .../playervaults/listeners/Listeners.java | 31 +- .../playervaults/listeners/SignListener.java | 5 +- .../listeners/VaultPreloadListener.java | 8 +- .../playervaults/tasks/Base64Conversion.java | 90 +++ .../playervaults/tasks/UUIDConversion.java | 2 - .../drtshock/playervaults/util/Updater.java | 537 ------------------ .../vaultmanagement/Base64Serialization.java | 62 ++ .../vaultmanagement/EconomyOperations.java | 2 +- .../vaultmanagement/Serialization.java | 15 +- .../vaultmanagement/UUIDVaultManager.java | 32 +- .../vaultmanagement/VaultManager.java | 286 ++++++++++ .../vaultmanagement/VaultOperations.java | 34 +- src/main/resources/config.yml | 7 - 17 files changed, 531 insertions(+), 648 deletions(-) create mode 100644 src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java delete mode 100644 src/main/java/com/drtshock/playervaults/util/Updater.java create mode 100644 src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java create mode 100644 src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java diff --git a/pom.xml b/pom.xml index 8e56182..7049c49 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.drtshock PlayerVaults - 3.6.0 + 4.0.0-SNAPSHOT PlayerVaults http://dev.bukkit.org/pancakes/playervaults/ diff --git a/src/main/java/com/drtshock/playervaults/PlayerVaults.java b/src/main/java/com/drtshock/playervaults/PlayerVaults.java index ba1ec19..4f86a88 100644 --- a/src/main/java/com/drtshock/playervaults/PlayerVaults.java +++ b/src/main/java/com/drtshock/playervaults/PlayerVaults.java @@ -24,11 +24,12 @@ import com.drtshock.playervaults.commands.VaultCommand; import com.drtshock.playervaults.listeners.Listeners; import com.drtshock.playervaults.listeners.SignListener; import com.drtshock.playervaults.listeners.VaultPreloadListener; +import com.drtshock.playervaults.tasks.Base64Conversion; import com.drtshock.playervaults.tasks.Cleanup; import com.drtshock.playervaults.tasks.UUIDConversion; import com.drtshock.playervaults.util.Lang; -import com.drtshock.playervaults.util.Updater; import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; import com.google.common.base.Charsets; import net.milkbowl.vault.economy.Economy; @@ -75,6 +76,7 @@ public class PlayerVaults extends JavaPlugin { private boolean saveQueued; private boolean backupsEnabled; private File backupsFolder = null; + private File uuidData; private File vaultData; private final Set blockedMats = new HashSet<>(); @@ -84,10 +86,14 @@ public class PlayerVaults extends JavaPlugin { loadConfig(); DEBUG = getConfig().getBoolean("debug", false); debug("config", System.currentTimeMillis()); - vaultData = new File(this.getDataFolder(), "uuidvaults"); + uuidData = new File(this.getDataFolder(), "uuidvaults"); + vaultData = new File(this.getDataFolder(), "base64vaults"); debug("vaultdata", System.currentTimeMillis()); getServer().getScheduler().runTask(this, new UUIDConversion()); // Convert to UUIDs first. Class checks if necessary. debug("uuid conversion", System.currentTimeMillis()); + new VaultManager(); + getServer().getScheduler().runTask(this, new Base64Conversion()); + debug("base64 conversion", System.currentTimeMillis()); loadLang(); debug("lang", System.currentTimeMillis()); new UUIDVaultManager(); @@ -98,7 +104,6 @@ public class PlayerVaults extends JavaPlugin { this.backupsEnabled = this.getConfig().getBoolean("backups.enabled", true); loadSigns(); debug("loaded signs", System.currentTimeMillis()); - checkUpdate(); debug("check update", System.currentTimeMillis()); getCommand("pv").setExecutor(new VaultCommand()); getCommand("pvdel").setExecutor(new DeleteCommand()); @@ -148,36 +153,15 @@ public class PlayerVaults extends JavaPlugin { @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String args[]) { - if (cmd.getName().equals("pvreload")) { + if (cmd.getName().equalsIgnoreCase("pvreload")) { reloadConfig(); loadConfig(); // To update blocked materials. loadLang(); - sender.sendMessage(ChatColor.GREEN + "Reloaded PlayerVaults' configuration and lang files."); + sender.sendMessage(ChatColor.GREEN + "Reloaded PlayerVault's configuration and lang files."); } return true; } - protected void checkUpdate() { - if (getConfig().getBoolean("check-update", true)) { - final PlayerVaults plugin = this; - final File file = this.getFile(); - final Updater.UpdateType updateType = getConfig().getBoolean("download-update", true) ? Updater.UpdateType.DEFAULT : Updater.UpdateType.NO_DOWNLOAD; - final Updater updater = new Updater(plugin, 50123, file, updateType, false); - getServer().getScheduler().runTaskAsynchronously(this, new Runnable() { - @Override - public void run() { - update = updater.getResult() == Updater.UpdateResult.UPDATE_AVAILABLE; - newVersion = updater.getLatestName(); - if (updater.getResult() == Updater.UpdateResult.SUCCESS) { - getLogger().log(Level.INFO, "Successfully updated PlayerVaults to version {0} for next restart!", updater.getLatestName()); - } else if (updater.getResult() == Updater.UpdateResult.NO_UPDATE) { - getLogger().log(Level.INFO, "We didn't find an update!"); - } - } - }); - } - } - private boolean setupEconomy() { if (getServer().getPluginManager().getPlugin("Vault") == null) { return false; @@ -364,6 +348,16 @@ public class PlayerVaults extends JavaPlugin { return this.vaultData; } + /** + * Get the legacy UUID vault data folder. + * Deprecated in favor of base64 data. + * @return + */ + @Deprecated + public File getUuidData() { + return this.uuidData; + } + public boolean isBackupsEnabled() { return this.backupsEnabled; } diff --git a/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java b/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java index 31105bd..deae74c 100644 --- a/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java +++ b/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java @@ -2,7 +2,7 @@ package com.drtshock.playervaults.commands; import com.drtshock.playervaults.PlayerVaults; import com.drtshock.playervaults.util.Lang; -import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultOperations; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; import org.bukkit.Bukkit; @@ -41,7 +41,7 @@ public class VaultCommand implements CommandExecutor { break; } - YamlConfiguration file = UUIDVaultManager.getInstance().getPlayerVaultFile(searchPlayer.getUniqueId()); + YamlConfiguration file = VaultManager.getInstance().getPlayerVaultFile(searchPlayer.getUniqueId()); if (file == null) { sender.sendMessage(Lang.TITLE.toString() + Lang.VAULT_DOES_NOT_EXIST.toString()); } else { @@ -55,7 +55,7 @@ public class VaultCommand implements CommandExecutor { } break; case 2: - if(!player.hasPermission("playervaults.admin")) { + if (!player.hasPermission("playervaults.admin")) { player.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS.toString()); break; } @@ -68,8 +68,11 @@ public class VaultCommand implements CommandExecutor { return true; } - if (VaultOperations.openOtherVault(player, args[0], args[1])) { - PlayerVaults.getInstance().getInVault().put(player.getUniqueId().toString(), new VaultViewInfo(args[0], number)); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(args[0]); + if (offlinePlayer != null && VaultOperations.openOtherVault(player, offlinePlayer.getUniqueId(), args[1])) { + PlayerVaults.getInstance().getInVault().put(player.getUniqueId().toString(), new VaultViewInfo(offlinePlayer.getUniqueId(), number)); + } else { + sender.sendMessage(Lang.TITLE.toString() + Lang.NO_PLAYER_FOUND.toString().replaceAll("%p", args[0])); } break; default: diff --git a/src/main/java/com/drtshock/playervaults/converters/BackpackConverter.java b/src/main/java/com/drtshock/playervaults/converters/BackpackConverter.java index 8e04921..c3c97e6 100644 --- a/src/main/java/com/drtshock/playervaults/converters/BackpackConverter.java +++ b/src/main/java/com/drtshock/playervaults/converters/BackpackConverter.java @@ -1,7 +1,7 @@ package com.drtshock.playervaults.converters; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.turt2live.uuid.PlayerRecord; import com.turt2live.uuid.ServiceProvider; import org.bukkit.command.CommandSender; @@ -12,7 +12,6 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import java.io.File; -import java.io.IOException; import java.util.UUID; /** @@ -50,7 +49,7 @@ public class BackpackConverter implements Converter { private int convert(File worldFolder, int intoVaultNum, ServiceProvider uuidProvider) { PlayerVaults plugin = PlayerVaults.getInstance(); - UUIDVaultManager vaults = UUIDVaultManager.getInstance(); + VaultManager vaults = VaultManager.getInstance(); int converted = 0; long lastUpdate = 0; File[] files = worldFolder.listFiles(); @@ -82,7 +81,7 @@ public class BackpackConverter implements Converter { // Overwrite vault.setItem(Integer.parseInt(key.split(" ")[1]), item); } - vaults.saveVault(vault, uuid.toString(), intoVaultNum); + vaults.saveVault(vault, uuid, intoVaultNum); converted++; if (System.currentTimeMillis() - lastUpdate >= 1500) { diff --git a/src/main/java/com/drtshock/playervaults/listeners/Listeners.java b/src/main/java/com/drtshock/playervaults/listeners/Listeners.java index ad0fc55..52ddb69 100644 --- a/src/main/java/com/drtshock/playervaults/listeners/Listeners.java +++ b/src/main/java/com/drtshock/playervaults/listeners/Listeners.java @@ -18,8 +18,9 @@ package com.drtshock.playervaults.listeners; import com.drtshock.playervaults.PlayerVaults; import com.drtshock.playervaults.util.Lang; -import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; + import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.EntityType; @@ -39,11 +40,12 @@ import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; + @SuppressWarnings("unused") public class Listeners implements Listener { public final PlayerVaults plugin; - private final UUIDVaultManager vaultManager = UUIDVaultManager.getInstance(); + private final VaultManager vaultManager = VaultManager.getInstance(); public Listeners(PlayerVaults playerVaults) { this.plugin = playerVaults; @@ -51,21 +53,16 @@ public class Listeners implements Listener { public void saveVault(Player player, Inventory inventory) { if (plugin.getInVault().containsKey(player.getUniqueId().toString())) { + + Inventory inv = Bukkit.createInventory(null, 6 * 9); + inv.setContents(inventory.getContents().clone()); + + if (inventory.getViewers().size() == 1) { + VaultViewInfo info = plugin.getInVault().get(player.getUniqueId().toString()); + vaultManager.saveVault(inv, info.getHolderUUID(), info.getNumber()); + plugin.getOpenInventories().remove(info.toString()); + } - VaultViewInfo info = plugin.getInVault().get(player.getUniqueId().toString()); - Inventory inv = Bukkit.createInventory(null, 6 * 9); - inv.setContents(inventory.getContents().clone()); - - if (inventory.getViewers().size() == 1 || info.getHolderUUID() == null) { - // DON'T save when others are viewing. Caused saving as username.yml - // TODO: verify this doesn't break faction / group vaults. - return; - } - - String target = info.getHolderUUID().toString(); - vaultManager.saveVault(inv, target, info.getNumber()); - - plugin.getOpenInventories().remove(info.toString()); plugin.getInVault().remove(player.getUniqueId().toString()); } } @@ -146,7 +143,7 @@ public class Listeners implements Listener { } } } - + @EventHandler(ignoreCancelled = true) public void onDrag(InventoryDragEvent event) { if (!(event.getWhoClicked() instanceof Player)) { diff --git a/src/main/java/com/drtshock/playervaults/listeners/SignListener.java b/src/main/java/com/drtshock/playervaults/listeners/SignListener.java index 3c4e283..f1bb3de 100644 --- a/src/main/java/com/drtshock/playervaults/listeners/SignListener.java +++ b/src/main/java/com/drtshock/playervaults/listeners/SignListener.java @@ -3,6 +3,7 @@ package com.drtshock.playervaults.listeners; import com.drtshock.playervaults.PlayerVaults; import com.drtshock.playervaults.util.Lang; import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultOperations; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; import org.bukkit.Bukkit; @@ -93,7 +94,7 @@ public class SignListener implements Listener { if (self) { // We already checked that they can use signs, now lets check if they have this many vaults. if (VaultOperations.checkPerms(player, num)) { - Inventory inv = UUIDVaultManager.getInstance().loadOwnVault(player, num, VaultOperations.getMaxVaultSize(player)); + Inventory inv = VaultManager.getInstance().loadOwnVault(player, num, VaultOperations.getMaxVaultSize(player)); if (inv != null) { player.openInventory(inv); } @@ -102,7 +103,7 @@ public class SignListener implements Listener { return; // Otherwise it would try to add vault view info down there. } } else { - Inventory inv = UUIDVaultManager.getInstance().loadOtherVault(offlinePlayer.getUniqueId().toString(), num, VaultOperations.getMaxVaultSize(offlinePlayer)); + Inventory inv = VaultManager.getInstance().loadOtherVault(offlinePlayer.getUniqueId(), num, VaultOperations.getMaxVaultSize(offlinePlayer)); if (inv == null) { player.sendMessage(Lang.TITLE.toString() + Lang.VAULT_DOES_NOT_EXIST.toString()); } else { diff --git a/src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java b/src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java index 531692f..f3c8d80 100644 --- a/src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java +++ b/src/main/java/com/drtshock/playervaults/listeners/VaultPreloadListener.java @@ -1,7 +1,7 @@ package com.drtshock.playervaults.listeners; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import com.drtshock.playervaults.vaultmanagement.VaultManager; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -13,7 +13,7 @@ import java.util.UUID; public class VaultPreloadListener implements Listener { - final UUIDVaultManager vm = UUIDVaultManager.getInstance(); + final VaultManager vm = VaultManager.getInstance(); @EventHandler(priority = EventPriority.MONITOR) public void onPlayerJoin(PlayerJoinEvent event) { @@ -21,13 +21,13 @@ public class VaultPreloadListener implements Listener { new BukkitRunnable() { @Override public void run() { - vm.cachePlayerVaultFile(uuid.toString()); + vm.cachePlayerVaultFile(uuid); } }.runTaskAsynchronously(PlayerVaults.getInstance()); } @EventHandler(priority = EventPriority.MONITOR) public void onPlayerQuit(PlayerQuitEvent event) { - vm.removeCachedPlayerVaultFile(event.getPlayer().getUniqueId().toString()); + vm.removeCachedPlayerVaultFile(event.getPlayer().getUniqueId()); } } diff --git a/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java b/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java new file mode 100644 index 0000000..a611c84 --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java @@ -0,0 +1,90 @@ +package com.drtshock.playervaults.tasks; + +import com.drtshock.playervaults.PlayerVaults; +import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; +import com.drtshock.playervaults.vaultmanagement.VaultManager; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; + +import java.io.File; +import java.util.UUID; +import java.util.logging.Logger; + +/** + * Class to convert vaults by Bukkit serialization to Base64. + */ +public final class Base64Conversion implements Runnable { + + @Override + public void run() { + Logger logger = PlayerVaults.getInstance().getLogger(); + + File newDir = PlayerVaults.getInstance().getVaultData(); + if (newDir.exists()) { + logger.info("** Vaults have already been converted to Base64. If this is incorrect, shutdown your server and rename the " + newDir.toString() + " directory."); + return; + } + + newDir.mkdirs(); + + File oldVaults = PlayerVaults.getInstance().getUuidData(); + if (!oldVaults.exists()) { + logger.info("No uuidvaults found to convert to base64."); + return; + } + + newDir.mkdirs(); + + UUIDVaultManager oldManager = UUIDVaultManager.getInstance(); + VaultManager manager = VaultManager.getInstance(); + + logger.info("********** Starting conversion to Base64 for PlayerVaults **********"); + logger.info("This might take awhile."); + logger.info(oldVaults.toString() + " will remain as a backup."); + + int players = 0; + int vaults = 0; + for (File file : oldVaults.listFiles()) { + if (file.isDirectory()) { + continue; // backups folder. + } + + FileConfiguration uuidFile = YamlConfiguration.loadConfiguration(file); + String stringUUID = file.getName().replace(".yml", ""); + UUID holderUUID; + try { + holderUUID = UUID.fromString(stringUUID); + } catch (Exception e) { + logger.warning(String.format("Failed to parse uuid for %s. Trying to convert", stringUUID)); + OfflinePlayer player = Bukkit.getOfflinePlayer(stringUUID); + if (player != null) { + logger.info(String.format("Successfully got UUID for %s", stringUUID)); + holderUUID = player.getUniqueId(); + } else { + logger.warning(String.format("Failed to convert name to uuid for %s", stringUUID)); + continue; + } + } + + for (String key : uuidFile.getKeys(false)) { + if (!key.startsWith("vault")) { + continue; + } + + int vaultNumber = Integer.valueOf(key.replace("vault", "")); + + Inventory inventory = oldManager.getVault(holderUUID, vaultNumber); + manager.saveVault(inventory, holderUUID, vaultNumber); + vaults++; + } + + players++; + } + + logger.info(String.format("Converted %d vaults for %d players to base64.", vaults, players)); + } +} diff --git a/src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java b/src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java index 86e813c..f2188c4 100644 --- a/src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java +++ b/src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java @@ -24,8 +24,6 @@ public final class UUIDConversion implements Runnable { return; } - newDir.mkdirs(); - File oldVaults = new File(PlayerVaults.getInstance().getDataFolder() + File.separator + "vaults"); if (oldVaults.exists()) { logger.info("********** Starting conversion to UUIDs for PlayerVaults **********"); diff --git a/src/main/java/com/drtshock/playervaults/util/Updater.java b/src/main/java/com/drtshock/playervaults/util/Updater.java deleted file mode 100644 index 9bc7277..0000000 --- a/src/main/java/com/drtshock/playervaults/util/Updater.java +++ /dev/null @@ -1,537 +0,0 @@ -package com.drtshock.playervaults.util; - -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.Plugin; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.JSONValue; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.util.Enumeration; -import java.util.logging.Level; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * Check dev.bukkit.org to find updates for a given plugin, and download the updates if needed. - *

- * VERY, VERY IMPORTANT: Because there are no standards for adding auto-update toggles in your plugin's config, - * this system provides NO CHECK WITH YOUR CONFIG to make sure the user has allowed auto-updating.
It is a - * BUKKIT POLICY that you include a boolean value in your config that prevents the auto-updater from running - * AT ALL.
If you fail to include this option in your config, your plugin will be REJECTED when you - * attempt to submit it to dev.bukkit.org. - *

- * An example of a good configuration option would be something similar to 'auto-update: true' - if this value is set - * to - * false you may NOT run the auto-updater.
If you are unsure about these rules, please read the plugin submission - * guidelines: http://goo.gl/8iU5l - * - * @author Gravity - */ - -public class Updater { - - private Plugin plugin; - private Updater.UpdateType type; - private String versionName; - private String versionLink; - private String versionType; - private String versionGameVersion; - - private int sizeLine; // Used for detecting file size - private int multiplier; // Used for determining when to broadcast download updates - private boolean announce; // Whether to announce file downloads - - private URL url; // Connecting to RSS - private File file; // The plugin's file - private Thread thread; // Updater thread - - private int id = -1; // Project's Curse ID - private String apiKey = null; // BukkitDev ServerMods API key - private static final String TITLE_VALUE = "name"; // Gets remote file's title - private static final String LINK_VALUE = "downloadUrl"; // Gets remote file's download link - private static final String TYPE_VALUE = "releaseType"; // Gets remote file's release type - private static final String VERSION_VALUE = "gameVersion"; // Gets remote file's build version - private static final String QUERY = "/servermods/files?projectIds="; // Path to GET - private static final String HOST = "https://api.curseforge.com"; // Slugs will be appended to this to get to the project's RSS feed - - private String[] noUpdateTag = {"-DEV", "-PRE", "-SNAPSHOT"}; // If the version number contains one of these, don't update. - private static final int BYTE_SIZE = 1024; // Used for downloading files - private YamlConfiguration config; // Config file - private String updateFolder = YamlConfiguration.loadConfiguration(new File("bukkit.yml")).getString("settings.update-folder"); // The folder that downloads will be placed in - private Updater.UpdateResult result = Updater.UpdateResult.SUCCESS; // Used for determining the outcome of the update process - - public Updater(Runnable aThis, int i, File file, UpdateType updateType, boolean b) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - /** - * Gives the dev the result of the update process. Can be obtained by called getResult(). - */ - public enum UpdateResult { - /** - * The updater found an update, and has readied it to be loaded the next time the server restarts/reloads. - */ - SUCCESS, - /** - * The updater did not find an update, and nothing was downloaded. - */ - NO_UPDATE, - /** - * The server administrator has disabled the updating system - */ - DISABLED, - /** - * The updater found an update, but was unable to download it. - */ - FAIL_DOWNLOAD, - /** - * For some reason, the updater was unable to contact dev.bukkit.org to download the file. - */ - FAIL_DBO, - /** - * When running the version check, the file on DBO did not contain the a version in the format 'vVersion' such - * as 'v1.0'. - */ - FAIL_NOVERSION, - /** - * The id provided by the plugin running the updater was invalid and doesn't exist on DBO. - */ - FAIL_BADID, - /** - * The server administrator has improperly configured their API key in the configuration - */ - FAIL_APIKEY, - /** - * The updater found an update, but because of the UpdateType being set to NO_DOWNLOAD, it wasn't downloaded. - */ - UPDATE_AVAILABLE - } - - /** - * Allows the dev to specify the type of update that will be run. - */ - public enum UpdateType { - /** - * Run a version check, and then if the file is out of date, download the newest version. - */ - DEFAULT, - /** - * Don't run a version check, just find the latest update and download it. - */ - NO_VERSION_CHECK, - /** - * Get information about the version and the download size, but don't actually download anything. - */ - NO_DOWNLOAD - } - - /** - * Initialize the updater - * - * @param plugin The plugin that is checking for an update. - * @param id The dev.bukkit.org id of the project - * @param file The file that the plugin is running from, get this by doing this.getFile() from within your main - * class. - * @param type Specify the type of update this will be. See {@link UpdateType} - * @param announce True if the program should announce the progress of new updates in console - */ - public Updater(Plugin plugin, int id, File file, Updater.UpdateType type, boolean announce) { - this.plugin = plugin; - this.type = type; - this.announce = announce; - this.file = file; - this.id = id; - - File pluginFile = plugin.getDataFolder().getParentFile(); - File updaterFile = new File(pluginFile, "Updater"); - File updaterConfigFile = new File(updaterFile, "config.yml"); - - if (!updaterFile.exists()) { - updaterFile.mkdir(); - } - if (!updaterConfigFile.exists()) { - try { - updaterConfigFile.createNewFile(); - } catch (IOException e) { - plugin.getLogger().log(Level.SEVERE, "The updater could not create a configuration in {0}", updaterFile.getAbsolutePath()); - e.printStackTrace(); - } - } - config = YamlConfiguration.loadConfiguration(updaterConfigFile); - - config.addDefault("api-key", "PUT_API_KEY_HERE"); - config.addDefault("disable", false); - - if (config.get("api-key", null) == null) { - config.options().copyDefaults(true); - try { - config.save(updaterConfigFile); - } catch (IOException e) { - plugin.getLogger().log(Level.SEVERE, "The updater could not save the configuration in {0}", updaterFile.getAbsolutePath()); - e.printStackTrace(); - } - } - - if (config.getBoolean("disable")) { - result = Updater.UpdateResult.DISABLED; - return; - } - - String key = config.getString("api-key"); - if (key.equalsIgnoreCase("PUT_API_KEY_HERE") || key.equals("")) { - key = null; - } - - apiKey = key; - - try { - url = new URL(HOST + QUERY + id); - } catch (MalformedURLException e) { - plugin.getLogger().log(Level.SEVERE, "The project ID provided for updating, {0} is invalid.", id); - result = Updater.UpdateResult.FAIL_BADID; - e.printStackTrace(); - } - - thread = new Thread(new Updater.UpdateRunnable()); - thread.start(); - } - - /** - * Get the result of the update process. - */ - public Updater.UpdateResult getResult() { - waitForThread(); - return result; - } - - /** - * Get the latest version's release type (release, beta, or alpha) - */ - public String getLatestType() { - waitForThread(); - return versionType; - } - - /** - * Get the latest version's game version - */ - public String getLatestGameVersion() { - waitForThread(); - return versionGameVersion; - } - - /** - * Get the latest version's name - */ - public String getLatestName() { - waitForThread(); - return versionName; - } - - /** - * As the result of Updater output depends on the thread's completion, it is necessary to wait for the thread to - * finish before allowing anyone to check the result. - */ - private void waitForThread() { - if (thread != null && thread.isAlive()) { - try { - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - - /** - * Save an update from dev.bukkit.org into the server's update folder. - */ - private void saveFile(File folder, String file, String u) { - if (!folder.exists()) { - folder.mkdir(); - } - BufferedInputStream in = null; - FileOutputStream fout = null; - try { - // Download the file - URL url = new URL(u); - int fileLength = url.openConnection().getContentLength(); - in = new BufferedInputStream(url.openStream()); - fout = new FileOutputStream(folder.getAbsolutePath() + "/" + file); - - byte[] data = new byte[BYTE_SIZE]; - int count; - if (announce) { - plugin.getLogger().log(Level.INFO, "About to download a new update: {0}", versionName); - } - long downloaded = 0; - while ((count = in.read(data, 0, BYTE_SIZE)) != -1) { - downloaded += count; - fout.write(data, 0, count); - int percent = (int) (downloaded * 100 / fileLength); - if (announce & (percent % 10 == 0)) { - plugin.getLogger().log(Level.INFO, "Downloading update: {0}% of {1} bytes.", new Object[]{percent, fileLength}); - } - } - //Just a quick check to make sure we didn't leave any files from last time... - for (File xFile : new File("plugins/" + updateFolder).listFiles()) { - if (xFile.getName().endsWith(".zip")) { - xFile.delete(); - } - } - // Check to see if it's a zip file, if it is, unzip it. - File dFile = new File(folder.getAbsolutePath() + "/" + file); - if (dFile.getName().endsWith(".zip")) { - // Unzip - unzip(dFile.getCanonicalPath()); - } - if (announce) { - plugin.getLogger().info("Finished updating."); - } - } catch (Exception ex) { - plugin.getLogger().warning("The auto-updater tried to download a new update, but was unsuccessful."); - result = Updater.UpdateResult.FAIL_DOWNLOAD; - } finally { - try { - if (in != null) { - in.close(); - } - if (fout != null) { - fout.close(); - } - } catch (Exception ex) { - } - } - } - - /** - * Part of Zip-File-Extractor, modified by H31IX for use with Bukkit - */ - private void unzip(String file) { - try { - File fSourceZip = new File(file); - String zipPath = file.substring(0, file.length() - 4); - ZipFile zipFile = new ZipFile(fSourceZip); - Enumeration e = zipFile.entries(); - while (e.hasMoreElements()) { - ZipEntry entry = e.nextElement(); - File destinationFilePath = new File(zipPath, entry.getName()); - destinationFilePath.getParentFile().mkdirs(); - if (entry.isDirectory()) { - continue; - } else { - BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry)); - int b; - byte buffer[] = new byte[BYTE_SIZE]; - FileOutputStream fos = new FileOutputStream(destinationFilePath); - BufferedOutputStream bos = new BufferedOutputStream(fos, BYTE_SIZE); - while ((b = bis.read(buffer, 0, BYTE_SIZE)) != -1) { - bos.write(buffer, 0, b); - } - bos.flush(); - bos.close(); - bis.close(); - String name = destinationFilePath.getName(); - if (name.endsWith(".jar") && pluginFile(name)) { - destinationFilePath.renameTo(new File("plugins/" + updateFolder + "/" + name)); - } - } - entry = null; - destinationFilePath = null; - } - e = null; - zipFile.close(); - zipFile = null; - - // Move any plugin data folders that were included to the right place, Bukkit won't do this for us. - for (File dFile : new File(zipPath).listFiles()) { - if (dFile.isDirectory()) { - if (pluginFile(dFile.getName())) { - File oFile = new File("plugins/" + dFile.getName()); // Get current dir - File[] contents = oFile.listFiles(); // List of existing files in the current dir - for (File cFile : dFile.listFiles()) // Loop through all the files in the new dir - { - boolean found = false; - for (File xFile : contents) // Loop through contents to see if it exists - { - if (xFile.getName().equals(cFile.getName())) { - found = true; - break; - } - } - if (!found) { - // Move the new file into the current dir - cFile.renameTo(new File(oFile.getCanonicalFile() + "/" + cFile.getName())); - } else { - // This file already exists, so we don't need it anymore. - cFile.delete(); - } - } - } - } - dFile.delete(); - } - new File(zipPath).delete(); - fSourceZip.delete(); - } catch (IOException ex) { - plugin.getLogger().warning("The auto-updater tried to unzip a new update file, but was unsuccessful."); - result = Updater.UpdateResult.FAIL_DOWNLOAD; - ex.printStackTrace(); - } - new File(file).delete(); - } - - /** - * Check if the name of a jar is one of the plugins currently installed, used for extracting the correct files out - * of a zip. - */ - private boolean pluginFile(String name) { - for (File file : new File("plugins").listFiles()) { - if (file.getName().equals(name)) { - return true; - } - } - return false; - } - - /** - * Check to see if the program should continue by evaluation whether the plugin is already updated, or shouldn't be - * updated - */ - private boolean versionCheck(String title) { - if (type != Updater.UpdateType.NO_VERSION_CHECK) { - String version = plugin.getDescription().getVersion(); - if (title.split("v").length == 2) { - String remoteVersion = title.split("v")[1].split(" ")[0]; // Get the newest file's version number - int remVer, curVer = 0; - try { - remVer = calVer(remoteVersion); - curVer = calVer(version); - } catch (NumberFormatException nfe) { - remVer = -1; - } - if (hasTag(version) || version.equalsIgnoreCase(remoteVersion) || curVer >= remVer) { - // We already have the latest version, or this build is tagged for no-update - result = Updater.UpdateResult.NO_UPDATE; - return false; - } - } else { - // The file's name did not contain the string 'vVersion' - plugin.getLogger().log(Level.WARNING, "The author of this plugin ({0}) has misconfigured their Auto Update system", plugin.getDescription().getAuthors().get(0)); - plugin.getLogger().warning("Files uploaded to BukkitDev should contain the version number, seperated from the name by a 'v', such as PluginName v1.0"); - plugin.getLogger().warning("Please notify the author of this error."); - result = Updater.UpdateResult.FAIL_NOVERSION; - return false; - } - } - return true; - } - - /** - * Used to calculate the version string as an Integer - */ - private Integer calVer(String s) throws NumberFormatException { - if (s.contains(".")) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < s.length(); i++) { - Character c = s.charAt(i); - if (Character.isLetterOrDigit(c)) { - sb.append(c); - } - } - return Integer.parseInt(sb.toString()); - } - return Integer.parseInt(s); - } - - /** - * Evaluate whether the version number is marked showing that it should not be updated by this program - */ - private boolean hasTag(String version) { - for (String string : noUpdateTag) { - if (version.contains(string)) { - return true; - } - } - return false; - } - - private boolean read() { - try { - URLConnection conn = url.openConnection(); - conn.setConnectTimeout(5000); - - if (apiKey != null) { - conn.addRequestProperty("X-API-Key", apiKey); - } - conn.addRequestProperty("User-Agent", "Updater (by Gravity)"); - - conn.setDoOutput(true); - - final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String response = reader.readLine(); - - JSONArray array = (JSONArray) JSONValue.parse(response); - - if (array.size() == 0) { - plugin.getLogger().log(Level.WARNING, "The updater could not find any files for the project id {0}", id); - result = Updater.UpdateResult.FAIL_BADID; - return false; - } - - versionName = (String) ((JSONObject) array.get(array.size() - 1)).get(TITLE_VALUE); - versionLink = (String) ((JSONObject) array.get(array.size() - 1)).get(LINK_VALUE); - versionType = (String) ((JSONObject) array.get(array.size() - 1)).get(TYPE_VALUE); - versionGameVersion = (String) ((JSONObject) array.get(array.size() - 1)).get(VERSION_VALUE); - - return true; - } catch (IOException e) { - if (e.getMessage().contains("HTTP response code: 403")) { - plugin.getLogger().warning("dev.bukkit.org rejected the API key provided in plugins/Updater/config.yml"); - plugin.getLogger().warning("Please double-check your configuration to ensure it is correct."); - result = Updater.UpdateResult.FAIL_APIKEY; - } else { - plugin.getLogger().warning("The updater could not contact dev.bukkit.org for updating."); - plugin.getLogger().warning("If you have not recently modified your configuration and this is the first time you are seeing this message, the site may be experiencing temporary downtime."); - result = Updater.UpdateResult.FAIL_DBO; - } - e.printStackTrace(); - return false; - } - } - - - private class UpdateRunnable implements Runnable { - - @Override - public void run() { - if (url != null) { - // Obtain the results of the project's file feed - if (read()) { - if (versionCheck(versionName)) { - if (versionLink != null && type != Updater.UpdateType.NO_DOWNLOAD) { - String name = file.getName(); - // If it's a zip file, it shouldn't be downloaded as the plugin's name - if (versionLink.endsWith(".zip")) { - String[] split = versionLink.split("/"); - name = split[split.length - 1]; - } - saveFile(new File("plugins/" + updateFolder), name, versionLink); - } else { - result = Updater.UpdateResult.UPDATE_AVAILABLE; - } - } - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java new file mode 100644 index 0000000..a8c2c8d --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java @@ -0,0 +1,62 @@ +package com.drtshock.playervaults.vaultmanagement; + + +import org.bukkit.Bukkit; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.bukkit.util.io.BukkitObjectOutputStream; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; + +/** + * Created by Lax on 6/6/2017. + */ +public class Base64Serialization { + + public static String toBase64(Inventory inventory) { + try { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream); + + // Write the size of the inventory + dataOutput.writeInt(inventory.getSize()); + + // Save every element in the list + for (int i = 0; i < inventory.getSize(); i++) { + dataOutput.writeObject(inventory.getItem(i)); + } + + // Serialize that array + dataOutput.close(); + return Base64Coder.encodeLines(outputStream.toByteArray()); + } catch (Exception e) { + throw new IllegalStateException("Cannot into itemstacksz!", e); + } + } + + public static String toBase64(ItemStack[] is, int size) { + Inventory inventory = Bukkit.createInventory(null, size); + inventory.setContents(is); + return toBase64(inventory); + } + + public static Inventory fromBase64(String data) { + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); + BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); + Inventory inventory = Bukkit.getServer().createInventory(null, dataInput.readInt()); + + // Read the serialized inventory + for (int i = 0; i < inventory.getSize(); i++) { + inventory.setItem(i, (ItemStack) dataInput.readObject()); + } + dataInput.close(); + return inventory; + } catch (Exception e) { + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java index 81b4d7c..0e9a4b5 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java @@ -47,7 +47,7 @@ public class EconomyOperations { return true; } - if (!UUIDVaultManager.getInstance().vaultExists(player.getUniqueId().toString(), number)) { + if (!VaultManager.getInstance().vaultExists(player.getUniqueId(), number)) { return payToCreate(player); } else { double cost = BUKKIT_CONFIG.getDouble("economy.cost-to-open", 10); diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java index b600cc0..10cf2b3 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java @@ -39,9 +39,10 @@ import org.json.simple.JSONValue; * * @author evilmidget38, gomeow */ +@SuppressWarnings("unchecked") public class Serialization { - @SuppressWarnings("unchecked") + @Deprecated public static Map toMap(JSONObject object) { Map map = new HashMap<>(); @@ -56,6 +57,7 @@ public class Serialization { return map; } + @Deprecated private static Object fromJson(Object json) { if (json == null) { return null; @@ -68,6 +70,7 @@ public class Serialization { } } + @Deprecated public static List toList(JSONArray array) { List list = new ArrayList<>(); for (Object value : array) { @@ -76,6 +79,7 @@ public class Serialization { return list; } + @Deprecated public static List toString(Inventory inv) { List result = new ArrayList<>(); List items = new ArrayList<>(); @@ -90,6 +94,7 @@ public class Serialization { return result; } + @Deprecated public static Inventory toInventory(List stringItems, int number, int size, String title) { VaultHolder holder = new VaultHolder(number); Inventory inv = Bukkit.createInventory(holder, size, title); @@ -110,13 +115,14 @@ public class Serialization { return inv; } + @Deprecated public static Map serialize(ConfigurationSerializable cs) { Map returnVal = handleSerialization(cs.serialize()); returnVal.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(cs.getClass())); return returnVal; } - @SuppressWarnings("unchecked") + @Deprecated private static Map handleSerialization(Map map) { Map serialized = recreateMap(map); for (Entry entry : serialized.entrySet()) { @@ -139,13 +145,14 @@ public class Serialization { return serialized; } + @Deprecated public static Map recreateMap(Map original) { Map map = new HashMap<>(); map.putAll(original); return map; } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @Deprecated public static Object deserialize(Map map) { List itemflags = null; for (Entry entry : map.entrySet()) { @@ -183,6 +190,7 @@ public class Serialization { } } + @Deprecated private static List convertIterable(Iterable iterable) { List newList = new ArrayList<>(); for (Object object : iterable) { @@ -198,6 +206,7 @@ public class Serialization { return newList; } + @Deprecated private static Number convertNumber(Number number) { if (number instanceof Long) { Long longObj = (Long) number; diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java index 1ec2213..e6d8dc9 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java @@ -5,6 +5,7 @@ import com.drtshock.playervaults.util.Lang; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -22,6 +23,7 @@ import java.util.logging.Level; /** * Class to handle vault operations with new UUIDs. */ +@Deprecated public class UUIDVaultManager { private static UUIDVaultManager instance; @@ -30,7 +32,7 @@ public class UUIDVaultManager { instance = this; } - private final File directory = PlayerVaults.getInstance().getVaultData(); + private final File directory = PlayerVaults.getInstance().getUuidData(); private final Map cachedVaultFiles = new ConcurrentHashMap<>(); /** @@ -135,7 +137,6 @@ public class UUIDVaultManager { * @param playerFile the YamlConfiguration file. * @param size the size of the vault. * @param number the vault number. - * * @return inventory if exists, otherwise null. */ private Inventory getInventory(YamlConfiguration playerFile, int size, int number, String title) { @@ -156,24 +157,28 @@ public class UUIDVaultManager { * * @param holder The holder of the vault. * @param number The vault number. - * * @return The inventory of the specified holder and vault number. */ public Inventory getVault(UUID holder, int number) { YamlConfiguration playerFile = getPlayerVaultFile(holder); - List data = playerFile.getStringList("vault" + number); - OfflinePlayer player = Bukkit.getOfflinePlayer(holder); - if (player == null || !player.hasPlayedBefore()) { - return null; - } - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", Bukkit.getOfflinePlayer(holder).getName()); - if (data == null) { + ConfigurationSection section = playerFile.getConfigurationSection("vault" + number); + int maxSize = VaultOperations.getMaxVaultSize(holder); + + String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)); + + if (section == null) { VaultHolder vaultHolder = new VaultHolder(number); - Inventory inv = Bukkit.createInventory(vaultHolder, VaultOperations.getMaxVaultSize(player), Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", player.getName())); + Inventory inv = Bukkit.createInventory(vaultHolder, maxSize, title); vaultHolder.setInventory(inv); return inv; } else { - return Serialization.toInventory(data, number, VaultOperations.getMaxVaultSize(player), title); + List data = new ArrayList<>(); + for (String s : section.getKeys(false)) { + String value = section.getString(s); + data.add(value); + } + + return Serialization.toInventory(data, number, maxSize, title); } } @@ -182,7 +187,6 @@ public class UUIDVaultManager { * * @param holder holder of the vault. * @param number vault number. - * * @return true if the vault file and vault number exist in that file, otherwise false. */ public boolean vaultExists(String holder, int number) { @@ -200,7 +204,6 @@ public class UUIDVaultManager { * @param sender The sender of whom to send messages to. * @param holder The vault holder. * @param number The vault number. - * * @throws IOException Uh oh! */ public void deleteVault(CommandSender sender, final String holder, final int number) throws IOException { @@ -264,7 +267,6 @@ public class UUIDVaultManager { * Get the holder's vault file. Create if doesn't exist. * * @param holder The vault holder. - * * @return The holder's vault config file. */ public YamlConfiguration getPlayerVaultFile(String holder) { diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java new file mode 100644 index 0000000..07c1e64 --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java @@ -0,0 +1,286 @@ +package com.drtshock.playervaults.vaultmanagement; + +import com.drtshock.playervaults.PlayerVaults; +import com.drtshock.playervaults.util.Lang; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.scheduler.BukkitRunnable; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Level; + +public class VaultManager { + + private static VaultManager instance; + private static final String VAULTKEY = "vault%d"; + + public VaultManager() { + instance = this; + } + + private final File directory = PlayerVaults.getInstance().getVaultData(); + private final Map cachedVaultFiles = new ConcurrentHashMap<>(); + + /** + * Saves the inventory to the specified player and vault number. + * + * @param inventory The inventory to be saved. + * @param target The player of whose file to save to. + * @param number The vault number. + */ + public void saveVault(Inventory inventory, UUID target, int number) { + YamlConfiguration yaml = getPlayerVaultFile(target); + String serialized = Base64Serialization.toBase64(inventory); + yaml.set(String.format(VAULTKEY, number), serialized); + saveFileSync(target, yaml); + } + + /** + * Load the player's vault and return it. + * + * @param player The holder of the vault. + * @param number The vault number. + */ + public Inventory loadOwnVault(Player player, int number, int size) { + if (size % 9 != 0) { + size = 54; + } + + String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", player.getName()); + VaultViewInfo info = new VaultViewInfo(player.getUniqueId(), number); + if (PlayerVaults.getInstance().getOpenInventories().containsKey(info.toString())) { + return PlayerVaults.getInstance().getOpenInventories().get(info.toString()); + } + + Inventory inv; + YamlConfiguration playerFile = getPlayerVaultFile(player.getUniqueId()); + if (playerFile.getString(String.format(VAULTKEY, number)) == null) { + VaultHolder vaultHolder = new VaultHolder(number); + if (EconomyOperations.payToCreate(player)) { + inv = Bukkit.createInventory(vaultHolder, size, title); + vaultHolder.setInventory(inv); + } else { + player.sendMessage(Lang.TITLE.toString() + Lang.INSUFFICIENT_FUNDS.toString()); + return null; + } + } else { + Inventory i = getInventory(playerFile, size, number, title); + if (i == null) { + return null; + } else { + inv = i; + } + } + PlayerVaults.getInstance().getOpenInventories().put(info.toString(), inv); + + return inv; + } + + /** + * Load the player's vault and return it. + * + * @param holder The holder of the vault. + * @param number The vault number. + */ + public Inventory loadOtherVault(UUID holder, int number, int size) { + if (size % 9 != 0) { + size = 54; + } + + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(holder); + String name = "null"; + if (offlinePlayer != null) { + name = offlinePlayer.getName(); + } + + String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", name); + VaultViewInfo info = new VaultViewInfo(holder, number); + Inventory inv; + if (PlayerVaults.getInstance().getOpenInventories().containsKey(info.toString())) { + inv = PlayerVaults.getInstance().getOpenInventories().get(info.toString()); + } else { + YamlConfiguration playerFile = getPlayerVaultFile(holder); + Inventory i = getInventory(playerFile, size, number, title); + if (i == null) { + return null; + } else { + inv = i; + } + PlayerVaults.getInstance().getOpenInventories().put(info.toString(), inv); + } + return inv; + } + + /** + * Get an inventory from file. Returns null if the inventory doesn't exist. SHOULD ONLY BE USED INTERNALLY + * + * @param playerFile the YamlConfiguration file. + * @param size the size of the vault. + * @param number the vault number. + * @return inventory if exists, otherwise null. + */ + private Inventory getInventory(YamlConfiguration playerFile, int size, int number, String title) { + String data = playerFile.getString(String.format(VAULTKEY, number)); + return Base64Serialization.fromBase64(data); + } + + /** + * Gets an inventory without storing references to it. Used for dropping a players inventories on death. + * + * @param holder The holder of the vault. + * @param number The vault number. + * @return The inventory of the specified holder and vault number. Can be null. + */ + public Inventory getVault(UUID holder, int number) { + YamlConfiguration playerFile = getPlayerVaultFile(holder); + String serialized = playerFile.getString(String.format(VAULTKEY, number)); + return Base64Serialization.fromBase64(serialized); + } + + /** + * Checks if a vault exists. + * + * @param holder holder of the vault. + * @param number vault number. + * @return true if the vault file and vault number exist in that file, otherwise false. + */ + public boolean vaultExists(UUID holder, int number) { + File file = new File(directory, holder + ".yml"); + if (!file.exists()) { + return false; + } + + return getPlayerVaultFile(holder).contains(String.format(VAULTKEY, number)); + } + + /** + * Deletes a players vault. + * + * @param sender The sender of whom to send messages to. + * @param holder The vault holder. + * @param number The vault number. + * @throws IOException Uh oh! + */ + public void deleteVault(CommandSender sender, final UUID holder, final int number) throws IOException { + new BukkitRunnable() { + @Override + public void run() { + File file = new File(directory, holder + ".yml"); + if (!file.exists()) { + return; + } + + YamlConfiguration playerFile = YamlConfiguration.loadConfiguration(file); + if (file.exists()) { + playerFile.set(String.format(VAULTKEY, number), null); + if (cachedVaultFiles.containsKey(holder)) { + cachedVaultFiles.put(holder, playerFile); + } + try { + playerFile.save(file); + } catch (IOException ignored) { + } + } + } + }.runTaskAsynchronously(PlayerVaults.getInstance()); + + OfflinePlayer player = Bukkit.getPlayer(holder); + if (player != null) { + if (sender.getName().equalsIgnoreCase(player.getName())) { + sender.sendMessage(Lang.TITLE.toString() + Lang.DELETE_VAULT.toString().replace("%v", String.valueOf(number))); + } else { + sender.sendMessage(Lang.TITLE.toString() + Lang.DELETE_OTHER_VAULT.toString().replace("%v", String.valueOf(number)).replaceAll("%p", player.getName())); + } + } + + PlayerVaults.getInstance().getOpenInventories().remove(new VaultViewInfo(holder, number).toString()); + } + + // Should only be run asynchronously + public void cachePlayerVaultFile(UUID holder) { + YamlConfiguration config = this.loadPlayerVaultFile(holder, false); + if (config != null) { + this.cachedVaultFiles.put(holder, config); + } else { + } + } + + public void removeCachedPlayerVaultFile(UUID holder) { + if (cachedVaultFiles.containsKey(holder)) { + cachedVaultFiles.remove(holder); + } + } + + /** + * Get the holder's vault file. Create if doesn't exist. + * + * @param holder The vault holder. + * @return The holder's vault config file. + */ + public YamlConfiguration getPlayerVaultFile(UUID holder) { + if (cachedVaultFiles.containsKey(holder)) { + return cachedVaultFiles.get(holder); + } + return loadPlayerVaultFile(holder); + } + + public YamlConfiguration loadPlayerVaultFile(UUID holder) { + return this.loadPlayerVaultFile(holder, true); + } + + public YamlConfiguration loadPlayerVaultFile(UUID uniqueId, boolean createIfNotFound) { + if (!this.directory.exists()) { + this.directory.mkdir(); + } + + File file = new File(this.directory, uniqueId.toString() + ".yml"); + if (!file.exists()) { + if (createIfNotFound) { + try { + file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + return null; + } + } + + return YamlConfiguration.loadConfiguration(file); + } + + public void saveFileSync(final UUID holder, final YamlConfiguration yaml) { + if (cachedVaultFiles.containsKey(holder)) { + cachedVaultFiles.put(holder, yaml); + } + + final boolean backups = PlayerVaults.getInstance().isBackupsEnabled(); + final File backupsFolder = PlayerVaults.getInstance().getBackupsFolder(); + final File file = new File(directory, holder.toString() + ".yml"); + if (file.exists() && backups) { + file.renameTo(new File(backupsFolder, holder.toString() + ".yml")); + } + try { + yaml.save(file); + } catch (IOException e) { + PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to save vault file for: " + holder.toString(), e); + } + } + + /** + * Get the instance of this class. + * + * @return - instance of this class. + */ + public static VaultManager getInstance() { + return instance; + } +} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java index 2909666..eaf012c 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java @@ -88,18 +88,11 @@ public class VaultOperations { /** * Get the max size vault a player is allowed to have. * - * @param target that is having his permissions checked. + * @param uuid that is having his permissions checked. * * @return max size as integer. If no max size is set then it will default to 54. */ - public static int getMaxVaultSize(String target) { - UUID uuid; - try { - uuid = UUID.fromString(target); - } catch (Exception e) { - return 54; - } - + public static int getMaxVaultSize(UUID uuid) { return getMaxVaultSize(Bukkit.getOfflinePlayer(uuid)); } @@ -147,7 +140,7 @@ public class VaultOperations { if (checkPerms(player, number)) { if (EconomyOperations.payToOpen(player, number)) { - Inventory inv = UUIDVaultManager.getInstance().loadOwnVault(player, number, getMaxVaultSize(player)); + Inventory inv = VaultManager.getInstance().loadOwnVault(player, number, getMaxVaultSize(player)); player.openInventory(inv); player.sendMessage(Lang.TITLE.toString() + Lang.OPEN_VAULT.toString().replace("%v", arg)); return true; @@ -187,14 +180,13 @@ public class VaultOperations { * * @return Whether or not the player was allowed to open it. */ - public static boolean openOtherVault(Player player, String holder, String arg) { + public static boolean openOtherVault(Player player, UUID holder, String arg) { if (isLocked()) { return false; } long time = System.currentTimeMillis(); - String nicename = holder; int number = 0; try { number = Integer.parseInt(arg); @@ -206,21 +198,15 @@ public class VaultOperations { player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); } - // Try to get the vault of an OfflinePlayer if we don't find one with the name first. - if (!UUIDVaultManager.getInstance().vaultExists(holder, number)) { - OfflinePlayer targetPlayer = Bukkit.getOfflinePlayer(holder); - if (targetPlayer.hasPlayedBefore()) { - holder = targetPlayer.getUniqueId().toString(); - } - } - - Inventory inv = UUIDVaultManager.getInstance().loadOtherVault(holder, number, getMaxVaultSize(holder)); + Inventory inv = VaultManager.getInstance().loadOtherVault(holder, number, getMaxVaultSize(holder)); + OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(holder); + String name = offlinePlayer != null ? offlinePlayer.getName() : ""; if (inv == null) { player.sendMessage(Lang.TITLE.toString() + Lang.VAULT_DOES_NOT_EXIST.toString()); } else { player.openInventory(inv); - player.sendMessage(Lang.TITLE.toString() + Lang.OPEN_OTHER_VAULT.toString().replace("%v", arg).replace("%p", nicename)); + player.sendMessage(Lang.TITLE.toString() + Lang.OPEN_OTHER_VAULT.toString().replace("%v", arg).replace("%p", name)); PlayerVaults.debug("opening other vault", time); return true; } @@ -253,7 +239,7 @@ public class VaultOperations { try { if (EconomyOperations.refundOnDelete(player, number)) { - UUIDVaultManager.getInstance().deleteVault(player, player.getUniqueId().toString(), number); + VaultManager.getInstance().deleteVault(player, player.getUniqueId(), number); } } catch (IOException e) { player.sendMessage(Lang.TITLE.toString() + Lang.DELETE_VAULT_ERROR); @@ -288,7 +274,7 @@ public class VaultOperations { } try { - UUIDVaultManager.getInstance().deleteVault(sender, holder.getUniqueId().toString(), number); + VaultManager.getInstance().deleteVault(sender, holder.getUniqueId(), number); } catch (IOException e) { sender.sendMessage(Lang.TITLE.toString() + Lang.DELETE_VAULT_ERROR); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 3263cc8..35eb51b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -2,13 +2,6 @@ # http://dev.bukkit.org/bukkit-plugins/playervaults/ # Made with love :3 -# Whether or not you want to check for updates. -# Will not download an update by default, that is your job :) -# We do not break between minecraft versions so auto updating should not be an issue. -# But it's always a smart idea to read changelogs and such first :) -check-update: true -download-update: false - # Debug mode # This will print lots of spammy stuff to console. # Should probably only enabled this if you're working with drtshock to fix something.