diff --git a/src/main/java/de/fanta/challenges/guis/savegui/ChallengeSaveGui.java b/src/main/java/de/fanta/challenges/guis/savegui/ChallengeSaveGui.java index 7d75bfa..9837144 100644 --- a/src/main/java/de/fanta/challenges/guis/savegui/ChallengeSaveGui.java +++ b/src/main/java/de/fanta/challenges/guis/savegui/ChallengeSaveGui.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.UUID; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; public class ChallengeSaveGui extends AbstractWindow { @@ -50,25 +51,37 @@ File save2; File save3; File saveAuto; + File saveZip1; + File saveZip2; + File saveZip3; + File saveZipAuto; if (plugin.getServerType() != ServerType.ADVENTURE) { save1 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/1"); save2 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/2"); save3 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/3"); saveAuto = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/autosave"); + saveZip1 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/1.zip"); + saveZip2 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/2.zip"); + saveZip3 = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/3.zip"); + saveZipAuto = new File(plugin.getChallengeSavePath().toFile(), savePlayerID + "/autosave.zip"); } else { save1 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/1"); save2 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/2"); save3 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/3"); saveAuto = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/autosave"); + saveZip1 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/1.zip"); + saveZip2 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/2.zip"); + saveZip3 = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/3.zip"); + saveZipAuto = new File(plugin.getAdventureSavePath().toFile(), savePlayerID + "/autosave.zip"); } for (int i = 0; i < WINDOW_SIZE; i++) { ItemStack item; switch (i) { - case SAVE_1_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_1, save1); - case SAVE_2_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_2, save2); - case SAVE_3_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_3, save3); - case SAVE_AUTO_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_AUTO, saveAuto); + case SAVE_1_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_1, save1, saveZip1); + case SAVE_2_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_2, save2, saveZip2); + case SAVE_3_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_3, save3, saveZip3); + case SAVE_AUTO_INDEX -> item = getDisplayItem(player, SaveSlot.SLOT_AUTO, saveAuto, saveZipAuto); default -> item = GUIUtils.EMPTY_ICON; } this.getInventory().setItem(i, item); @@ -156,29 +169,51 @@ return StringUtil.formatDate(fileTime.toMillis()); } - private static ItemStack getDisplayItem(Player player, SaveSlot saveSlot, File save) { + private static ItemStack getDisplayItem(Player player, SaveSlot saveSlot, File save, File saveZIP) { ItemStack item; if (player.hasPermission(saveSlot.getPermission())) { + File saveFile = null; if (save.isDirectory()) { - File mapConfig = new File(save, "/Challenges/serverconfig.yml"); + saveFile = save; + } else if (saveZIP.isFile()) { + saveFile = saveZIP; + } + + + if (saveFile != null) { + File mapConfig = null; + if (save.isDirectory()) { + mapConfig = new File(saveFile, "/Challenges/serverconfig.yml"); + } else if (saveZIP.isFile()) { + try { + mapConfig = SaveWorldUtils.getFileFromZip(saveZIP, "/Challenges/serverconfig.yml"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + + Material displayItem = null; String displayName = null; - try { - YamlConfiguration serverConfig = new YamlConfiguration(); - serverConfig.load(mapConfig); - String itemType = serverConfig.getString("displayItem.item"); - String itemName = serverConfig.getString("displayItem.name"); - if (itemType != null) { - try { - displayItem = Material.valueOf(itemType); - } catch (IllegalArgumentException ignore) { + if (mapConfig != null) { + try { + YamlConfiguration serverConfig = new YamlConfiguration(); + serverConfig.load(mapConfig); + String itemType = serverConfig.getString("displayItem.item"); + String itemName = serverConfig.getString("displayItem.name"); + if (itemType != null) { + try { + displayItem = Material.valueOf(itemType); + } catch (IllegalArgumentException ignore) { + } } + if (itemName != null) { + displayName = itemName; + } + } catch (IOException | InvalidConfigurationException ex) { + plugin.getLogger().log(Level.SEVERE, "Fehler beim laden der config", ex); } - if (itemName != null) { - displayName = itemName; - } - } catch (IOException | InvalidConfigurationException ex) { - plugin.getLogger().log(Level.SEVERE, "Fehler beim laden der config", ex); } ItemStack stack = new ItemStack(displayItem != null ? displayItem : Material.MAP); @@ -186,9 +221,9 @@ meta.setDisplayName(displayName != null ? displayName : ChatUtil.GREEN + "Save " + saveSlot.getSlot()); if (saveSlot == SaveSlot.SLOT_AUTO) { - meta.setLore(List.of(ChatUtil.RED + "AutoSave kann nicht überschrieben werden!", ChatUtil.GREEN + "Gespeichert am " + getFileDate(save))); + meta.setLore(List.of(ChatUtil.RED + "AutoSave kann nicht überschrieben werden!", ChatUtil.GREEN + "Gespeichert am " + getFileDate(saveFile))); } else { - meta.setLore(List.of(ChatUtil.GREEN + "Gespeichert am " + getFileDate(save))); + meta.setLore(List.of(ChatUtil.GREEN + "Gespeichert am " + getFileDate(saveFile))); } stack.setItemMeta(meta); diff --git a/src/main/java/de/fanta/challenges/utils/SaveWorldUtils.java b/src/main/java/de/fanta/challenges/utils/SaveWorldUtils.java index 8d42948..1a14e93 100644 --- a/src/main/java/de/fanta/challenges/utils/SaveWorldUtils.java +++ b/src/main/java/de/fanta/challenges/utils/SaveWorldUtils.java @@ -16,15 +16,21 @@ import javax.annotation.Nullable; import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; +import java.util.List; import java.util.Properties; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; public class SaveWorldUtils { @@ -107,6 +113,7 @@ } private static boolean copyWorldAsync(Player player, String saveID, SaveSlot saveSlot) { + ArrayList fileList = new ArrayList<>(); File dir = new File(saveID); File configs = new File("plugins/Challenges"); File end = new File("world_the_end"); @@ -119,9 +126,9 @@ File saveFolder; AtomicBoolean done = new AtomicBoolean(false); if (plugin.getServerType() != ServerType.ADVENTURE) { - saveFolder = new File(plugin.getChallengeSavePath().toFile(), saveID + "/" + saveSlot.getSlot() + "/"); + saveFolder = new File(plugin.getChallengeSavePath().toFile(), saveID + "/"); } else { - saveFolder = new File(plugin.getAdventureSavePath().toFile(), saveID + "/" + saveSlot.getSlot() + "/"); + saveFolder = new File(plugin.getAdventureSavePath().toFile(), saveID + "/"); } try { FileUtils.forceMkdir(dir); @@ -130,16 +137,36 @@ FileUtils.copyDirectory(nether, savenether); FileUtils.copyDirectory(world, saveworld); + fileList.add(saveconfigs); + fileList.add(saveend); + fileList.add(savenether); + fileList.add(saveworld); + if (player != null) { ChatUtil.sendNormalMessage(player, "Welt wurde erfolgreich kopiert und wird nun gespeichert. Dies kann einige Minuten dauern. Du kannst aber ganz normal weiter spielen."); } CompletableFuture copyFuture = CompletableFuture.supplyAsync(() -> { try { - if (saveFolder.isDirectory()) { - FileUtils.deleteDirectory(saveFolder); + createZipFile(saveSlot.getSlot() + ".zip", fileList); + + if (dir.isDirectory()) { + FileUtils.deleteDirectory(dir); } - FileUtils.moveDirectory(dir, saveFolder); + + if (saveFolder.isDirectory()) { + saveFolder.mkdirs(); + } + File saveFile = new File(saveFolder, saveSlot.getSlot() + "/"); + if (saveFile.isDirectory()) { + FileUtils.deleteDirectory(saveFile); + } + saveFile = new File(saveFolder, saveSlot.getSlot() + ".zip"); + System.out.println(saveFile.toPath()); + if (saveFile.exists()) { + FileUtils.delete(saveFile); + } + FileUtils.moveFile(new File(saveSlot.getSlot() + ".zip"), new File(saveFolder, saveSlot.getSlot() + ".zip"), StandardCopyOption.REPLACE_EXISTING); return true; } catch (IOException ex) { Bukkit.getLogger().log(Level.SEVERE, "Could not save world ", ex); @@ -174,6 +201,41 @@ return done.get(); } + public static void createZipFile(String zipFilePath, List folders) throws IOException { + byte[] buffer = new byte[1024]; + + try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFilePath))) { + for (File folder : folders) { + if (folder.isDirectory()) { + addFolderToZip(folder, folder.getName(), zipOutputStream, buffer); + } + } + } + } + + private static void addFolderToZip(File folder, String parentFolder, ZipOutputStream zipOutputStream, byte[] buffer) throws IOException { + File[] files = folder.listFiles(); + + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + addFolderToZip(file, parentFolder + "/" + file.getName(), zipOutputStream, buffer); + } else { + try (FileInputStream fileInputStream = new FileInputStream(file)) { + zipOutputStream.putNextEntry(new ZipEntry(parentFolder + "/" + file.getName())); + + int length; + while ((length = fileInputStream.read(buffer)) > 0) { + zipOutputStream.write(buffer, 0, length); + } + + zipOutputStream.closeEntry(); + } + } + } + } + } + public static void restartServer(@Nullable String seed) { if (isSavingWorld) { restartSeed = seed; @@ -211,6 +273,7 @@ restart = true; SaveWorldUtils.saveWorld(plugin.getFirstEditor().getUniqueId().toString(), SaveSlot.SLOT_AUTO); } else { + Config.setValue("World_Reset", true); Bukkit.shutdown(); } @@ -236,4 +299,17 @@ e.printStackTrace(); } } + + public static File getFileFromZip(File zipFilePath, String fileName) throws IOException { + try (ZipFile zipFile = new ZipFile(zipFilePath)) { + ZipEntry entry = zipFile.getEntry(fileName); + + if (entry != null) { + File tempFile = File.createTempFile("temp", null); + tempFile.deleteOnExit(); + return tempFile; + } + return null; + } + } }