From 778f26d55ffdb0166ea000498b2defd1b897008d Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Fri, 21 Dec 2018 00:34:46 +0800 Subject: [PATCH] Support manually created world pack --- .../hmcl/ui/versions/WorldListPage.java | 3 +- .../resources/assets/lang/I18N.properties | 1 + .../resources/assets/lang/I18N_zh.properties | 1 + .../assets/lang/I18N_zh_CN.properties | 1 + .../java/org/jackhuang/hmcl/game/World.java | 47 +++++++++++++------ 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java index 2e50d4792..8ace6dcf5 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java @@ -85,7 +85,8 @@ public class WorldListPage extends ListPage { }).setInitialText(world.getWorldName()); } catch (IOException | IllegalArgumentException e) { - Logging.LOG.log(Level.WARNING, "Unable to parse datapack file " + zipFile, e); + Logging.LOG.log(Level.WARNING, "Unable to parse world file " + zipFile, e); + Controllers.dialog(i18n("world.import.invalid")); } } } diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index d18549266..a1f547fcd 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -272,6 +272,7 @@ world.game_version=Game Version world.import.already_exists=This world already exists. world.import.choose=Choose the save zip to be imported world.import.failed=Unable to import this world: %s +world.import.invalid=Not a valid world zip world.name=World Name world.name.enter=Enter the world name world.time=EEE, MMM d, yyyy HH:mm:ss diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 9d0811c23..fc657b9a4 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -270,6 +270,7 @@ world.extension=存檔壓縮檔 world.import.already_exists=此世界已經存在 world.import.choose=選擇要導入的存檔壓縮檔 world.import.failed=無法導入此世界: %s +world.import.invalid=無法識別的存檔壓縮包 world.game_version=遊戲版本 world.name=世界名稱 world.name.enter=輸入世界名稱 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 4a08d381d..4bc2e590c 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -271,6 +271,7 @@ world.game_version=游戏版本 world.import.already_exists=此世界已经存在 world.import.choose=选择要导入的存档压缩包 world.import.failed=无法导入此世界:%s +world.import.invalid=无法识别的存档压缩包 world.name=世界名称 world.name.enter=输入世界名称 world.time=yyyy 年 MM 月 dd 日 HH:mm:ss diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java index 67a2240e7..45be92e00 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java @@ -87,17 +87,27 @@ public class World { return gameVersion; } + private void loadFromZipImpl(Path root) throws IOException { + Path levelDat = root.resolve("level.dat"); + if (!Files.exists(levelDat)) + throw new IllegalArgumentException("Not a valid world zip file since level.dat cannot be found."); + + getWorldName(levelDat); + } + private void loadFromZip() throws IOException { try (FileSystem fs = CompressingUtils.readonly(file).setAutoDetectEncoding(true).build()) { + Path cur = fs.getPath("/level.dat"); + if (Files.isRegularFile(cur)) { + fileName = FileUtils.getName(file); + loadFromZipImpl(fs.getPath("/")); + return; + } + Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny() .orElseThrow(() -> new IOException("Not a valid world zip file")); - - Path levelDat = root.resolve("level.dat"); - if (!Files.exists(levelDat)) - throw new IllegalArgumentException("Not a valid world zip file since level.dat cannot be found."); - fileName = FileUtils.getName(root); - getWorldName(levelDat); + loadFromZipImpl(root); } } @@ -149,17 +159,24 @@ public class World { } if (Files.isRegularFile(file)) { - String subDirectoryName; - try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(file)) { - List subDirs = Files.list(fs.getPath("/")).collect(Collectors.toList()); - if (subDirs.size() != 1) { - throw new IOException("World zip malformed"); + try (FileSystem fs = CompressingUtils.readonly(file).setAutoDetectEncoding(true).build()) { + Path cur = fs.getPath("/level.dat"); + if (Files.isRegularFile(cur)) { + fileName = FileUtils.getName(file); + + new Unzipper(file, worldDir).unzip(); + } else { + List subDirs = Files.list(fs.getPath("/")).collect(Collectors.toList()); + if (subDirs.size() != 1) { + throw new IOException("World zip malformed"); + } + String subDirectoryName = FileUtils.getName(subDirs.get(0)); + new Unzipper(file, worldDir) + .setSubDirectory("/" + subDirectoryName + "/") + .unzip(); } - subDirectoryName = FileUtils.getName(subDirs.get(0)); + } - new Unzipper(file, worldDir) - .setSubDirectory("/" + subDirectoryName + "/") - .unzip(); new World(worldDir).rename(name); } else if (Files.isDirectory(file)) { FileUtils.copyDirectory(file, worldDir);