From 5e3deaa8e28a9b954627b7bd48e5afc882888b8a Mon Sep 17 00:00:00 2001 From: mbax Date: Fri, 25 Dec 2020 12:19:55 -0500 Subject: [PATCH] Introduce MiniMessage, new lang, and fix storage quirks --- pom.xml | 64 ++++ .../com/drtshock/playervaults/Metrics.java | 3 +- .../drtshock/playervaults/PlayerVaults.java | 108 +++--- .../playervaults/commands/ConvertCommand.java | 15 +- .../playervaults/commands/DeleteCommand.java | 21 +- .../playervaults/commands/SignCommand.java | 26 +- .../playervaults/commands/VaultCommand.java | 23 +- .../drtshock/playervaults/config/Loader.java | 44 ++- .../playervaults/config/file/Config.java | 38 +- .../playervaults/config/file/Translation.java | 362 ++++++++++++++++++ .../playervaults/listeners/Listeners.java | 23 +- .../playervaults/listeners/SignListener.java | 15 +- .../playervaults/tasks/Base64Conversion.java | 46 ++- .../playervaults/tasks/UUIDConversion.java | 73 ---- .../playervaults/translations/Lang.java | 106 ----- .../playervaults/translations/Language.java | 39 -- .../vaultmanagement/Base64Serialization.java | 109 ------ .../CardboardBoxSerialization.java | 84 ++++ .../vaultmanagement/EconomyOperations.java | 12 +- .../vaultmanagement/Serialization.java | 6 +- .../vaultmanagement/UUIDVaultManager.java | 345 ----------------- .../vaultmanagement/VaultManager.java | 30 +- .../vaultmanagement/VaultOperations.java | 58 ++- 23 files changed, 754 insertions(+), 896 deletions(-) create mode 100644 src/main/java/com/drtshock/playervaults/config/file/Translation.java delete mode 100644 src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java delete mode 100644 src/main/java/com/drtshock/playervaults/translations/Lang.java delete mode 100644 src/main/java/com/drtshock/playervaults/translations/Language.java delete mode 100644 src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java create mode 100644 src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java delete mode 100644 src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java diff --git a/pom.xml b/pom.xml index 738549a..f111538 100644 --- a/pom.xml +++ b/pom.xml @@ -36,6 +36,32 @@ 1.8 + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + false + + + net.kyori + com.drtshock.playervaults.lib.net.kyori + + + com.google.gson + com.drtshock.playervaults.lib.com.google.gson + + + + + + package + + shade + + + + @@ -48,9 +74,47 @@ spigot-repo https://hub.spigotmc.org/nexus/content/groups/public/ + + sonatype + http://oss.sonatype.org/content/repositories/snapshots + + false + + + true + + + + jitpack.io + https://jitpack.io + + + net.kyori + adventure-platform-bukkit + 4.0.0-SNAPSHOT + compile + + + net.kyori + adventure-text-minimessage + 4.0.0-SNAPSHOT + compile + + + com.google.code.gson + gson + 2.8.0 + compile + + + org.kitteh + cardboardbox + 0.1.0 + compile + org.spigotmc spigot-api diff --git a/src/main/java/com/drtshock/playervaults/Metrics.java b/src/main/java/com/drtshock/playervaults/Metrics.java index f145632..caf9f92 100644 --- a/src/main/java/com/drtshock/playervaults/Metrics.java +++ b/src/main/java/com/drtshock/playervaults/Metrics.java @@ -143,7 +143,8 @@ public class Metrics { service.getField("B_STATS_VERSION"); // Our identifier :) found = true; // We aren't the first break; - } catch (NoSuchFieldException ignored) { } + } catch (NoSuchFieldException ignored) { + } } // Register our service Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal); diff --git a/src/main/java/com/drtshock/playervaults/PlayerVaults.java b/src/main/java/com/drtshock/playervaults/PlayerVaults.java index 39ee11c..ec05337 100644 --- a/src/main/java/com/drtshock/playervaults/PlayerVaults.java +++ b/src/main/java/com/drtshock/playervaults/PlayerVaults.java @@ -25,17 +25,15 @@ import com.drtshock.playervaults.commands.SignSetInfo; import com.drtshock.playervaults.commands.VaultCommand; import com.drtshock.playervaults.config.Loader; import com.drtshock.playervaults.config.file.Config; +import com.drtshock.playervaults.config.file.Translation; 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.translations.Lang; -import com.drtshock.playervaults.translations.Language; -import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.permission.Permission; import org.bukkit.Bukkit; @@ -93,6 +91,8 @@ public class PlayerVaults extends JavaPlugin { private int maxVaultAmountPermTest; private Metrics metrics; private Config config = new Config(); + private BukkitAudiences platform; + private Translation translation = new Translation(this); public static PlayerVaults getInstance() { return instance; @@ -115,25 +115,19 @@ public class PlayerVaults extends JavaPlugin { instance = this; long start = System.currentTimeMillis(); long time = System.currentTimeMillis(); + this.platform = BukkitAudiences.create(this); + debug("adventure!", time); + time = System.currentTimeMillis(); loadConfig(); DEBUG = getConf().isDebug(); debug("config", time); time = System.currentTimeMillis(); uuidData = new File(this.getDataFolder(), "uuidvaults"); - vaultData = new File(this.getDataFolder(), "base64vaults"); - debug("vaultdata", time); - time = System.currentTimeMillis(); - getServer().getScheduler().runTask(this, new UUIDConversion()); // Convert to UUIDs first. Class checks if necessary. - debug("uuid conversion", time); - time = System.currentTimeMillis(); - new VaultManager(); + vaultData = new File(this.getDataFolder(), "newvaults"); + new VaultManager(this); getServer().getScheduler().runTask(this, new Base64Conversion()); debug("base64 conversion", time); time = System.currentTimeMillis(); - loadLang(); - debug("lang", time); - time = System.currentTimeMillis(); - new UUIDVaultManager(); debug("uuidvaultmanager", time); time = System.currentTimeMillis(); getServer().getPluginManager().registerEvents(new Listeners(this), this); @@ -146,10 +140,10 @@ public class PlayerVaults extends JavaPlugin { loadSigns(); debug("loaded signs", time); time = System.currentTimeMillis(); - getCommand("pv").setExecutor(new VaultCommand()); - getCommand("pvdel").setExecutor(new DeleteCommand()); - getCommand("pvconvert").setExecutor(new ConvertCommand()); - getCommand("pvsign").setExecutor(new SignCommand()); + getCommand("pv").setExecutor(new VaultCommand(this)); + getCommand("pvdel").setExecutor(new DeleteCommand(this)); + getCommand("pvconvert").setExecutor(new ConvertCommand(this)); + getCommand("pvsign").setExecutor(new SignCommand(this)); debug("registered commands", time); time = System.currentTimeMillis(); useVault = setupEconomy(); @@ -221,7 +215,6 @@ public class PlayerVaults extends JavaPlugin { this.metricsSimplePie("signs", () -> getConf().isSigns() ? "enabled" : "disabled"); this.metricsSimplePie("cleanup", () -> getConf().getPurge().isEnabled() ? "enabled" : "disabled"); - this.metricsSimplePie("language", () -> getConf().getLanguage()); this.metricsDrillPie("block_items", () -> { Map> map = new HashMap<>(); @@ -313,7 +306,6 @@ public class PlayerVaults extends JavaPlugin { reloadConfig(); loadConfig(); // To update blocked materials. reloadSigns(); - loadLang(); sender.sendMessage(ChatColor.GREEN + "Reloaded PlayerVault's configuration and lang files."); } return true; @@ -362,6 +354,24 @@ public class PlayerVaults extends JavaPlugin { } } } + + File lang = new File(this.getDataFolder(), "lang"); + if (lang.exists()) { + this.getLogger().warning("There is no clean way for us to migrate your old lang data."); + this.getLogger().warning("If you made any customizations, or used another language, you need to migrate the info to the new format in lang.conf"); + try { + Files.move(lang.toPath(), lang.getParentFile().toPath().resolve("old_unused_lang")); + } catch (Exception e) { + this.getLogger().log(Level.SEVERE, "Failed to rename lang folder as it is no longer used", e); + configYaml.deleteOnExit(); + } + } + + try { + Loader.loadAndSave("lang", this.translation); + } catch (IOException | IllegalAccessException e) { + this.getLogger().log(Level.SEVERE, "Could not load lang.", e); + } } public Config getConf() { @@ -428,50 +438,6 @@ public class PlayerVaults extends JavaPlugin { } } - public void loadLang() { - File folder = new File(getDataFolder(), "lang"); - if (!folder.exists()) { - folder.mkdir(); - } - - String definedLanguage = getConf().getLanguage(); - - // Save as default just incase. - File english = null; - File definedFile = null; - - for (Language lang : Language.values()) { - String fileName = lang.getFriendlyName() + ".yml"; - File file = new File(folder, fileName); - if (lang == Language.ENGLISH) { - english = file; - } - - if (definedLanguage.equalsIgnoreCase(lang.getFriendlyName())) { - definedFile = file; - } - - // Have Bukkit save the file. - if (!file.exists()) { - saveResource("lang/" + fileName, false); - } - } - - if (definedFile != null && !definedFile.exists()) { - getLogger().severe("Failed to load language for " + definedLanguage + ". Defaulting to English."); - definedFile = english; - } - - if (definedFile == null) { - getLogger().severe("Failed to load custom language settings. Loading plugin defaults. This should never happen, go ask for help."); - return; - } - - YamlConfiguration config = YamlConfiguration.loadConfiguration(definedFile); - Lang.setFile(config); - getLogger().info("Loaded lang for " + definedLanguage); - } - public HashMap getSetSign() { return this.setSign; } @@ -572,4 +538,16 @@ public class PlayerVaults extends JavaPlugin { public int getMaxVaultAmountPermTest() { return this.maxVaultAmountPermTest; } + + public BukkitAudiences getPlatform() { + return this.platform; + } + + public Translation getTL() { + return this.translation; + } + + public String getVaultTitle(String id) { + return this.translation.vaultTitle().with("vault", id).getLegacy(); + } } diff --git a/src/main/java/com/drtshock/playervaults/commands/ConvertCommand.java b/src/main/java/com/drtshock/playervaults/commands/ConvertCommand.java index d57e95e..4f1ce56 100644 --- a/src/main/java/com/drtshock/playervaults/commands/ConvertCommand.java +++ b/src/main/java/com/drtshock/playervaults/commands/ConvertCommand.java @@ -21,7 +21,6 @@ package com.drtshock.playervaults.commands; import com.drtshock.playervaults.PlayerVaults; import com.drtshock.playervaults.converters.BackpackConverter; import com.drtshock.playervaults.converters.Converter; -import com.drtshock.playervaults.translations.Lang; import com.drtshock.playervaults.vaultmanagement.VaultOperations; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -33,18 +32,20 @@ import java.util.List; public class ConvertCommand implements CommandExecutor { private final List converters = new ArrayList<>(); + private final PlayerVaults plugin; - public ConvertCommand() { + public ConvertCommand(PlayerVaults plugin) { converters.add(new BackpackConverter()); + this.plugin = plugin; } @Override public boolean onCommand(final CommandSender sender, Command command, String label, String[] args) { if (!sender.hasPermission("playervaults.convert")) { - sender.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS); + this.plugin.getTL().noPerms().title().send(sender); } else { if (args.length == 0) { - sender.sendMessage(Lang.TITLE + "/" + label + " "); + sender.sendMessage("/" + label + " "); } else { String name = args[0]; final List applicableConverters = new ArrayList<>(); @@ -58,10 +59,10 @@ public class ConvertCommand implements CommandExecutor { } } if (applicableConverters.size() <= 0) { - sender.sendMessage(Lang.TITLE.toString() + Lang.CONVERT_PLUGIN_NOT_FOUND); + this.plugin.getTL().convertPluginNotFound().title().send(sender); } else { // Fork into background - sender.sendMessage(Lang.TITLE + Lang.CONVERT_BACKGROUND.toString()); + this.plugin.getTL().convertBackground().title().send(sender); PlayerVaults.getInstance().getServer().getScheduler().runTaskLaterAsynchronously(PlayerVaults.getInstance(), () -> { int converted = 0; VaultOperations.setLocked(true); @@ -71,7 +72,7 @@ public class ConvertCommand implements CommandExecutor { } } VaultOperations.setLocked(false); - sender.sendMessage(Lang.TITLE + Lang.CONVERT_COMPLETE.toString().replace("%converted", converted + "")); + this.plugin.getTL().convertComplete().title().with("count", converted + "").send(sender); }, 5); } } diff --git a/src/main/java/com/drtshock/playervaults/commands/DeleteCommand.java b/src/main/java/com/drtshock/playervaults/commands/DeleteCommand.java index eade262..23c40ca 100644 --- a/src/main/java/com/drtshock/playervaults/commands/DeleteCommand.java +++ b/src/main/java/com/drtshock/playervaults/commands/DeleteCommand.java @@ -19,11 +19,9 @@ package com.drtshock.playervaults.commands; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultOperations; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -31,11 +29,16 @@ import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; public class DeleteCommand implements CommandExecutor { + private final PlayerVaults plugin; + + public DeleteCommand(PlayerVaults plugin) { + this.plugin = plugin; + } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (VaultOperations.isLocked()) { - sender.sendMessage(Lang.TITLE + Lang.LOCKED.toString()); + this.plugin.getTL().locked().title().send(sender); return true; } switch (args.length) { @@ -43,7 +46,7 @@ public class DeleteCommand implements CommandExecutor { if (sender instanceof Player) { VaultOperations.deleteOwnVault((Player) sender, args[0]); } else { - sender.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.PLAYER_ONLY); + this.plugin.getTL().playerOnly().title().send(sender); } break; case 2: @@ -57,19 +60,19 @@ public class DeleteCommand implements CommandExecutor { if (args[1].equalsIgnoreCase("all")) { if (sender.hasPermission("playervaults.delete.all")) { VaultManager.getInstance().deleteAllVaults(target); - sender.sendMessage(Lang.TITLE.toString() + Lang.DELETE_OTHER_VAULT_ALL.toString().replaceAll("%p", target)); + this.plugin.getTL().deleteOtherVaultAll().title().with("player", target).send(sender); PlayerVaults.getInstance().getLogger().info(String.format("%s deleted ALL vaults belonging to %s", sender.getName(), target)); } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS); + this.plugin.getTL().noPerms().title().send(sender); } } VaultOperations.deleteOtherVault(sender, target, args[1]); break; default: - sender.sendMessage(Lang.TITLE + "/" + label + " "); - sender.sendMessage(Lang.TITLE + "/" + label + " "); - sender.sendMessage(Lang.TITLE + "/" + label + " all"); + sender.sendMessage("/" + label + " "); + sender.sendMessage("/" + label + " "); + sender.sendMessage("/" + label + " all"); } return true; } diff --git a/src/main/java/com/drtshock/playervaults/commands/SignCommand.java b/src/main/java/com/drtshock/playervaults/commands/SignCommand.java index b3fea75..901bd4e 100644 --- a/src/main/java/com/drtshock/playervaults/commands/SignCommand.java +++ b/src/main/java/com/drtshock/playervaults/commands/SignCommand.java @@ -19,19 +19,23 @@ package com.drtshock.playervaults.commands; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; public class SignCommand implements CommandExecutor { + private final PlayerVaults plugin; + + public SignCommand(PlayerVaults plugin) { + this.plugin = plugin; + } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (sender.hasPermission("playervaults.signs.set")) { if (!PlayerVaults.getInstance().getConf().isSigns()) { - sender.sendMessage(Lang.TITLE.toString() + Lang.SIGNS_DISABLED.toString()); + this.plugin.getTL().signsDisabled().title().send(sender); return true; } if (sender instanceof Player) { @@ -40,31 +44,31 @@ public class SignCommand implements CommandExecutor { try { i = Integer.parseInt(args[0]); } catch (NumberFormatException nfe) { - sender.sendMessage(Lang.TITLE.toString() + Lang.MUST_BE_NUMBER); - sender.sendMessage(Lang.TITLE.toString() + "Usage: /" + label + " [owner] <#>"); + this.plugin.getTL().mustBeNumber().title().send(sender); + sender.sendMessage(" /" + label + " [owner] <#>"); return true; } PlayerVaults.getInstance().getSetSign().put(sender.getName(), new SignSetInfo(i)); - sender.sendMessage(Lang.TITLE.toString() + Lang.CLICK_A_SIGN); + this.plugin.getTL().clickASign().title().send(sender); } else if (args.length >= 2) { int i; try { i = Integer.parseInt(args[1]); } catch (NumberFormatException nfe) { - sender.sendMessage(Lang.TITLE.toString() + Lang.MUST_BE_NUMBER); - sender.sendMessage(Lang.TITLE.toString() + "Usage: /" + label + " [owner] <#>"); + this.plugin.getTL().mustBeNumber().title().send(sender); + sender.sendMessage(" /" + label + " [owner] <#>"); return true; } PlayerVaults.getInstance().getSetSign().put(sender.getName(), new SignSetInfo(args[0].toLowerCase(), i)); - sender.sendMessage(Lang.TITLE.toString() + Lang.CLICK_A_SIGN); + this.plugin.getTL().clickASign().title().send(sender); } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.INVALID_ARGS); + this.plugin.getTL().invalidArgs().title().send(sender); } } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.PLAYER_ONLY); + this.plugin.getTL().playerOnly().title().send(sender); } } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS); + this.plugin.getTL().noPerms().title().send(sender); } return true; diff --git a/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java b/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java index e648df4..ee208c6 100644 --- a/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java +++ b/src/main/java/com/drtshock/playervaults/commands/VaultCommand.java @@ -19,12 +19,10 @@ package com.drtshock.playervaults.commands; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultOperations; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -33,11 +31,16 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; public class VaultCommand implements CommandExecutor { + private final PlayerVaults plugin; + + public VaultCommand(PlayerVaults plugin) { + this.plugin = plugin; + } @Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { if (VaultOperations.isLocked()) { - sender.sendMessage(Lang.TITLE + Lang.LOCKED.toString()); + this.plugin.getTL().locked().title().send(sender); return true; } @@ -61,20 +64,20 @@ public class VaultCommand implements CommandExecutor { YamlConfiguration file = VaultManager.getInstance().getPlayerVaultFile(target, false); if (file == null) { - sender.sendMessage(Lang.TITLE.toString() + Lang.VAULT_DOES_NOT_EXIST.toString()); + this.plugin.getTL().vaultDoesNotExist().title().send(sender); } else { StringBuilder sb = new StringBuilder(); for (String key : file.getKeys(false)) { sb.append(key.replace("vault", "")).append(" "); } - sender.sendMessage(Lang.TITLE.toString() + Lang.EXISTING_VAULTS.toString().replaceAll("%p", args[0]).replaceAll("%v", sb.toString().trim())); + this.plugin.getTL().existingVaults().title().with("player", args[0]).with("vault", sb.toString().trim()).send(sender); } } break; case 2: if (!player.hasPermission("playervaults.admin")) { - player.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS.toString()); + this.plugin.getTL().noPerms().title().send(sender); break; } @@ -82,7 +85,7 @@ public class VaultCommand implements CommandExecutor { try { number = Integer.parseInt(args[1]); } catch (NumberFormatException e) { - player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); + this.plugin.getTL().mustBeNumber().title().send(sender); return true; } @@ -94,14 +97,14 @@ public class VaultCommand implements CommandExecutor { if (VaultOperations.openOtherVault(player, target, args[1])) { PlayerVaults.getInstance().getInVault().put(player.getUniqueId().toString(), new VaultViewInfo(target, number)); } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.NO_OWNER_FOUND.toString().replaceAll("%p", args[0])); + this.plugin.getTL().noOwnerFound().title().with("player", args[0]).send(sender); } break; default: - sender.sendMessage(Lang.TITLE.toString() + Lang.HELP.toString()); + this.plugin.getTL().help().title().send(sender); } } else { - sender.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.PLAYER_ONLY.toString()); + this.plugin.getTL().playerOnly().title().send(sender); } return true; diff --git a/src/main/java/com/drtshock/playervaults/config/Loader.java b/src/main/java/com/drtshock/playervaults/config/Loader.java index fa71b45..d025ee0 100644 --- a/src/main/java/com/drtshock/playervaults/config/Loader.java +++ b/src/main/java/com/drtshock/playervaults/config/Loader.java @@ -21,6 +21,7 @@ import com.drtshock.playervaults.PlayerVaults; import com.drtshock.playervaults.config.annotation.Comment; import com.drtshock.playervaults.config.annotation.ConfigName; import com.drtshock.playervaults.config.annotation.WipeOnReload; +import com.drtshock.playervaults.config.file.Translation; import com.drtshock.playervaults.lib.com.typesafe.config.Config; import com.drtshock.playervaults.lib.com.typesafe.config.ConfigFactory; import com.drtshock.playervaults.lib.com.typesafe.config.ConfigRenderOptions; @@ -39,6 +40,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -70,7 +72,7 @@ public class Loader { Files.write(file.toPath(), s.getBytes(StandardCharsets.UTF_8)); } - public static ConfigValue load(Config config, Object configObject) throws IOException, IllegalAccessException { + public static @NonNull ConfigValue load(Config config, Object configObject) throws IllegalAccessException { return Loader.loadNode(config, configObject); } @@ -89,6 +91,7 @@ public class Loader { Loader.types.add(Map.class); Loader.types.add(Set.class); Loader.types.add(String.class); + Loader.types.add(Translation.TL.class); } private static @NonNull ConfigValue loadNode(@NonNull Config config, @NonNull Object object) throws IllegalAccessException { @@ -120,17 +123,48 @@ public class Loader { Object defaultValue = field.get(object); if (Loader.types.contains(field.getType())) { if (needsValue) { - newValue = ConfigValueFactory.fromAnyRef(defaultValue); + if (Translation.TL.class.isAssignableFrom(field.getType())) { + Translation.TL tl = (Translation.TL) defaultValue; + newValue = tl.size() == 1 ? ConfigValueFactory.fromAnyRef(tl.get(0)) : ConfigValueFactory.fromAnyRef(tl); + } else { + newValue = ConfigValueFactory.fromAnyRef(defaultValue); + } } else { + dance: try { - if (Set.class.isAssignableFrom(field.getType()) && curValue.valueType() == ConfigValueType.LIST) { + if (Translation.TL.class.isAssignableFrom(field.getType())) { + Translation.TL tl; + if (curValue.valueType() == ConfigValueType.STRING) { + String s = curValue.unwrapped().toString(); + tl = Translation.TL.copyOf(Collections.singletonList(s)); + } else if (curValue.valueType() == ConfigValueType.LIST) { + List l = (List) curValue.unwrapped(); + tl = Translation.TL.copyOf(l); + } else { + tl = (Translation.TL) defaultValue; + } + newValue = tl.size() == 1 ? ConfigValueFactory.fromAnyRef(tl.get(0)) : ConfigValueFactory.fromAnyRef(tl); + field.set(object, tl); + break dance; + } + if (List.class.isAssignableFrom(field.getType()) && curValue.valueType() == ConfigValueType.STRING) { + List list = Collections.singletonList(curValue.unwrapped()); + field.set(object, list); + newValue = ConfigValueFactory.fromAnyRef(list); + break dance; + } else if (Set.class.isAssignableFrom(field.getType()) && curValue.valueType() == ConfigValueType.STRING) { + Set set = Collections.singleton(curValue.unwrapped()); + field.set(object, set); + newValue = ConfigValueFactory.fromAnyRef(set); + break dance; + } else if (Set.class.isAssignableFrom(field.getType()) && curValue.valueType() == ConfigValueType.LIST) { field.set(object, new HashSet((List) curValue.unwrapped())); } else { field.set(object, curValue.unwrapped()); } newValue = curValue; } catch (IllegalArgumentException ex) { - System.out.println("Found incorrect type for " + confName + ": Expected " + field.getType() + ", found " + curValue.unwrapped().getClass()); + PlayerVaults.getInstance().getLogger().warning("Found incorrect type for " + confName + ": Expected " + field.getType() + ", found " + curValue.unwrapped().getClass()); field.set(object, defaultValue); newValue = ConfigValueFactory.fromAnyRef(defaultValue); } @@ -150,7 +184,7 @@ public class Loader { return config.hasPath(path) ? config.getValue(path) : null; } - private static @NonNull List getFields(Class clazz) { + private static @NonNull List getFields(@NonNull Class clazz) { return Loader.getFields(new ArrayList<>(), clazz); } diff --git a/src/main/java/com/drtshock/playervaults/config/file/Config.java b/src/main/java/com/drtshock/playervaults/config/file/Config.java index 08a5861..b8a60b3 100644 --- a/src/main/java/com/drtshock/playervaults/config/file/Config.java +++ b/src/main/java/com/drtshock/playervaults/config/file/Config.java @@ -116,7 +116,7 @@ public class Config { "Resource page: https://www.spigotmc.org/resources/51204/\n" + "Discord server: https://discordapp.com/invite/JZcWDEt/\n" + "Made with love <3") - private boolean aPleasantHello=true; + private boolean aPleasantHello = true; @Comment("Debug Mode\n" + " This will print everything the plugin is doing to console.\n" + @@ -127,11 +127,6 @@ public class Config { "Default: 6") private int defaultVaultRows = 6; - @Comment("Language\n" + - " This determines which language file the plugin will read from.\n" + - " Valid options are (don't include .yml): bulgarian, danish, dutch, english, german, turkish, russian") - private String language = "english"; - @Comment("Signs\n" + " This will determine whether vault signs are enabled.\n" + " If you don't know what this is or if it's for you, see the resource page.") @@ -161,25 +156,24 @@ public class Config { public void setFromConfig(Logger l, FileConfiguration c) { l.info("Importing old configuration..."); - l.info("debug = "+(this.debug = c.getBoolean("debug", false))); - l.info("language = "+(this.language = c.getString("language", "english"))); - l.info("signs = "+(this.signs = c.getBoolean("signs-enabled", false))); - l.info("economy enabled = "+(this.economy.enabled = c.getBoolean("economy.enabled", false))); - l.info(" creation fee = "+(this.economy.feeToCreate = c.getDouble("economy.cost-to-create", 100))); - l.info(" open fee = "+(this.economy.feeToOpen = c.getDouble("economy.cost-to-open", 10))); - l.info(" refund = "+(this.economy.refundOnDelete = c.getDouble("economy.refund-on-delete", 50))); - l.info("item blocking enabled = "+(this.itemBlocking.enabled = c.getBoolean("blockitems", true))); - l.info("blocked items = "+(this.itemBlocking.list = c.getStringList("blocked-items"))); + l.info("debug = " + (this.debug = c.getBoolean("debug", false))); + l.info("signs = " + (this.signs = c.getBoolean("signs-enabled", false))); + l.info("economy enabled = " + (this.economy.enabled = c.getBoolean("economy.enabled", false))); + l.info(" creation fee = " + (this.economy.feeToCreate = c.getDouble("economy.cost-to-create", 100))); + l.info(" open fee = " + (this.economy.feeToOpen = c.getDouble("economy.cost-to-open", 10))); + l.info(" refund = " + (this.economy.refundOnDelete = c.getDouble("economy.refund-on-delete", 50))); + l.info("item blocking enabled = " + (this.itemBlocking.enabled = c.getBoolean("blockitems", true))); + l.info("blocked items = " + (this.itemBlocking.list = c.getStringList("blocked-items"))); if (this.itemBlocking.list == null) { this.itemBlocking.list = new ArrayList<>(); this.itemBlocking.list.add("PUMPKIN"); this.itemBlocking.list.add("DIAMOND_BLOCK"); - l.info(" set defaults: "+this.itemBlocking.list); + l.info(" set defaults: " + this.itemBlocking.list); } - l.info("cleanup purge enabled = "+(this.purge.enabled = c.getBoolean("cleanup.enable", false))); - l.info(" days since last edit = "+(this.purge.daysSinceLastEdit = c.getInt("cleanup.lastEdit", 30))); - l.info("flatfile storage backups = "+(this.storage.flatFile.backups = c.getBoolean("backups.enabled", true))); - l.info("max vault amount to test via perms = "+(this.maxVaultAmountPermTest = c.getInt("max-vault-amount-perm-to-test", 99))); + l.info("cleanup purge enabled = " + (this.purge.enabled = c.getBoolean("cleanup.enable", false))); + l.info(" days since last edit = " + (this.purge.daysSinceLastEdit = c.getInt("cleanup.lastEdit", 30))); + l.info("flatfile storage backups = " + (this.storage.flatFile.backups = c.getBoolean("backups.enabled", true))); + l.info("max vault amount to test via perms = " + (this.maxVaultAmountPermTest = c.getInt("max-vault-amount-perm-to-test", 99))); } public boolean isDebug() { @@ -190,10 +184,6 @@ public class Config { return this.defaultVaultRows; } - public String getLanguage() { - return this.language; - } - public boolean isSigns() { return this.signs; } diff --git a/src/main/java/com/drtshock/playervaults/config/file/Translation.java b/src/main/java/com/drtshock/playervaults/config/file/Translation.java new file mode 100644 index 0000000..6e5c30e --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/config/file/Translation.java @@ -0,0 +1,362 @@ +package com.drtshock.playervaults.config.file; + +import com.drtshock.playervaults.PlayerVaults; +import com.google.common.collect.ImmutableMap; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.craftbukkit.BukkitComponentSerializer; +import org.bukkit.command.CommandSender; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@SuppressWarnings("FieldMayBeFinal") +public class Translation { + public static class TL extends ArrayList { + private static transient PlayerVaults plugin; + private static transient final Pattern REPLACEMENT_PATTERN = Pattern.compile("(?:\\{([a-zA-Z0-9\\-_]+)(?:(?::)([a-zA-Z0-9_\\-|]+))?})"); + private static transient final Pattern TAG_PATTERN = Pattern.compile("(?:<(/?)([a-zA-Z\\-_]+)>)"); + private static transient final String SKIP_LINE_IF_MISSING = "s"; + private static transient final String BLANK_IF_MISSING = "b"; + private static transient final String PRE_FORMATTED = "p"; + + private static @NonNull TL of(@NonNull String... strings) { + TL list = new TL(); + Collections.addAll(list, strings); + return list; + } + + public static @NonNull TL copyOf(@NonNull Collection collection) { + TL list = new TL(); + list.addAll(collection); + return list; + } + + public class Builder { + private transient ImmutableMap.Builder map; + private transient TL title; + + private Builder(@NonNull TL title) { + this.title = title; + } + + private Builder(@NonNull String key, @Nullable String value) { + this.with(key, value); + } + + public @NonNull Builder with(@NonNull String key, @Nullable String value) { + if (this.map == null) { + this.map = ImmutableMap.builder(); + } + this.map.put(key, value); + return this; + } + + public void send(@NonNull CommandSender sender) { + TL.this.send(sender, this.map == null ? Collections.emptyMap() : this.map.build(), this.title); + } + + public @NonNull String getLegacy() { + return TL.this.getLegacy(this.map == null ? Collections.emptyMap() : this.map.build(), this.title); + } + } + + public @NonNull Builder with(@NonNull String key, @Nullable String value) { + return new Builder(key, value); + } + + public @NonNull Builder title() { + return new Builder(TL.plugin.getTL().title()); + } + + public @NonNull Builder title(@NonNull TL title) { + return new Builder(title); + } + + public void send(@NonNull CommandSender sender) { + this.send(sender, Collections.emptyMap(), null); + } + + private void send(@NonNull CommandSender sender, @NonNull Map map, @Nullable TL title) { + this.send(TL.plugin.getPlatform().sender(sender), map, title); + } + + private void send(@NonNull Audience audience, @NonNull Map map, @Nullable TL title) { + this.forEach(line -> { + Component component = this.getComponent(line, map, title); + if (component != null) { + audience.sendMessage(component); + } + }); + } + + private @Nullable Component getComponent(@NonNull String line, @NonNull Map map, @Nullable TL title) { + if (title != null && !title.isEmpty()) { + line = title.get(0) + line; + } + StringBuffer builder = null; + String found; + String foundDetails; + String repl; + String[] features; + Matcher replMatcher = TL.REPLACEMENT_PATTERN.matcher(line); + while (replMatcher.find()) { + if (builder == null) { + builder = new StringBuffer(); + } + found = replMatcher.group(1); + foundDetails = replMatcher.group(2); + features = foundDetails == null ? null : foundDetails.split("\\|"); + repl = map.get(found); + if (repl == null) { + if (this.arrContains(features, TL.SKIP_LINE_IF_MISSING)) { + return null; + } + if (this.arrContains(features, TL.BLANK_IF_MISSING)) { + replMatcher.appendReplacement(builder, ""); + } + } else { + if (this.arrContains(features, TL.PRE_FORMATTED)) { + repl = MiniMessage.get().escapeTokens(repl).replace("\\", "\\\\"); + } + replMatcher.appendReplacement(builder, repl); + } + } + if (builder != null) { + replMatcher.appendTail(builder); + line = builder.toString(); + builder = null; + } + + Matcher tagMatcher = TL.TAG_PATTERN.matcher(line); + while (tagMatcher.find()) { + if (builder == null) { + builder = new StringBuffer(); + } + found = tagMatcher.group(2); + repl = TL.plugin.getTL().colorMappings().get(found); + if (repl != null) { + tagMatcher.appendReplacement(builder, '<' + tagMatcher.group(1) + repl + '>'); + } + } + if (builder != null) { + tagMatcher.appendTail(builder); + line = builder.toString(); + } + return MiniMessage.get().parse(line); + } + + public @NonNull String getLegacy() { + return this.getLegacy(Collections.emptyMap(), null); + } + + public @NonNull String getLegacy(@NonNull Map map) { + return this.getLegacy(map, null); + } + + public @NonNull String getLegacy(@NonNull Map map, @Nullable TL title) { + return this.stream() + .map(line -> this.getComponent(line, map, title)) + .filter(Objects::nonNull) + .map(component -> BukkitComponentSerializer.legacy().serialize(component)) + .collect(Collectors.joining("\n")); + } + + public boolean arrContains(@Nullable String[] array, @NonNull String target) { + if (array == null) { + return false; + } + for (String string : array) { + if (target.equals(string)) { + return true; + } + } + return false; + } + } + + private static class Placeholders { + private TL title = TL.of("[PlayerVaults]: "); + } + + private static class Translations { + private TL openVault = TL.of("Opening vault {vault}"); + private TL openOtherVault = TL.of("Opening vault {vault} of {player}"); + private TL invalidArgs = TL.of("Invalid args!"); + private TL deleteVault = TL.of("Deleted vault {vault}"); + private TL deleteOtherVault = TL.of("Deleted vault {vault} of {player}"); + private TL deleteOtherVaultAll = TL.of("Deleted all vaults belonging to {player}"); + private TL playerOnly = TL.of("Sorry but that can only be run by a player!"); + private TL mustBeNumber = TL.of("You need to specify a valid number."); + private TL noPerms = TL.of("You don't have permission for that!"); + private TL insufficientFunds = TL.of("You don't have enough money for that!"); + private TL refundAmount = TL.of("You were refunded {price} for deleting that vault."); + private TL costToCreate = TL.of("You were charged {price} for creating a vault."); + private TL costToOpen = TL.of("You were charged {price} for opening that vault."); + private TL vaultDoesNotExist = TL.of("That vault does not exist!"); + private TL clickASign = TL.of("Now click a sign!"); + private TL notASign = TL.of("You must click a sign!"); + private TL setSign = TL.of("You have successfully set a PlayerVault access sign!"); + private TL existingVaults = TL.of("{player} has vaults: {vault}"); + private TL vaultTitle = TL.of("Vault #{vault}"); + private TL openWithSign = TL.of("Opening vault {vault} of {player}"); + private TL noOwnerFound = TL.of("Cannot find vault owner: {player}"); + private TL convertPluginNotFound = TL.of("No converter found for that plugin."); + private TL convertComplete = TL.of("Converted {count} players to PlayerVaults."); + private TL convertBackground = TL.of("Conversion has been forked to the background. See console for updates."); + private TL locked = TL.of("Vaults are currently locked while conversion occurs. Please try again in a moment!"); + private TL help = TL.of("/pv "); + private TL blockedItem = TL.of("{item} is blocked from vaults."); + private TL signsDisabled = TL.of("Vault signs are currently disabled."); + private TL blockedBadItem = TL.of("This item is not allowed in a vault."); + } + + private Placeholders placeholders = new Placeholders(); + private Translations translations = new Translations(); + + public Translation(@NonNull PlayerVaults plugin) { + TL.plugin = plugin; + } + + private Map colorMappings = new HashMap() { + { + this.put("error", "red"); + this.put("normal", "white"); + this.put("info", "green"); + } + }; + + public @NonNull TL title() { + return this.placeholders.title; + } + + public @NonNull TL openVault() { + return this.translations.openVault; + } + + public @NonNull TL openOtherVault() { + return this.translations.openOtherVault; + } + + public @NonNull TL invalidArgs() { + return this.translations.invalidArgs; + } + + public @NonNull TL deleteVault() { + return this.translations.deleteVault; + } + + public @NonNull TL deleteOtherVault() { + return this.translations.deleteOtherVault; + } + + public @NonNull TL deleteOtherVaultAll() { + return this.translations.deleteOtherVaultAll; + } + + public @NonNull TL playerOnly() { + return this.translations.playerOnly; + } + + public @NonNull TL mustBeNumber() { + return this.translations.mustBeNumber; + } + + public @NonNull TL noPerms() { + return this.translations.noPerms; + } + + public @NonNull TL insufficientFunds() { + return this.translations.insufficientFunds; + } + + public @NonNull TL refundAmount() { + return this.translations.refundAmount; + } + + public @NonNull TL costToCreate() { + return this.translations.costToCreate; + } + + public @NonNull TL costToOpen() { + return this.translations.costToOpen; + } + + public @NonNull TL vaultDoesNotExist() { + return this.translations.vaultDoesNotExist; + } + + public @NonNull TL clickASign() { + return this.translations.clickASign; + } + + public @NonNull TL notASign() { + return this.translations.notASign; + } + + public @NonNull TL setSign() { + return this.translations.setSign; + } + + public @NonNull TL existingVaults() { + return this.translations.existingVaults; + } + + public @NonNull TL vaultTitle() { + return this.translations.vaultTitle; + } + + public @NonNull TL openWithSign() { + return this.translations.openWithSign; + } + + public @NonNull TL noOwnerFound() { + return this.translations.noOwnerFound; + } + + public @NonNull TL convertPluginNotFound() { + return this.translations.convertPluginNotFound; + } + + public @NonNull TL convertComplete() { + return this.translations.convertComplete; + } + + public @NonNull TL convertBackground() { + return this.translations.convertBackground; + } + + public @NonNull TL locked() { + return this.translations.locked; + } + + public @NonNull TL help() { + return this.translations.help; + } + + public @NonNull TL blockedItem() { + return this.translations.blockedItem; + } + + public @NonNull TL signsDisabled() { + return this.translations.signsDisabled; + } + + public @NonNull TL blockedBadItem() { + return this.translations.blockedBadItem; + } + + public @NonNull Map colorMappings() { + return Collections.unmodifiableMap(this.colorMappings); + } +} diff --git a/src/main/java/com/drtshock/playervaults/listeners/Listeners.java b/src/main/java/com/drtshock/playervaults/listeners/Listeners.java index ef5f7e5..410df02 100644 --- a/src/main/java/com/drtshock/playervaults/listeners/Listeners.java +++ b/src/main/java/com/drtshock/playervaults/listeners/Listeners.java @@ -19,7 +19,6 @@ package com.drtshock.playervaults.listeners; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import com.drtshock.playervaults.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; import org.bukkit.Bukkit; @@ -121,7 +120,7 @@ public class Listeners implements Listener { if (info != null) { int num = info.getNumber(); String inventoryTitle = event.getView().getTitle(); - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(num)).replace("%p", info.getVaultName()); + String title = this.plugin.getVaultTitle(String.valueOf(num)); if (inventoryTitle.equalsIgnoreCase(title)) { ItemStack[] items = new ItemStack[2]; items[0] = event.getCurrentItem(); @@ -133,16 +132,9 @@ public class Listeners implements Listener { if (item == null) { continue; } - try { - item.toString(); - } catch (Exception e) { - player.sendMessage(Lang.TITLE.toString() + Lang.BLOCKED_BAD_ITEM); - event.setCancelled(true); - return; - } if (!player.hasPermission("playervaults.bypassblockeditems") && PlayerVaults.getInstance().isBlockedMaterial(item.getType())) { event.setCancelled(true); - player.sendMessage(Lang.TITLE.toString() + Lang.BLOCKED_ITEM.toString().replace("%m", item.getType().name())); + this.plugin.getTL().blockedItem().title().with("item", item.getType().name()).send(player); return; } } @@ -165,19 +157,12 @@ public class Listeners implements Listener { if (info != null) { int num = info.getNumber(); String inventoryTitle = event.getView().getTitle(); - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(num)).replace("%p", info.getVaultName()); + String title = this.plugin.getVaultTitle(String.valueOf(num)); if ((inventoryTitle != null && inventoryTitle.equalsIgnoreCase(title)) && event.getNewItems() != null) { for (ItemStack item : event.getNewItems().values()) { - try { - item.toString(); - } catch (Exception e) { - player.sendMessage(Lang.TITLE.toString() + Lang.BLOCKED_BAD_ITEM); - event.setCancelled(true); - continue; - } if (!player.hasPermission("playervaults.bypassblockeditems") && PlayerVaults.getInstance().isBlockedMaterial(item.getType())) { event.setCancelled(true); - player.sendMessage(Lang.TITLE.toString() + Lang.BLOCKED_ITEM.toString().replace("%m", item.getType().name())); + this.plugin.getTL().blockedItem().title().with("item", item.getType().name()).send(player); return; } } diff --git a/src/main/java/com/drtshock/playervaults/listeners/SignListener.java b/src/main/java/com/drtshock/playervaults/listeners/SignListener.java index cc6d00b..56483d6 100644 --- a/src/main/java/com/drtshock/playervaults/listeners/SignListener.java +++ b/src/main/java/com/drtshock/playervaults/listeners/SignListener.java @@ -19,7 +19,6 @@ package com.drtshock.playervaults.listeners; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import com.drtshock.playervaults.vaultmanagement.VaultOperations; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; import org.bukkit.Bukkit; @@ -38,7 +37,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.InventoryHolder; public class SignListener implements Listener { - private PlayerVaults plugin; + private final PlayerVaults plugin; /** * TODO: Some of these events can be lag inducing (specifically: interactions & block breaking), @@ -88,12 +87,12 @@ public class SignListener implements Listener { } plugin.getSigns().set(world + ";;" + x + ";;" + y + ";;" + z + ".chest", i); plugin.saveSigns(); - player.sendMessage(Lang.TITLE.toString() + Lang.SET_SIGN); + this.plugin.getTL().setSign().title().send(player); } else { - player.sendMessage(Lang.TITLE.toString() + Lang.NOT_A_SIGN); + this.plugin.getTL().notASign().title().send(player); } } else { - player.sendMessage(Lang.TITLE.toString() + Lang.NOT_A_SIGN); + this.plugin.getTL().notASign().title().send(player); } return; } @@ -120,7 +119,7 @@ public class SignListener implements Listener { OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(owner != null ? owner : event.getPlayer().getName()); // Not best way but :\ if (offlinePlayer == null || (!offlinePlayer.isOnline() && !offlinePlayer.hasPlayedBefore())) { PlayerVaults.debug("Denied sign vault for never-seen-before owner " + owner); - player.sendMessage(Lang.TITLE.toString() + Lang.VAULT_DOES_NOT_EXIST.toString()); + this.plugin.getTL().vaultDoesNotExist().title().send(player); return; } if (self) { @@ -139,10 +138,10 @@ public class SignListener implements Listener { } PlayerVaults.debug("Player " + player.getName() + " succeeded in opening sign vault"); event.setCancelled(true); - player.sendMessage(Lang.TITLE.toString() + Lang.OPEN_WITH_SIGN.toString().replace("%v", String.valueOf(num)).replace("%p", owner)); + this.plugin.getTL().openWithSign().title().with("vault", String.valueOf(num)).with("player", owner).send(player); } else { - player.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS); PlayerVaults.debug("Player " + player.getName() + " no sign perms!"); + this.plugin.getTL().noPerms().title().send(player); } } } diff --git a/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java b/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java index 0b60aab..87326f2 100644 --- a/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java +++ b/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java @@ -19,15 +19,15 @@ package com.drtshock.playervaults.tasks; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.vaultmanagement.UUIDVaultManager; -import com.drtshock.playervaults.vaultmanagement.VaultManager; +import com.drtshock.playervaults.vaultmanagement.CardboardBoxSerialization; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.inventory.Inventory; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; import java.util.UUID; import java.util.logging.Logger; @@ -41,24 +41,36 @@ public final class Base64Conversion implements Runnable { Logger logger = PlayerVaults.getInstance().getLogger(); File newDir = PlayerVaults.getInstance().getVaultData(); + File oldVaults = PlayerVaults.getInstance().getDataFolder().toPath().resolve("base64vaults").toFile(); + File reallyOldVaults = PlayerVaults.getInstance().getDataFolder().toPath().resolve("uuidvaults").toFile(); if (newDir.exists()) { + PlayerVaults.getInstance().getDataFolder().toPath().resolve("oldVaultsData").toFile().mkdirs(); + if (oldVaults.exists()) { + try { + Files.move(oldVaults.toPath(), PlayerVaults.getInstance().getDataFolder().toPath().resolve("oldVaultsData").resolve("base64vaults")); + } catch (IOException e) { + PlayerVaults.getInstance().getLogger().warning("Failed to move old vaults dir: " + e.getMessage()); + } + } + if (reallyOldVaults.exists()) { + try { + Files.move(reallyOldVaults.toPath(), PlayerVaults.getInstance().getDataFolder().toPath().resolve("oldVaultsData").resolve("uuidvaults")); + } catch (IOException e) { + PlayerVaults.getInstance().getLogger().warning("Failed to move old vaults dir: " + e.getMessage()); + } + } return; } newDir.mkdirs(); - File oldVaults = PlayerVaults.getInstance().getUuidData(); if (!oldVaults.exists()) { - logger.info("No uuidvaults found to convert to base64."); + logger.info("No base64vaults found to convert to new format."); return; } - newDir.mkdirs(); - UUIDVaultManager oldManager = UUIDVaultManager.getInstance(); - VaultManager manager = VaultManager.getInstance(); - - logger.info("********** Starting conversion to Base64 for PlayerVaults **********"); + logger.info("********** Starting conversion from Base64 for PlayerVaults **********"); logger.info("This might take awhile."); logger.info(oldVaults.toString() + " will remain as a backup."); @@ -92,21 +104,27 @@ public final class Base64Conversion implements Runnable { continue; } - int vaultNumber = Integer.valueOf(key.replace("vault", "")); + int vaultNumber = Integer.parseInt(key.replace("vault", "")); try { - Inventory inventory = oldManager.getVault(holderUUID, vaultNumber); - manager.saveVault(inventory, holderUUID.toString(), vaultNumber); + String data = uuidFile.getString(key); + String newData = CardboardBoxSerialization.convert(data, holderUUID + " " + key); + uuidFile.set(key, newData); vaults++; } catch (Exception e) { logger.severe("Failed to parse vault " + vaultNumber + " for " + holderUUID); failed++; } } + try { + uuidFile.save(newDir.toPath().resolve(file.getName()).toFile()); + } catch (IOException e) { + logger.severe("Failed to save new file " + file.getName()); + } players++; } - logger.info(String.format("Converted %d vaults for %d players to base64. %d failed to convert", vaults, players, failed)); + logger.info(String.format("Converted %d vaults for %d players to new storage. %d failed to convert", vaults, players, failed)); } } diff --git a/src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java b/src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java deleted file mode 100644 index 91211d7..0000000 --- a/src/main/java/com/drtshock/playervaults/tasks/UUIDConversion.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * PlayerVaultsX - * Copyright (C) 2013 Trent Hensler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.drtshock.playervaults.tasks; - -import com.drtshock.playervaults.PlayerVaults; -import com.google.common.io.Files; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; - -import java.io.File; -import java.io.IOException; -import java.util.logging.Logger; - -/** - * Class to convert vaults by name to vaults by UUID. - */ -public final class UUIDConversion implements Runnable { - - @Override - public void run() { - Logger logger = PlayerVaults.getInstance().getLogger(); - - File newDir = PlayerVaults.getInstance().getVaultData(); - if (newDir.exists()) { - return; - } - - File oldVaults = new File(PlayerVaults.getInstance().getDataFolder() + File.separator + "vaults"); - if (oldVaults.exists()) { - logger.info("********** Starting conversion to UUIDs for PlayerVaults **********"); - logger.info("This might take awhile."); - logger.info(oldVaults.toString() + " will remain as a backup."); - - for (File file : oldVaults.listFiles()) { - if (file.isDirectory()) { - continue; // backups folder. - } - OfflinePlayer player = Bukkit.getOfflinePlayer(file.getName().replace(".yml", "")); - if (player == null) { - logger.warning("Unable to convert file because player never joined the server: " + file.getName()); - break; - } - - File newFile = new File(PlayerVaults.getInstance().getVaultData(), player.getUniqueId().toString() + ".yml"); - file.mkdirs(); - try { - Files.copy(file, newFile); - logger.info("Successfully converted vault file for " + player.getName()); - } catch (IOException e) { - logger.severe("Couldn't convert vault file for " + player.getName()); - } - } - - logger.info("********** Conversion done ;D **********"); - } - } -} diff --git a/src/main/java/com/drtshock/playervaults/translations/Lang.java b/src/main/java/com/drtshock/playervaults/translations/Lang.java deleted file mode 100644 index 4f2a100..0000000 --- a/src/main/java/com/drtshock/playervaults/translations/Lang.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * PlayerVaultsX - * Copyright (C) 2013 Trent Hensler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.drtshock.playervaults.translations; - -import org.bukkit.ChatColor; -import org.bukkit.configuration.file.YamlConfiguration; - -/** - * An enum for requesting strings from the language file. - */ -public enum Lang { - TITLE("title-name", "&4[&fPlayerVaults&4]:"), - OPEN_VAULT("open-vault", "&fOpening vault &a%v"), - OPEN_OTHER_VAULT("open-other-vault", "&fOpening vault &a%v &fof &a%p"), - INVALID_ARGS("invalid-args", "&cInvalid args!"), - DELETE_VAULT("delete-vault", "&fDeleted vault &a%v"), - DELETE_OTHER_VAULT("delete-other-vault", "&fDeleted vault &a%v &fof &a%p"), - DELETE_OTHER_VAULT_ALL("delete-other-vault-all", "&4Deleted all vaults belonging to &a%p"), - PLAYER_ONLY("player-only", "&cSorry but that can only be run by a player!"), - MUST_BE_NUMBER("must-be-number", "&cYou need to specify a valid number."), - NO_PERMS("no-permissions", "&cYou don''t have permission for that!"), - INSUFFICIENT_FUNDS("insufficient-funds", "&cYou don''t have enough money for that!"), - REFUND_AMOUNT("refund-amount", "&fYou were refunded &a%price &ffor deleting that vault."), - COST_TO_CREATE("cost-to-create", "&fYou were charged &c%price &ffor creating a vault."), - COST_TO_OPEN("cost-to-open", "&fYou were charged &c%price &ffor opening that vault."), - VAULT_DOES_NOT_EXIST("vault-does-not-exist", "&cThat vault does not exist!"), - CLICK_A_SIGN("click-a-sign", "&fNow click a sign!"), - NOT_A_SIGN("not-a-sign", "&cYou must click a sign!"), - SET_SIGN("set-sign-success", "&fYou have successfully set a PlayerVault access sign!"), - EXISTING_VAULTS("existing-vaults", "&f%p has vaults: &a%v"), - VAULT_TITLE("vault-title", "&4Vault #%number"), - OPEN_WITH_SIGN("open-with-sign", "&fOpening vault &a%v &fof &a%p"), - NO_OWNER_FOUND("no-owner-found", "&cCannot find vault owner: &a%p"), - CONVERT_PLUGIN_NOT_FOUND("plugin-not-found", "&cNo converter found for that plugin."), - CONVERT_COMPLETE("conversion-complete", "&aConverted %converted players to PlayerVaults."), - CONVERT_BACKGROUND("conversion-background", "&fConversion has been forked to the background. See console for updates."), - LOCKED("vaults-locked", "&cVaults are currently locked while conversion occurs. Please try again in a moment!"), - HELP("help", "/pv "), - BLOCKED_ITEM("blocked-item", "&6%m &cis blocked from vaults."), - SIGNS_DISABLED("signs-disabled", "&cVault signs are currently disabled."), - BLOCKED_BAD_ITEM("blocked-bad-item", "&cThis item is not allowed in a vault."); - - private static YamlConfiguration LANG; - private final String path; - private final String def; - - /** - * Lang enum constructor. - * - * @param path The string path. - * @param start The default string. - */ - Lang(String path, String start) { - this.path = path; - this.def = start; - } - - /** - * Set the {@code YamlConfiguration} to use. - * - * @param config The config to set. - */ - public static void setFile(YamlConfiguration config) { - LANG = config; - } - - @Override - public String toString() { - String extra = (this == TITLE && !LANG.getString(this.path, this.def).isEmpty()) ? " " : ""; - return ChatColor.translateAlternateColorCodes('&', LANG.getString(this.path, def)) + extra; - } - - /** - * Get the default value of the path. - * - * @return The default value of the path. - */ - public String getDefault() { - return this.def; - } - - /** - * Get the path to the string. - * - * @return The path to the string. - */ - public String getPath() { - return this.path; - } -} diff --git a/src/main/java/com/drtshock/playervaults/translations/Language.java b/src/main/java/com/drtshock/playervaults/translations/Language.java deleted file mode 100644 index dc0ce6d..0000000 --- a/src/main/java/com/drtshock/playervaults/translations/Language.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * PlayerVaultsX - * Copyright (C) 2013 Trent Hensler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.drtshock.playervaults.translations; - -public enum Language { - ENGLISH, - BULGARIAN, - TURKISH, - DUTCH, - GERMAN, - RUSSIAN, - DANISH; - - private String friendlyName; - - Language() { - this.friendlyName = this.name().toLowerCase(); - } - - public String getFriendlyName() { - return this.friendlyName; - } -} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java deleted file mode 100644 index 6ef5059..0000000 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/Base64Serialization.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * PlayerVaultsX - * Copyright (C) 2013 Trent Hensler, Laxwashere - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.drtshock.playervaults.vaultmanagement; - - -import com.drtshock.playervaults.PlayerVaults; -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; -import java.util.logging.Level; - -/** - * Created by Lax on 6/6/2017. - */ -public class Base64Serialization { - - public static String toBase64(Inventory inventory, int size) { - return toBase64(inventory, size, null); - } - - public static String toBase64(Inventory inventory, int size, String target) { - try { - ByteArrayOutputStream finalOutputStream = new ByteArrayOutputStream(); - ByteArrayOutputStream temporaryOutputStream = new ByteArrayOutputStream(); - BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(temporaryOutputStream); - int failedItems = 0; - - // Write the size of the inventory - dataOutput.writeInt(size); - - // Save every element in the list - for (int i = 0; i < inventory.getSize(); i++) { - try { - dataOutput.writeObject(inventory.getItem(i)); - } catch (Exception ignored) { - failedItems++; - temporaryOutputStream.reset(); - } finally { - if (temporaryOutputStream.size() == 0) { - dataOutput.writeObject(null); - } - finalOutputStream.write(temporaryOutputStream.toByteArray()); - temporaryOutputStream.reset(); - } - } - - if (failedItems > 0) { - PlayerVaults.getInstance().getLogger().severe("Failed to save " + failedItems + " invalid items to vault " + target); - } - PlayerVaults.debug("Serialized " + inventory.getSize() + " items"); - - // Serialize that array - dataOutput.close(); - return Base64Coder.encodeLines(finalOutputStream.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, size); - } - - public static Inventory fromBase64(String data) { - return fromBase64(data, null); - } - - public static Inventory fromBase64(String data, String target) { - 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(); - PlayerVaults.debug("Read " + inventory.getSize() + " items"); - return inventory; - } catch (Exception e) { - PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to load vault " + target, e); - } - return null; - } -} \ No newline at end of file diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java new file mode 100644 index 0000000..1dcb7ff --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java @@ -0,0 +1,84 @@ +package com.drtshock.playervaults.vaultmanagement; + +import com.drtshock.playervaults.PlayerVaults; +import org.bukkit.Material; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.kitteh.cardboardbox.CardboardBox; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.logging.Level; + +public class CardboardBoxSerialization { + public static String toStorage(Inventory inventory, String target) { + try { + return Base64Coder.encodeLines(writeInventory(inventory.getContents())); + } catch (IOException e) { + throw new IllegalStateException("Failed to save items for " + target, e); + } + } + + public static ItemStack[] fromStorage(String data, String target) { + if (data == null || data.isEmpty()) { + ItemStack[] i = new ItemStack[6 * 9]; + for (int x = 0; x < i.length; x++) { + i[x] = new ItemStack(Material.AIR); + } + return i; + } + try { + return readInventory(Base64Coder.decodeLines(data)); + } catch (IOException e) { + PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to load items for " + target, e); + return null; + } + } + + private static byte[] writeInventory(ItemStack[] contents) throws IOException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bytes); + out.writeInt(contents.length); + for (ItemStack content : contents) { + byte[] item = CardboardBox.serializeItem(content); + out.writeInt(item.length); + out.write(item); + } + out.close(); + return bytes.toByteArray(); + } + + private static ItemStack[] readInventory(byte[] data) throws IOException { + DataInputStream input = new DataInputStream(new ByteArrayInputStream(data)); + ItemStack[] contents = new ItemStack[input.readInt()]; + for (int i = 0; i < contents.length; i++) { + int len = input.readInt(); + byte[] itemBytes = new byte[len]; + input.readFully(itemBytes); + contents[i] = CardboardBox.deserializeItem(itemBytes); + } + return contents; + } + + public static String convert(String data, String target) { + try { + ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); + BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); + ItemStack[] contents = new ItemStack[dataInput.readInt()]; + // Read the serialized inventory + for (int i = 0; i < contents.length; i++) { + contents[i] = (ItemStack) dataInput.readObject(); + } + dataInput.close(); + return Base64Coder.encodeLines(writeInventory(contents)); + } catch (Exception e) { + PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to convert vault " + target, e); + } + return null; + } +} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java index e37703c..a0b6e36 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/EconomyOperations.java @@ -19,9 +19,7 @@ package com.drtshock.playervaults.vaultmanagement; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import net.milkbowl.vault.economy.EconomyResponse; -import org.bukkit.ChatColor; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -53,7 +51,7 @@ public class EconomyOperations { double cost = PlayerVaults.getInstance().getConf().getEconomy().getFeeToOpen(); EconomyResponse resp = PlayerVaults.getInstance().getEconomy().withdrawPlayer(player, cost); if (resp.transactionSuccess()) { - player.sendMessage(Lang.TITLE.toString() + Lang.COST_TO_OPEN.toString().replaceAll("%price", "" + cost)); + PlayerVaults.getInstance().getTL().costToOpen().title().with("price", cost + "").send(player); return true; } } @@ -75,7 +73,7 @@ public class EconomyOperations { double cost = PlayerVaults.getInstance().getConf().getEconomy().getFeeToCreate(); EconomyResponse resp = PlayerVaults.getInstance().getEconomy().withdrawPlayer(player, cost); if (resp.transactionSuccess()) { - player.sendMessage(Lang.TITLE.toString() + Lang.COST_TO_CREATE.toString().replaceAll("%price", "" + cost)); + PlayerVaults.getInstance().getTL().costToCreate().title().with("price", cost + "").send(player); return true; } @@ -98,18 +96,18 @@ public class EconomyOperations { if (playerFile.exists()) { YamlConfiguration playerData = YamlConfiguration.loadConfiguration(playerFile); if (playerData.getString("vault" + number) == null) { - player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.VAULT_DOES_NOT_EXIST); + PlayerVaults.getInstance().getTL().vaultDoesNotExist().title().send(player); return false; } } else { - player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.VAULT_DOES_NOT_EXIST); + PlayerVaults.getInstance().getTL().vaultDoesNotExist().title().send(player); return false; } double cost = PlayerVaults.getInstance().getConf().getEconomy().getRefundOnDelete(); EconomyResponse resp = PlayerVaults.getInstance().getEconomy().depositPlayer(player, cost); if (resp.transactionSuccess()) { - player.sendMessage(Lang.TITLE.toString() + Lang.REFUND_AMOUNT.toString().replaceAll("%price", String.valueOf(cost))); + PlayerVaults.getInstance().getTL().refundAmount().title().with("price", cost + "").send(player); return true; } diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java index b346f7d..c66b96a 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java @@ -27,7 +27,11 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; /** diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java deleted file mode 100644 index 0f5661c..0000000 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/UUIDVaultManager.java +++ /dev/null @@ -1,345 +0,0 @@ -/* - * PlayerVaultsX - * Copyright (C) 2013 Trent Hensler - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.drtshock.playervaults.vaultmanagement; - -import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.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; -import org.bukkit.scheduler.BukkitRunnable; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.logging.Level; - -/** - * Class to handle vault operations with new UUIDs. - */ -@Deprecated -public class UUIDVaultManager { - - private static UUIDVaultManager instance; - private final File directory = PlayerVaults.getInstance().getUuidData(); - private final Map cachedVaultFiles = new ConcurrentHashMap<>(); - - public UUIDVaultManager() { - instance = this; - } - - /** - * Get the instance of this class. - * - * @return - instance of this class. - */ - public static UUIDVaultManager getInstance() { - return instance; - } - - /** - * 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, String target, int number) { - int size = inventory.getSize(); - YamlConfiguration yaml = getPlayerVaultFile(target); - if (size == 54) { - yaml.set("vault" + number, null); - } else { - for (int x = 0; x < size; x++) { - yaml.set("vault" + number + "." + x, null); - } - } - List list = Serialization.toString(inventory); - String[] ser = list.toArray(new String[0]); - for (int x = 0; x < ser.length; x++) { - if (!ser[x].equalsIgnoreCase("null")) { - yaml.set("vault" + number + "." + x, ser[x]); - } - } - 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 = PlayerVaults.getInstance().getDefaultVaultSize(); - } - - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", player.getName()); - VaultViewInfo info = new VaultViewInfo(player.getUniqueId().toString(), number); - Inventory inv; - if (PlayerVaults.getInstance().getOpenInventories().containsKey(info.toString())) { - inv = PlayerVaults.getInstance().getOpenInventories().get(info.toString()); - } else { - YamlConfiguration playerFile = getPlayerVaultFile(player.getUniqueId()); - if (playerFile.getConfigurationSection("vault" + 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(String holder, int number, int size) { - if (size % 9 != 0) { - size = PlayerVaults.getInstance().getDefaultVaultSize(); - } - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", PlayerVaults.getInstance().getNameIfPlayer(holder)); - 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) { - List data = new ArrayList<>(); - for (int x = 0; x < size; x++) { - String line = playerFile.getString("vault" + number + "." + x); - if (line != null) { - data.add(line); - } else { - data.add("null"); - } - } - return Serialization.toInventory(data, number, size, title); - } - - /** - * 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. - */ - public Inventory getVault(UUID holder, int number) { - YamlConfiguration playerFile = getPlayerVaultFile(holder); - ConfigurationSection section = playerFile.getConfigurationSection("vault" + number); - int maxSize = VaultOperations.getMaxVaultSize(holder.toString()); - - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)); - - if (section == null) { - VaultHolder vaultHolder = new VaultHolder(number); - Inventory inv = Bukkit.createInventory(vaultHolder, maxSize, title); - vaultHolder.setInventory(inv); - return inv; - } else { - 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); - } - } - - /** - * 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(String holder, int number) { - File file = new File(directory, holder + ".yml"); - if (!file.exists()) { - return false; - } - - return getPlayerVaultFile(holder).contains("vault" + 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 String 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("vault" + 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())); - } - } - - String uuid = sender instanceof Player ? ((Player) sender).getUniqueId().toString() : holder; - PlayerVaults.getInstance().getOpenInventories().remove(new VaultViewInfo(holder, number).toString()); - } - - // Should only be run asynchronously - public void cachePlayerVaultFile(String holder) { - YamlConfiguration config = this.loadPlayerVaultFile(holder, false); - if (config != null) { - this.cachedVaultFiles.put(holder, config); - } - } - - public void removeCachedPlayerVaultFile(String holder) { - cachedVaultFiles.remove(holder); - } - - /** - * Use below method for getting it via String. - */ - @Deprecated - public YamlConfiguration getPlayerVaultFile(UUID holder) { - return getPlayerVaultFile(holder.toString()); - } - - /** - * 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) { - if (cachedVaultFiles.containsKey(holder)) { - return cachedVaultFiles.get(holder); - } - return loadPlayerVaultFile(holder); - } - - public YamlConfiguration loadPlayerVaultFile(String holder) { - return this.loadPlayerVaultFile(holder, true); - } - - public YamlConfiguration loadPlayerVaultFile(String uniqueId, boolean createIfNotFound) { - if (!this.directory.exists()) { - this.directory.mkdir(); - } - - File file = new File(this.directory, uniqueId + ".yml"); - if (!file.exists()) { - if (createIfNotFound) { - try { - file.createNewFile(); - } catch (IOException e) { - // Who cares? - } - } else { - return null; - } - } - - return YamlConfiguration.loadConfiguration(file); - } - - public void saveFileSync(final String 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 + ".yml"); - if (file.exists() && backups) { - file.renameTo(new File(backupsFolder, holder + ".yml")); - } - try { - yaml.save(file); - } catch (IOException e) { - PlayerVaults.getInstance().getLogger().log(Level.SEVERE, "Failed to save vault file for: " + holder, e); - } - } -} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java index 904dd0c..d1ee5de 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultManager.java @@ -19,7 +19,6 @@ package com.drtshock.playervaults.vaultmanagement; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; @@ -45,8 +44,10 @@ public class VaultManager { private static VaultManager instance; private final File directory = PlayerVaults.getInstance().getVaultData(); private final Map cachedVaultFiles = new ConcurrentHashMap<>(); + private final PlayerVaults plugin; - public VaultManager() { + public VaultManager(PlayerVaults plugin) { + this.plugin = plugin; instance = this; } @@ -69,7 +70,7 @@ public class VaultManager { public void saveVault(Inventory inventory, String target, int number) { YamlConfiguration yaml = getPlayerVaultFile(target, true); int size = VaultOperations.getMaxVaultSize(target); - String serialized = Base64Serialization.toBase64(inventory, size, target); + String serialized = CardboardBoxSerialization.toStorage(inventory, target); yaml.set(String.format(VAULTKEY, number), serialized); saveFileSync(target, yaml); } @@ -87,7 +88,7 @@ public class VaultManager { PlayerVaults.debug("Loading self vault for " + player.getName() + " (" + player.getUniqueId() + ')'); - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", player.getName()); + String title = PlayerVaults.getInstance().getVaultTitle(String.valueOf(number)); VaultViewInfo info = new VaultViewInfo(player.getUniqueId().toString(), number); if (PlayerVaults.getInstance().getOpenInventories().containsKey(info.toString())) { PlayerVaults.debug("Already open"); @@ -129,7 +130,7 @@ public class VaultManager { // Not a player } - String title = Lang.VAULT_TITLE.toString().replace("%number", String.valueOf(number)).replace("%p", holder); + String title = PlayerVaults.getInstance().getVaultTitle(String.valueOf(number)); VaultViewInfo info = new VaultViewInfo(name, number); Inventory inv; VaultHolder vaultHolder = new VaultHolder(number); @@ -161,23 +162,23 @@ public class VaultManager { Inventory inventory = Bukkit.createInventory(owner, size, title); String data = playerFile.getString(String.format(VAULTKEY, number)); - Inventory deserialized = Base64Serialization.fromBase64(data, ownerName); + ItemStack[] deserialized = CardboardBoxSerialization.fromStorage(data, ownerName); if (deserialized == null) { - PlayerVaults.debug("Loaded vault as null"); + PlayerVaults.debug("Loaded vault for " + ownerName + " as null"); return inventory; } // Check if deserialized has more used slots than the limit here. // Happens on change of permission or if people used the broken version. // In this case, players will lose items. - if (deserialized.getContents().length > size) { - for (ItemStack stack : deserialized.getContents()) { + if (deserialized.length > size) { + for (ItemStack stack : deserialized) { if (stack != null) { inventory.addItem(stack); } } } else { - inventory.setContents(deserialized.getContents()); + inventory.setContents(deserialized); } PlayerVaults.debug("Loaded vault"); @@ -194,7 +195,10 @@ public class VaultManager { public Inventory getVault(String holder, int number) { YamlConfiguration playerFile = getPlayerVaultFile(holder, true); String serialized = playerFile.getString(String.format(VAULTKEY, number)); - return Base64Serialization.fromBase64(serialized, holder); + ItemStack[] contents = CardboardBoxSerialization.fromStorage(serialized, holder); + Inventory inventory = Bukkit.createInventory(null, contents.length, holder + " vault " + number); + inventory.setContents(contents); + return inventory; } /** @@ -279,9 +283,9 @@ public class VaultManager { 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))); + this.plugin.getTL().deleteVault().title().with("vault", String.valueOf(number)).send(sender); } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.DELETE_OTHER_VAULT.toString().replace("%v", String.valueOf(number)).replaceAll("%p", player.getName())); + this.plugin.getTL().deleteOtherVault().title().with("vault", String.valueOf(number)).with("player", player.getName()).send(sender); } } diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java index 757df7d..d21badb 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/VaultOperations.java @@ -19,9 +19,7 @@ package com.drtshock.playervaults.vaultmanagement; import com.drtshock.playervaults.PlayerVaults; -import com.drtshock.playervaults.translations.Lang; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -60,7 +58,7 @@ public class VaultOperations { InventoryView view = player.getOpenInventory(); if (view.getTopInventory().getHolder() instanceof VaultHolder) { player.closeInventory(); - player.sendMessage(Lang.TITLE + Lang.LOCKED.toString()); + PlayerVaults.getInstance().getTL().locked().title().send(player); } } } @@ -111,7 +109,7 @@ public class VaultOperations { */ public static int getMaxVaultSize(OfflinePlayer player) { if (player == null || !player.isOnline()) { - return PlayerVaults.getInstance().getDefaultVaultSize(); + return 6 * 9; } for (int i = 6; i != 0; i--) { if (player.getPlayer().hasPermission("playervaults.size." + i)) { @@ -125,7 +123,7 @@ public class VaultOperations { * Open a player's own vault. * * @param player The player to open to. - * @param arg The vault number to open. + * @param arg The vault number to open. * @return Whether or not the player was allowed to open it. */ public static boolean openOwnVault(Player player, String arg) { @@ -150,7 +148,7 @@ public class VaultOperations { return false; } } catch (NumberFormatException nfe) { - player.sendMessage(Lang.TITLE.toString() + Lang.MUST_BE_NUMBER.toString()); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(player); return false; } @@ -174,15 +172,15 @@ public class VaultOperations { PlayerVaults.getInstance().getOpenInventories().put(info.toString(), inv); if (send) { - player.sendMessage(Lang.TITLE.toString() + Lang.OPEN_VAULT.toString().replace("%v", arg)); + PlayerVaults.getInstance().getTL().openVault().title().with("vault", arg).send(player); } return true; } else { - player.sendMessage(Lang.TITLE.toString() + Lang.INSUFFICIENT_FUNDS); + PlayerVaults.getInstance().getTL().insufficientFunds().title().send(player); return false; } } else { - player.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS); + PlayerVaults.getInstance().getTL().noPerms().title().send(player); } return false; } @@ -190,8 +188,8 @@ public class VaultOperations { /** * Open a player's own vault. If player is using a command, they'll need the required permission. * - * @param player The player to open to. - * @param arg The vault number to open. + * @param player The player to open to. + * @param arg The vault number to open. * @param isCommand - if player is opening via a command or not. * @return Whether or not the player was allowed to open it. */ @@ -199,16 +197,16 @@ public class VaultOperations { if (isCommand && player.hasPermission("playervaults.commands.use")) { return openOwnVault(player, arg); } - player.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS.toString()); + PlayerVaults.getInstance().getTL().noPerms().title().send(player); return false; } /** * Open another player's vault. * - * @param player The player to open to. + * @param player The player to open to. * @param vaultOwner The name of the vault owner. - * @param arg The vault number to open. + * @param arg The vault number to open. * @return Whether or not the player was allowed to open it. */ public static boolean openOtherVault(Player player, String vaultOwner, String arg) { @@ -230,11 +228,11 @@ public class VaultOperations { try { number = Integer.parseInt(arg); if (number < 1) { - player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(player); return false; } } catch (NumberFormatException nfe) { - player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(player); } Inventory inv = VaultManager.getInstance().loadOtherVault(vaultOwner, number, getMaxVaultSize(vaultOwner)); @@ -247,7 +245,7 @@ public class VaultOperations { } if (inv == null) { - player.sendMessage(Lang.TITLE.toString() + Lang.VAULT_DOES_NOT_EXIST.toString()); + PlayerVaults.getInstance().getTL().vaultDoesNotExist().title().send(player); } else { player.openInventory(inv); @@ -257,7 +255,7 @@ public class VaultOperations { return false; // inventory open event was cancelled. } if (send) { - player.sendMessage(Lang.TITLE.toString() + Lang.OPEN_OTHER_VAULT.toString().replace("%v", arg).replace("%p", name)); + PlayerVaults.getInstance().getTL().openOtherVault().title().with("vault", arg).with("player", name).send(player); } PlayerVaults.debug("opening other vault", time); @@ -276,7 +274,7 @@ public class VaultOperations { * Delete a player's own vault. * * @param player The player to delete. - * @param arg The vault number to delete. + * @param arg The vault number to delete. */ public static void deleteOwnVault(Player player, String arg) { if (isLocked()) { @@ -287,20 +285,20 @@ public class VaultOperations { try { number = Integer.parseInt(arg); if (number == 0) { - player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(player); return; } } catch (NumberFormatException nfe) { - player.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(player); } if (EconomyOperations.refundOnDelete(player, number)) { VaultManager.getInstance().deleteVault(player, player.getUniqueId().toString(), number); - player.sendMessage(Lang.TITLE.toString() + Lang.DELETE_VAULT.toString().replaceAll("%v", arg)); + PlayerVaults.getInstance().getTL().deleteVault().title().with("vault", arg).send(player); } } else { - player.sendMessage(Lang.TITLE.toString() + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(player); } } @@ -309,7 +307,7 @@ public class VaultOperations { * * @param sender The sender executing the deletion. * @param holder The user to whom the deleted vault belongs. - * @param arg The vault number to delete. + * @param arg The vault number to delete. */ public static void deleteOtherVault(CommandSender sender, String holder, String arg) { if (isLocked()) { @@ -321,20 +319,20 @@ public class VaultOperations { try { number = Integer.parseInt(arg); if (number == 0) { - sender.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(sender); return; } } catch (NumberFormatException nfe) { - sender.sendMessage(Lang.TITLE.toString() + ChatColor.RED + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(sender); } VaultManager.getInstance().deleteVault(sender, holder, number); - sender.sendMessage(Lang.TITLE.toString() + Lang.DELETE_OTHER_VAULT.toString().replaceAll("%v", arg).replaceAll("%p", holder)); + PlayerVaults.getInstance().getTL().deleteOtherVault().title().with("vault", arg).with("player", holder).send(sender); } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.MUST_BE_NUMBER); + PlayerVaults.getInstance().getTL().mustBeNumber().title().send(sender); } } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS); + PlayerVaults.getInstance().getTL().noPerms().title().send(sender); } } @@ -353,7 +351,7 @@ public class VaultOperations { VaultManager.getInstance().deleteAllVaults(holder); PlayerVaults.getInstance().getLogger().info(String.format("%s deleted ALL vaults belonging to %s", sender.getName(), holder)); } else { - sender.sendMessage(Lang.TITLE.toString() + Lang.NO_PERMS); + PlayerVaults.getInstance().getTL().noPerms().title().send(sender); } }