diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/StructureCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/StructureCommand.java index f0ae346f..25ef4c90 100644 --- a/src/main/java/com/songoda/skyblock/command/commands/admin/StructureCommand.java +++ b/src/main/java/com/songoda/skyblock/command/commands/admin/StructureCommand.java @@ -1,14 +1,21 @@ package com.songoda.skyblock.command.commands.admin; +import com.google.gson.Gson; import com.songoda.skyblock.command.SubCommand; import com.songoda.skyblock.config.FileManager.Config; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.playerdata.PlayerData; import com.songoda.skyblock.sound.SoundManager; import com.songoda.skyblock.utils.ChatComponent; +import com.songoda.skyblock.utils.Compression; +import com.songoda.skyblock.utils.structure.Storage; +import com.songoda.skyblock.utils.structure.Structure; import com.songoda.skyblock.utils.structure.StructureUtil; import com.songoda.skyblock.utils.version.Sounds; import com.songoda.skyblock.utils.world.LocationUtil; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.Base64; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; @@ -19,7 +26,6 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import java.io.File; import java.util.logging.Level; public class StructureCommand extends SubCommand { @@ -82,6 +88,22 @@ public class StructureCommand extends SubCommand { ChatColor.translateAlternateColorCodes('&', configLoad.getString( "Command.Island.Admin.Structure.Save.Info.Message"))) .create())).getTextComponent()); + player.spigot() + .sendMessage( + new ChatComponent( + prefix.replace("%info", + ChatColor.translateAlternateColorCodes('&', configLoad.getString( + "Command.Island.Admin.Structure.Convert.Info.Message"))) + + "/island admin structure convert" + + suffix.replace("%info", ChatColor.translateAlternateColorCodes( + '&', + configLoad.getString( + "Command.Island.Admin.Structure.Save.Convert.Message"))), + false, null, null, + new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder( + ChatColor.translateAlternateColorCodes('&', configLoad.getString( + "Command.Island.Admin.Structure.Convert.Info.Message"))) + .create())).getTextComponent()); } else { messageManager.sendMessage(player, helpLines); } @@ -176,6 +198,49 @@ public class StructureCommand extends SubCommand { soundManager.playSound(player, Sounds.ANVIL_LAND.bukkitSound(), 1.0F, 1.0F); } + } else if (args[0].equalsIgnoreCase("convert")) { + if (args.length == 2) { + File structureFile = new File(new File(skyblock.getDataFolder().toString() + "/structures"), args[1]); + if (!structureFile.exists()) { + messageManager.sendMessage(player, + configLoad.getString("Command.Island.Admin.Structure.Convert.Invalid.Message") + .replace("%name", args[1])); + soundManager.playSound(player, Sounds.ANVIL_LAND.bukkitSound(), 1.0F, 1.0F); + return; + } + byte[] content = new byte[(int) structureFile.length()]; + try { + FileInputStream fileInputStream = new FileInputStream(structureFile); + fileInputStream.read(content); + fileInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + FileOutputStream fileOutputStream = new FileOutputStream(structureFile, false); + fileOutputStream.write(Base64.getEncoder().encode(Compression.decompress(content).getBytes())); + fileOutputStream.flush(); + fileOutputStream.close(); + } catch (IOException e) { + messageManager.sendMessage(player, + configLoad.getString("Command.Island.Admin.Structure.Convert.Converted.Failed.Message") + .replace("%name", args[1])); + soundManager.playSound(player, Sounds.ANVIL_LAND.bukkitSound(), 1.0F, 1.0F); + e.printStackTrace(); + } + + messageManager.sendMessage(player, + configLoad.getString("Command.Island.Admin.Structure.Convert.Converted.Successful.Message") + .replace("%name", args[1])); + soundManager.playSound(player, Sounds.VILLAGER_YES.bukkitSound(), 1.0F, 1.0F); + + } else { + messageManager.sendMessage(player, + configLoad.getString("Command.Island.Admin.Structure.Convert.Invalid.Message")); + soundManager.playSound(player, Sounds.ANVIL_LAND.bukkitSound(), 1.0F, 1.0F); + } + return; } @@ -206,6 +271,7 @@ public class StructureCommand extends SubCommand { @Override public String[] getArguments() { - return new String[]{"tool", "save"}; + return new String[]{"tool", "save", "convert"}; } + } diff --git a/src/main/java/com/songoda/skyblock/utils/structure/StructureUtil.java b/src/main/java/com/songoda/skyblock/utils/structure/StructureUtil.java index a3928653..41d64b6c 100644 --- a/src/main/java/com/songoda/skyblock/utils/structure/StructureUtil.java +++ b/src/main/java/com/songoda/skyblock/utils/structure/StructureUtil.java @@ -6,6 +6,7 @@ import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; import com.songoda.skyblock.SkyBlock; import com.songoda.skyblock.config.FileManager; +import com.songoda.skyblock.utils.Compression; import com.songoda.skyblock.utils.version.NMSUtil; import com.songoda.skyblock.utils.world.LocationUtil; import com.songoda.skyblock.utils.world.block.BlockData; @@ -14,6 +15,8 @@ import com.songoda.skyblock.utils.world.block.BlockUtil; import com.songoda.skyblock.utils.world.entity.EntityData; import com.songoda.skyblock.utils.world.entity.EntityUtil; +import java.io.FileInputStream; +import java.util.Base64; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; @@ -29,7 +32,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Base64; import java.util.LinkedHashMap; import java.util.List; import java.util.logging.Level; @@ -103,24 +105,37 @@ public final class StructureUtil { } public static Structure loadStructure(File configFile) throws IOException { - String base64 = getBase64String(configFile); - - if (base64 == null) { - base64 = getBase64String(new File(SkyBlock.getInstance().getDataFolder() + "/" + "structures", "default.structure")); - SkyBlock.getInstance().getLogger().log(Level.SEVERE, "Unable to load structure '" + configFile.getAbsolutePath() + "' using default instead."); - } - - if (base64 == null) { - throw new IllegalArgumentException("Couldn't load the default structure file."); - } + byte[] content = new byte[(int) configFile.length()]; + FileInputStream fileInputStream = new FileInputStream(configFile); + fileInputStream.read(content); + fileInputStream.close(); Storage storage; - try { - storage = new Gson().fromJson(new String(Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8))), Storage.class); - } catch (JsonSyntaxException e) { - e.printStackTrace(); - return null; + if (!org.bukkit.craftbukkit.libs.org.apache.commons.codec.binary.Base64.isBase64(content)) { + try { + storage = new Gson().fromJson(Compression.decompress(content), Storage.class); + } catch (JsonSyntaxException e) { + e.printStackTrace(); + return null; + } + } else { + String base64 = getBase64String(configFile); + + if (base64 == null) { + base64 = getBase64String(new File(SkyBlock.getInstance().getDataFolder() + "/" + "structures", "default.structure")); + SkyBlock.getInstance().getLogger().log(Level.SEVERE, "Unable to load structure '" + configFile.getAbsolutePath() + "' using default instead."); + } + + if (base64 == null) { + throw new IllegalArgumentException("Couldn't load the default structure file."); + } + try { + storage = new Gson().fromJson(new String(Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8))), Storage.class); + } catch (JsonSyntaxException e) { + e.printStackTrace(); + return null; + } } return new Structure(storage, configFile.getName()); diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml index 72d3742d..93563d20 100644 --- a/src/main/resources/language.yml +++ b/src/main/resources/language.yml @@ -226,6 +226,16 @@ Command: Message: '&bSkyBlock &8| &cError&8: &eBoth selected positions have to be in the same World.' Info: Message: '&f&oCreate Structures for Islands.' + Convert: + Info: + Message: '&f&oConverts old Structure files.' + Invalid: + Message: '&bSkyBlock &8| &aInfo&8: &eThe Structure with the name ''&d%name&e'' was not found!' + Converted: + Successful: + Message: '&bSkyBlock &8| &aInfo&8: &eThe Structure with the name ''&d%name&e'' has been converted!' + Failed: + Message: '&bSkyBlock &8| &cError&8: &eAn error occurred when trying to convert the Structure.' SetSize: Set: Message: '&bSkyBlock &8| &aInfo&8: &eYou have set &d%player''s &eIsland size to &d%size&e.'