diff --git a/src/main/java/com/drtshock/playervaults/Conversion.java b/src/main/java/com/drtshock/playervaults/Conversion.java new file mode 100644 index 0000000..b0e4919 --- /dev/null +++ b/src/main/java/com/drtshock/playervaults/Conversion.java @@ -0,0 +1,235 @@ +package com.drtshock.playervaults; + +import com.drtshock.playervaults.vaultmanagement.CardboardBoxSerialization; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.io.BukkitObjectInputStream; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Logger; + +class Conversion { + /** + * Fancy JSON serialization mostly by evilmidget38. + * + * @author evilmidget38, gomeow + */ + @SuppressWarnings("unchecked") + static class OldestSerialization { + private static Map toMap(JSONObject object) { + Map map = new HashMap<>(); + + // Weird case of bad meta causing null map to be passed here. + if (object == null) { + return map; + } + + for (Object key : object.keySet()) { + map.put(key.toString(), fromJson(object.get(key))); + } + return map; + } + + private static Object fromJson(Object json) { + if (json == null) { + return null; + } else if (json instanceof JSONObject) { + return toMap((JSONObject) json); + } else if (json instanceof JSONArray) { + return toList((JSONArray) json); + } else { + return json; + } + } + + private static List toList(JSONArray array) { + List list = new ArrayList<>(); + for (Object value : array) { + list.add(fromJson(value)); + } + return list; + } + + private static ItemStack[] getItems(List stringItems) { + List contents = new ArrayList<>(); + for (String piece : stringItems) { + if (piece.equalsIgnoreCase("null")) { + contents.add(null); + } else { + ItemStack item = (ItemStack) deserialize(toMap((JSONObject) JSONValue.parse(piece))); + contents.add(item); + } + } + ItemStack[] items = new ItemStack[contents.size()]; + for (int x = 0; x < contents.size(); x++) { + items[x] = contents.get(x); + } + return items; + } + + private static Map recreateMap(Map original) { + return new HashMap<>(original); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private static Object deserialize(Map map) { + for (Entry entry : map.entrySet()) { + if (entry.getValue() instanceof Map) { + entry.setValue(deserialize((Map) entry.getValue())); + } else if (entry.getValue() instanceof Iterable) { + entry.setValue(convertIterable((Iterable) entry.getValue())); + } else if (entry.getValue() instanceof Number) { + entry.setValue(convertNumber((Number) entry.getValue())); + } + } + return map.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY) ? ConfigurationSerialization.deserializeObject(map) : map; + } + + private static List convertIterable(Iterable iterable) { + List newList = new ArrayList<>(); + for (Object object : iterable) { + if (object instanceof Map) { + object = deserialize((Map) object); + } else if (object instanceof List) { + object = convertIterable((Iterable) object); + } else if (object instanceof Number) { + object = convertNumber((Number) object); + } + newList.add(object); + } + return newList; + } + + private static Number convertNumber(Number number) { + if (number instanceof Long) { + Long longObj = (Long) number; + if (longObj == longObj.intValue()) { + return longObj.intValue(); + } + } + return number; + } + } + + static void convert(PlayerVaults plugin) { + Logger logger = plugin.getLogger(); + + File newDir = plugin.getVaultData(); + File oldVaults = plugin.getDataFolder().toPath().resolve("base64vaults").toFile(); + File reallyOldVaults = plugin.getDataFolder().toPath().resolve("uuidvaults").toFile(); + + if (newDir.exists()) { + plugin.getDataFolder().toPath().resolve("oldVaultsData").toFile().mkdirs(); + if (oldVaults.exists()) { + try { + Files.move(oldVaults.toPath(), plugin.getDataFolder().toPath().resolve("oldVaultsData").resolve("base64vaults")); + } catch (IOException e) { + plugin.getLogger().warning("Failed to move old vaults dir: " + e.getMessage()); + } + } + if (reallyOldVaults.exists()) { + try { + Files.move(reallyOldVaults.toPath(), plugin.getDataFolder().toPath().resolve("oldVaultsData").resolve("uuidvaults")); + } catch (IOException e) { + plugin.getLogger().warning("Failed to move old vaults dir: " + e.getMessage()); + } + } + return; + } + + newDir.mkdirs(); + + File oldDir; + boolean recent; + if (oldVaults.exists()) { + logger.info("********** Starting data storage conversion **********"); + logger.info("This might take a while."); + logger.info(oldVaults.toString() + " will remain as a backup."); + recent = true; + oldDir = oldVaults; + } else if (reallyOldVaults.exists()) { + logger.info("********** Starting data storage conversion **********"); + logger.info("This might take a while."); + logger.info(reallyOldVaults.toString() + " will remain as a backup."); + recent = false; + oldDir = reallyOldVaults; + } else { + logger.info("No old vaults found to convert to new format. :)"); + return; + } + + int players = 0; + int vaults = 0; + int failed = 0; + for (File file : oldDir.listFiles()) { + if (file.isDirectory() || !file.getName().endsWith(".yml")) { + continue; // backups folder. + } + + FileConfiguration uuidFile = YamlConfiguration.loadConfiguration(file); + String stringUUID = file.getName().replace(".yml", ""); + + for (String key : uuidFile.getKeys(false)) { + if (!key.startsWith("vault")) { + continue; + } + + int vaultNumber = Integer.parseInt(key.replace("vault", "")); + + try { + + ItemStack[] contents; + if (recent) { + String data = uuidFile.getString(key); + ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(data)); + BukkitObjectInputStream dataInput = new BukkitObjectInputStream(inputStream); + contents = new ItemStack[dataInput.readInt()]; + // Read the serialized inventory + for (int i = 0; i < contents.length; i++) { + contents[i] = (ItemStack) dataInput.readObject(); + } + dataInput.close(); + } else { + ConfigurationSection section = uuidFile.getConfigurationSection(key); + List data = new ArrayList<>(); + for (String s : section.getKeys(false)) { + String value = section.getString(s); + data.add(value); + } + contents = OldestSerialization.getItems(data); + } + String newData = Base64Coder.encodeLines(CardboardBoxSerialization.writeInventory(contents)); + uuidFile.set(key, newData); + vaults++; + } catch (Exception e) { + logger.severe("Failed to parse vault " + vaultNumber + " for " + stringUUID); + 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 new storage. %d failed to convert", vaults, players, failed)); + } +} diff --git a/src/main/java/com/drtshock/playervaults/PlayerVaults.java b/src/main/java/com/drtshock/playervaults/PlayerVaults.java index ec05337..16ba66c 100644 --- a/src/main/java/com/drtshock/playervaults/PlayerVaults.java +++ b/src/main/java/com/drtshock/playervaults/PlayerVaults.java @@ -29,7 +29,6 @@ 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.vaultmanagement.VaultManager; import com.drtshock.playervaults.vaultmanagement.VaultViewInfo; @@ -122,11 +121,10 @@ public class PlayerVaults extends JavaPlugin { DEBUG = getConf().isDebug(); debug("config", time); time = System.currentTimeMillis(); - uuidData = new File(this.getDataFolder(), "uuidvaults"); vaultData = new File(this.getDataFolder(), "newvaults"); + Conversion.convert(this); new VaultManager(this); - getServer().getScheduler().runTask(this, new Base64Conversion()); - debug("base64 conversion", time); + debug("conversion", time); time = System.currentTimeMillis(); debug("uuidvaultmanager", time); time = System.currentTimeMillis(); diff --git a/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java b/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java deleted file mode 100644 index 87326f2..0000000 --- a/src/main/java/com/drtshock/playervaults/tasks/Base64Conversion.java +++ /dev/null @@ -1,130 +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.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 java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.UUID; -import java.util.logging.Logger; - -/** - * Class to convert vaults by Bukkit serialization to Base64. - */ -public final class Base64Conversion implements Runnable { - - @Override - public void run() { - Logger logger = PlayerVaults.getInstance().getLogger(); - - File newDir = PlayerVaults.getInstance().getVaultData(); - 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(); - - if (!oldVaults.exists()) { - logger.info("No base64vaults found to convert to new format."); - return; - } - - - logger.info("********** Starting conversion from Base64 for PlayerVaults **********"); - logger.info("This might take awhile."); - logger.info(oldVaults.toString() + " will remain as a backup."); - - int players = 0; - int vaults = 0; - int failed = 0; - for (File file : oldVaults.listFiles()) { - if (file.isDirectory()) { - continue; // backups folder. - } - - FileConfiguration uuidFile = YamlConfiguration.loadConfiguration(file); - String stringUUID = file.getName().replace(".yml", ""); - UUID holderUUID; - try { - holderUUID = UUID.fromString(stringUUID); - } catch (Exception e) { - logger.warning(String.format("Failed to parse uuid for %s. Trying to convert", stringUUID)); - OfflinePlayer player = Bukkit.getOfflinePlayer(stringUUID); - if (player != null) { - logger.info(String.format("Successfully got UUID for %s", stringUUID)); - holderUUID = player.getUniqueId(); - } else { - logger.warning(String.format("Failed to convert name to uuid for %s", stringUUID)); - continue; - } - } - - for (String key : uuidFile.getKeys(false)) { - if (!key.startsWith("vault")) { - continue; - } - - int vaultNumber = Integer.parseInt(key.replace("vault", "")); - - try { - 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 new storage. %d failed to convert", vaults, players, failed)); - } -} diff --git a/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java index 1dcb7ff..a06f459 100644 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java +++ b/src/main/java/com/drtshock/playervaults/vaultmanagement/CardboardBoxSerialization.java @@ -40,7 +40,7 @@ public class CardboardBoxSerialization { } } - private static byte[] writeInventory(ItemStack[] contents) throws IOException { + public static byte[] writeInventory(ItemStack[] contents) throws IOException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(bytes); out.writeInt(contents.length); @@ -64,21 +64,4 @@ public class CardboardBoxSerialization { } 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/Serialization.java b/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java deleted file mode 100644 index c66b96a..0000000 --- a/src/main/java/com/drtshock/playervaults/vaultmanagement/Serialization.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * PlayerVaultsX - * Copyright (C) 2013 Trent Hensler, evilmidget38, gomeow - * - * 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 org.bukkit.Bukkit; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.bukkit.configuration.serialization.ConfigurationSerialization; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; -import org.json.simple.JSONValue; - -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; - -/** - * Fancy JSON serialization mostly by evilmidget38. - * - * @author evilmidget38, gomeow - */ -@SuppressWarnings("unchecked") -public class Serialization { - - @Deprecated - public static Map toMap(JSONObject object) { - Map map = new HashMap<>(); - - // Weird case of bad meta causing null map to be passed here. - if (object == null) { - return map; - } - - for (Object key : object.keySet()) { - map.put(key.toString(), fromJson(object.get(key))); - } - return map; - } - - @Deprecated - private static Object fromJson(Object json) { - if (json == null) { - return null; - } else if (json instanceof JSONObject) { - return toMap((JSONObject) json); - } else if (json instanceof JSONArray) { - return toList((JSONArray) json); - } else { - return json; - } - } - - @Deprecated - public static List toList(JSONArray array) { - List list = new ArrayList<>(); - for (Object value : array) { - list.add(fromJson(value)); - } - return list; - } - - @Deprecated - public static List toString(Inventory inv) { - List result = new ArrayList<>(); - List items = new ArrayList<>(); - Collections.addAll(items, inv.getContents()); - for (ConfigurationSerializable cs : items) { - if (cs == null) { - result.add("null"); - } else { - result.add(new JSONObject(serialize(cs)).toString()); - } - } - return result; - } - - @Deprecated - public static Inventory toInventory(List stringItems, int number, int size, String title) { - VaultHolder holder = new VaultHolder(number); - Inventory inv = Bukkit.createInventory(holder, size, title); - holder.setInventory(inv); - List contents = new ArrayList<>(); - for (String piece : stringItems) { - if (piece.equalsIgnoreCase("null")) { - contents.add(null); - } else { - ItemStack item = (ItemStack) deserialize(toMap((JSONObject) JSONValue.parse(piece))); - contents.add(item); - } - } - ItemStack[] items = new ItemStack[contents.size()]; - for (int x = 0; x < contents.size(); x++) { - items[x] = contents.get(x); - } - inv.setContents(items); - return inv; - } - - @Deprecated - public static Map serialize(ConfigurationSerializable cs) { - Map returnVal = handleSerialization(cs.serialize()); - returnVal.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(cs.getClass())); - return returnVal; - } - - @Deprecated - private static Map handleSerialization(Map map) { - Map serialized = recreateMap(map); - for (Entry entry : serialized.entrySet()) { - if (entry.getValue() instanceof ConfigurationSerializable) { - entry.setValue(serialize((ConfigurationSerializable) entry.getValue())); - } else if (entry.getValue() instanceof Iterable) { - List newList = new ArrayList<>(); - for (Object object : ((Iterable) entry.getValue())) { - if (object instanceof ConfigurationSerializable) { - object = serialize((ConfigurationSerializable) object); - } - newList.add(object); - } - entry.setValue(newList); - } else if (entry.getValue() instanceof Map) { - // unchecked cast here. If you're serializing to a non-standard Map you deserve ClassCastExceptions - entry.setValue(handleSerialization((Map) entry.getValue())); - } - } - return serialized; - } - - @Deprecated - public static Map recreateMap(Map original) { - return new HashMap<>(original); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public static Object deserialize(Map map) { - for (Entry entry : map.entrySet()) { - if (entry.getValue() instanceof Map) { - entry.setValue(deserialize((Map) entry.getValue())); - } else if (entry.getValue() instanceof Iterable) { - entry.setValue(convertIterable((Iterable) entry.getValue())); - } else if (entry.getValue() instanceof Number) { - entry.setValue(convertNumber((Number) entry.getValue())); - } - } - return map.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY) ? ConfigurationSerialization.deserializeObject(map) : map; - } - - private static List convertIterable(Iterable iterable) { - List newList = new ArrayList<>(); - for (Object object : iterable) { - if (object instanceof Map) { - object = deserialize((Map) object); - } else if (object instanceof List) { - object = convertIterable((Iterable) object); - } else if (object instanceof Number) { - object = convertNumber((Number) object); - } - newList.add(object); - } - return newList; - } - - private static Number convertNumber(Number number) { - if (number instanceof Long) { - Long longObj = (Long) number; - if (longObj == longObj.intValue()) { - return longObj.intValue(); - } - } - return number; - } -} \ No newline at end of file