diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java index b19c1cb4d..ff4ed6c11 100644 --- a/src/main/java/fr/xephi/authme/AuthMe.java +++ b/src/main/java/fr/xephi/authme/AuthMe.java @@ -40,7 +40,7 @@ import fr.xephi.authme.api.API; import fr.xephi.authme.api.NewAPI; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; -import fr.xephi.authme.cache.backup.FileCache; +import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.commands.AdminCommand; @@ -88,7 +88,7 @@ public class AuthMe extends JavaPlugin { public static AuthMe authme; public Permission permission; private Utils utils = Utils.getInstance(); - private FileCache playerBackup = new FileCache(this); + private JsonCache playerBackup = new JsonCache(this); public CitizensCommunicator citizens; public boolean isCitizensActive = false; public SendMailSSL mail = null; diff --git a/src/main/java/fr/xephi/authme/cache/backup/FileCache.java b/src/main/java/fr/xephi/authme/cache/backup/FileCache.java deleted file mode 100644 index 3e119ba6d..000000000 --- a/src/main/java/fr/xephi/authme/cache/backup/FileCache.java +++ /dev/null @@ -1,277 +0,0 @@ -package fr.xephi.authme.cache.backup; - -import com.google.common.io.BaseEncoding; -import fr.xephi.authme.AuthMe; -import fr.xephi.authme.ConsoleLogger; -import fr.xephi.authme.Utils; -import fr.xephi.authme.api.API; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; -import org.bukkit.util.io.BukkitObjectInputStream; -import org.bukkit.util.io.BukkitObjectOutputStream; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.Scanner; - -public class FileCache { - - private final File cacheDir; - private AuthMe plugin; - - public FileCache(AuthMe plugin) { - this.plugin = plugin; - cacheDir = new File(plugin.getDataFolder() + File.separator + "cache"); - if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) { - ConsoleLogger.showError("Failed to create cache directory."); - } - } - - public void createCache(Player player, DataFileCache playerData, - String group, boolean operator, boolean flying) { - if (player == null) { - return; - } - - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - - File playerDir = new File(cacheDir, path); - if (!playerDir.exists() && !playerDir.isDirectory() && !playerDir.mkdir()) { - return; - } - - File datafile = new File(playerDir, "playerdatas.cache"); - if (datafile.exists()) { - return; - } - - FileWriter writer; - try { - datafile.createNewFile(); - writer = new FileWriter(datafile); - writer.write(group + API.newline); - writer.write(String.valueOf(operator) + API.newline); - writer.write(String.valueOf(flying) + API.newline); - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - - BaseEncoding base64 = BaseEncoding.base64(); - - File invDir = new File(playerDir, "inventory"); - if (!invDir.isDirectory() && !invDir.mkdir()) - return; - - ItemStack[] inv = playerData.getInventory(); - for (int i = 0; i < inv.length; i++) { - ItemStack item = inv[i]; - if (item == null) { - item = new ItemStack(Material.AIR); - } - if (item.getType() == Material.SKULL_ITEM) { - SkullMeta meta = (SkullMeta) item.getItemMeta(); - if (meta.hasOwner() && (meta.getOwner() == null || meta.getOwner().isEmpty())) { - item.setItemMeta(plugin.getServer().getItemFactory().getItemMeta(Material.SKULL_ITEM)); - } - } - - try { - File cacheFile = new File(invDir, i + ".cache"); - if (!cacheFile.isFile() && !cacheFile.createNewFile()) { - continue; - } - writer = new FileWriter(cacheFile); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BukkitObjectOutputStream objectOut = new BukkitObjectOutputStream(baos); - objectOut.writeObject(item); - objectOut.close(); - writer.write(base64.encode(baos.toByteArray())); - writer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - File armourDir = new File(cacheDir, path + File.separator + "armours"); - if (!armourDir.isDirectory() && !armourDir.mkdir()) - return; - - ItemStack[] armors = playerData.getArmour(); - for (int i = 0; i < armors.length; i++) { - ItemStack item = armors[i]; - if (item == null) { - item = new ItemStack(Material.AIR); - } - if (item.getType() == Material.SKULL_ITEM) { - SkullMeta meta = (SkullMeta) item.getItemMeta(); - if (meta.hasOwner() && (meta.getOwner() == null || meta.getOwner().isEmpty())) { - item.setItemMeta(plugin.getServer().getItemFactory().getItemMeta(Material.SKULL_ITEM)); - } - } - - try { - File cacheFile = new File(armourDir, i + ".cache"); - if (!cacheFile.isFile() && !cacheFile.createNewFile()) { - continue; - } - writer = new FileWriter(cacheFile); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BukkitObjectOutputStream objectOut = new BukkitObjectOutputStream(baos); - objectOut.writeObject(item); - objectOut.close(); - writer.write(base64.encode(baos.toByteArray())); - writer.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - } - - public DataFileCache readCache(Player player) { - if (player == null) { - return null; - } - - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - - File playerDir = new File(cacheDir, path); - if (!playerDir.exists() && !playerDir.isDirectory()) { - return null; - } - - try { - File datafile = new File(playerDir, "playerdatas.cache"); - if (!datafile.exists() || !datafile.isFile()) { - return null; - } - ItemStack[] inv = new ItemStack[36]; - ItemStack[] armours = new ItemStack[4]; - String group = null; - boolean op = false; - boolean flying = false; - - Scanner reader; - try { - reader = new Scanner(datafile); - int count = 1; - while (reader.hasNextLine()) { - String line = reader.nextLine(); - switch (count) { - case 1: - group = line; - break; - case 2: - op = Boolean.parseBoolean(line); - break; - case 3: - flying = Boolean.parseBoolean(line); - break; - default: - break; - } - count++; - } - reader.close(); - } catch (Exception e) { - e.printStackTrace(); - } - - BaseEncoding base64 = BaseEncoding.base64(); - - File invDir = new File(playerDir, "inventory"); - for (int i = 0; i < inv.length; i++) { - byte[] bytes = Files.readAllBytes(Paths.get(invDir.getPath(), i + ".cache")); - String encodedItem = new String(bytes); - bytes = base64.decode(encodedItem); - ByteArrayInputStream baos = new ByteArrayInputStream(bytes); - BukkitObjectInputStream objectIn = new BukkitObjectInputStream(baos); - ItemStack item = (ItemStack) objectIn.readObject(); - objectIn.close(); - if (item == null) { - inv[i] = new ItemStack(Material.AIR); - } else { - inv[i] = item; - } - } - - File armourDir = new File(playerDir, "armours"); - for (int i = 0; i < armours.length; i++) { - byte[] bytes = Files.readAllBytes(Paths.get(armourDir.getPath(), i + ".cache")); - String encodedItem = new String(bytes); - bytes = base64.decode(encodedItem); - ByteArrayInputStream baos = new ByteArrayInputStream(bytes); - BukkitObjectInputStream objectIn = new BukkitObjectInputStream(baos); - ItemStack item = (ItemStack) objectIn.readObject(); - objectIn.close(); - if (item == null) { - armours[i] = new ItemStack(Material.AIR); - } else { - armours[i] = item; - } - } - - return new DataFileCache(inv, armours, group, op, flying); - - } catch (Exception e) { - e.printStackTrace(); - ConsoleLogger.showError("Error while reading file for " + player.getName() + ", some wipe inventory incoming..."); - return null; - } - } - - public void removeCache(Player player) { - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - try { - File file = new File(cacheDir, path); - if (file.list() != null) { - Utils.purgeDirectory(file); - if (!file.delete()) { - ConsoleLogger.showError("Failed to remove" + player.getName() + "cache."); - } - } else { - file = new File(cacheDir, player.getName().toLowerCase() + ".cache"); - if (file.isFile() && !file.delete()) { - ConsoleLogger.showError("Failed to remove" + player.getName() + "cache."); - } - } - } catch (Exception e) { - ConsoleLogger.showError("Failed to remove" + player.getName() + "cache :/"); - } - } - - public boolean doesCacheExist(Player player) { - String path; - try { - path = player.getUniqueId().toString(); - } catch (Exception | Error e) { - path = player.getName().toLowerCase(); - } - File file = new File(cacheDir, path + File.separator + "playerdatas.cache"); - if (!file.exists()) { - file = new File(cacheDir, player.getName().toLowerCase() + ".cache"); - } - - return file.exists(); - } - -} diff --git a/src/main/java/fr/xephi/authme/cache/backup/JsonCache.java b/src/main/java/fr/xephi/authme/cache/backup/JsonCache.java new file mode 100644 index 000000000..25db2afbf --- /dev/null +++ b/src/main/java/fr/xephi/authme/cache/backup/JsonCache.java @@ -0,0 +1,206 @@ +package fr.xephi.authme.cache.backup; + +import com.google.common.io.BaseEncoding; +import com.google.gson.*; +import fr.xephi.authme.AuthMe; +import fr.xephi.authme.ConsoleLogger; +import fr.xephi.authme.Utils; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.bukkit.util.io.BukkitObjectOutputStream; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class JsonCache { + + private final Gson gson; + private final AuthMe plugin; + private final File cacheDir; + + public JsonCache(AuthMe plugin) { + this.plugin = plugin; + cacheDir = new File(plugin.getDataFolder() + File.separator + "cache"); + if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) { + ConsoleLogger.showError("Failed to create cache directory."); + } + gson = new GsonBuilder() + .registerTypeAdapter(DataFileCache.class, new PlayerDataSerializer()) + .registerTypeAdapter(DataFileCache.class, new PlayerDataDeserializer()) + .setPrettyPrinting() + .create(); + } + + public void createCache(Player player, DataFileCache playerData) { + if (player == null) { + return; + } + + String path; + try { + path = player.getUniqueId().toString(); + } catch (Exception | Error e) { + path = player.getName().toLowerCase(); + } + + File file = new File(cacheDir, path + File.separator + "cache.json"); + if (file.exists()) { + return; + } + if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { + return; + } + + try { + String data = gson.toJson(playerData); + Files.write(Paths.get(file.getPath()), data.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public DataFileCache readCache(Player player) { + String path; + try { + path = player.getUniqueId().toString(); + } catch (Exception | Error e) { + path = player.getName().toLowerCase(); + } + + File file = new File(cacheDir, path + File.separator + "cache.json"); + try { + byte[] bytes = Files.readAllBytes(Paths.get(file.getPath())); + String str = new String(bytes); + return gson.fromJson(str, DataFileCache.class); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private class PlayerDataSerializer implements JsonSerializer { + @Override + public JsonElement serialize(DataFileCache dataFileCache, Type type, JsonSerializationContext jsonSerializationContext) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("group", dataFileCache.getGroup()); + jsonObject.addProperty("operator", dataFileCache.getOperator()); + jsonObject.addProperty("flying", dataFileCache.isFlying()); + + JsonArray arr; + ItemStack[] contents; + + // inventory + contents = dataFileCache.getInventory(); + arr = new JsonArray(); + putItems(contents, arr); + + // armour + contents = dataFileCache.getArmour(); + arr = new JsonArray(); + putItems(contents, arr); + jsonObject.add("armour", arr); + + return jsonObject; + } + + private void putItems(ItemStack[] contents, JsonArray target) { + for (ItemStack item : contents) { + if (item == null) { + item = new ItemStack(Material.AIR); + } + JsonObject val = new JsonObject(); + if (item.getType() == Material.SKULL_ITEM) { + SkullMeta meta = (SkullMeta) item.getItemMeta(); + if (meta.hasOwner() && (meta.getOwner() == null || meta.getOwner().isEmpty())) { + item.setItemMeta(plugin.getServer().getItemFactory().getItemMeta(Material.SKULL_ITEM)); + } + } + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + BukkitObjectOutputStream objectOut = new BukkitObjectOutputStream(baos); + objectOut.writeObject(item); + objectOut.close(); + val.addProperty("item", BaseEncoding.base64().encode(baos.toByteArray())); + } catch (IOException e) { + e.printStackTrace(); + continue; + } + target.add(val); + } + } + } + + private class PlayerDataDeserializer implements JsonDeserializer { + @Override + public DataFileCache deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + JsonObject jsonObject = jsonElement.getAsJsonObject(); + String group = jsonObject.get("group").getAsString(); + boolean operator = jsonObject.get("operator").getAsBoolean(); + boolean flying = jsonObject.get("flying").getAsBoolean(); + + JsonArray arr; + + arr = jsonObject.get("inventory").getAsJsonArray(); + ItemStack[] inv = getItems(arr); + + arr = jsonObject.get("armour").getAsJsonArray(); + ItemStack[] armour = getItems(arr); + + return new DataFileCache(inv, armour, group, operator, flying); + } + + private ItemStack[] getItems(JsonArray arr) { + ItemStack[] contents = new ItemStack[arr.size()]; + for (int i = 0; i < arr.size(); i++) { + JsonObject item = arr.get(i).getAsJsonObject(); + String encoded = item.get("item").getAsString(); + byte[] decoded = BaseEncoding.base64().decode(encoded); + try { + ByteArrayInputStream baos = new ByteArrayInputStream(decoded); + BukkitObjectInputStream objectIn = new BukkitObjectInputStream(baos); + contents[i] = (ItemStack) objectIn.readObject(); + objectIn.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return contents; + } + } + + public void removeCache(Player player) { + String path; + try { + path = player.getUniqueId().toString(); + } catch (Exception | Error e) { + path = player.getName().toLowerCase(); + } + File file = new File(cacheDir, path + File.separator + "cache.json"); + if (file.exists()) { + Utils.purgeDirectory(file); + if (!file.delete()) { + ConsoleLogger.showError("Failed to remove" + player.getName() + "cache."); + } + } + } + + public boolean doesCacheExist(Player player) { + String path; + try { + path = player.getUniqueId().toString(); + } catch (Exception | Error e) { + path = player.getName().toLowerCase(); + } + File file = new File(cacheDir, path + File.separator + "cache.json"); + return file.exists(); + } + +} diff --git a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java index 6f7450244..b158a8ccf 100644 --- a/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java +++ b/src/main/java/fr/xephi/authme/cache/limbo/LimboCache.java @@ -3,7 +3,7 @@ package fr.xephi.authme.cache.limbo; import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.cache.backup.DataFileCache; -import fr.xephi.authme.cache.backup.FileCache; +import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.events.ResetInventoryEvent; import fr.xephi.authme.events.StoreInventoryEvent; import fr.xephi.authme.settings.Settings; @@ -19,13 +19,13 @@ public class LimboCache { private volatile static LimboCache singleton = null; public ConcurrentHashMap cache; - private FileCache playerData; + private JsonCache playerData; public AuthMe plugin; private LimboCache(AuthMe plugin) { this.plugin = plugin; this.cache = new ConcurrentHashMap(); - this.playerData = new FileCache(plugin); + this.playerData = new JsonCache(plugin); } public void addLimboPlayer(Player player) { diff --git a/src/main/java/fr/xephi/authme/commands/UnregisterCommand.java b/src/main/java/fr/xephi/authme/commands/UnregisterCommand.java index 1361656d6..57e653039 100644 --- a/src/main/java/fr/xephi/authme/commands/UnregisterCommand.java +++ b/src/main/java/fr/xephi/authme/commands/UnregisterCommand.java @@ -18,7 +18,7 @@ import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.Utils; import fr.xephi.authme.Utils.groupType; import fr.xephi.authme.cache.auth.PlayerCache; -import fr.xephi.authme.cache.backup.FileCache; +import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.events.SpawnTeleportEvent; import fr.xephi.authme.security.PasswordSecurity; @@ -31,11 +31,11 @@ public class UnregisterCommand implements CommandExecutor { private Messages m = Messages.getInstance(); public AuthMe plugin; - private FileCache playerCache; + private JsonCache playerCache; public UnregisterCommand(AuthMe plugin) { this.plugin = plugin; - this.playerCache = new FileCache(plugin); + this.playerCache = new JsonCache(plugin); } @Override diff --git a/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java b/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java index 66911d187..e8a78806c 100644 --- a/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java +++ b/src/main/java/fr/xephi/authme/events/StoreInventoryEvent.java @@ -1,7 +1,7 @@ package fr.xephi.authme.events; import fr.xephi.authme.cache.backup.DataFileCache; -import fr.xephi.authme.cache.backup.FileCache; +import fr.xephi.authme.cache.backup.JsonCache; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -22,9 +22,9 @@ public class StoreInventoryEvent extends CustomEvent { this.armor = player.getInventory().getArmorContents(); } - public StoreInventoryEvent(Player player, FileCache fileCache) { + public StoreInventoryEvent(Player player, JsonCache jsonCache) { this.player = player; - DataFileCache cache = fileCache.readCache(player); + DataFileCache cache = jsonCache.readCache(player); if (cache != null) { this.inventory = cache.getInventory(); this.armor = cache.getArmour(); diff --git a/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java index 3a3e8e1f3..c0cd93d72 100644 --- a/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java +++ b/src/main/java/fr/xephi/authme/process/join/AsyncronousJoin.java @@ -19,7 +19,7 @@ import fr.xephi.authme.Utils.groupType; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.backup.DataFileCache; -import fr.xephi.authme.cache.backup.FileCache; +import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.datasource.DataSource; @@ -42,13 +42,13 @@ public class AsyncronousJoin { protected String name; private Utils utils = Utils.getInstance(); private Messages m = Messages.getInstance(); - private FileCache playerBackup; + private JsonCache playerBackup; public AsyncronousJoin(Player player, AuthMe plugin, DataSource database) { this.player = player; this.plugin = plugin; this.database = database; - this.playerBackup = new FileCache(plugin); + this.playerBackup = new JsonCache(plugin); this.name = player.getName().toLowerCase(); } diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java index 276a8c23b..acb1f832e 100644 --- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java +++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java @@ -11,7 +11,7 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.Utils; import fr.xephi.authme.Utils.groupType; import fr.xephi.authme.cache.auth.PlayerAuth; -import fr.xephi.authme.cache.backup.FileCache; +import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.datasource.DataSource; @@ -31,7 +31,7 @@ public class ProcessSyncronousPlayerLogin implements Runnable { private AuthMe plugin; private DataSource database; private PluginManager pm; - private FileCache playerCache; + private JsonCache playerCache; public ProcessSyncronousPlayerLogin(Player player, AuthMe plugin, DataSource data) { @@ -42,7 +42,7 @@ public class ProcessSyncronousPlayerLogin implements Runnable { this.name = player.getName().toLowerCase(); this.limbo = LimboCache.getInstance().getLimboPlayer(name); this.auth = database.getAuth(name); - this.playerCache = new FileCache(plugin); + this.playerCache = new JsonCache(plugin); } public LimboPlayer getLimbo() { diff --git a/src/main/java/fr/xephi/authme/process/logout/AsyncronousLogout.java b/src/main/java/fr/xephi/authme/process/logout/AsyncronousLogout.java index 366e72d4c..a665a229d 100644 --- a/src/main/java/fr/xephi/authme/process/logout/AsyncronousLogout.java +++ b/src/main/java/fr/xephi/authme/process/logout/AsyncronousLogout.java @@ -10,7 +10,7 @@ import fr.xephi.authme.Utils.groupType; import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.backup.DataFileCache; -import fr.xephi.authme.cache.backup.FileCache; +import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.events.AuthMeTeleportEvent; @@ -26,7 +26,7 @@ public class AsyncronousLogout { protected boolean canLogout = true; private Messages m = Messages.getInstance(); private Utils utils = Utils.getInstance(); - private FileCache playerBackup; + private JsonCache playerBackup; public AsyncronousLogout(Player player, AuthMe plugin, DataSource database) { @@ -34,7 +34,7 @@ public class AsyncronousLogout { this.plugin = plugin; this.database = database; this.name = player.getName().toLowerCase(); - this.playerBackup = new FileCache(plugin); + this.playerBackup = new JsonCache(plugin); } private void preLogout() {