From 55d38f2b3660dc25923b60c03a05a6ab128ba7fd Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Sun, 28 Apr 2019 14:18:04 +0800 Subject: [PATCH] Fix importing fabric multimc instance --- .../mod/MultiMCInstanceConfiguration.java | 20 ++++++++++--- .../jackhuang/hmcl/mod/MultiMCManifest.java | 29 ++++++++++--------- .../hmcl/mod/MultiMCModpackInstallTask.java | 3 +- .../org/jackhuang/hmcl/util/io/FileUtils.java | 5 ++++ 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCInstanceConfiguration.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCInstanceConfiguration.java index 5dca0fdfc..5087fa217 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCInstanceConfiguration.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCInstanceConfiguration.java @@ -20,6 +20,7 @@ package org.jackhuang.hmcl.mod; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.io.CompressingUtils; +import org.jackhuang.hmcl.util.io.FileUtils; import java.io.IOException; import java.io.InputStream; @@ -264,12 +265,23 @@ public final class MultiMCInstanceConfiguration { return mmcPack; } + private static boolean testPath(Path root) { + return Files.exists(root.resolve("instance.cfg")); + } + + public static Path getRootPath(Path root) throws IOException { + if (testPath(root)) return root; + Path candidate = Files.list(root).filter(Files::isDirectory).findAny() + .orElseThrow(() -> new IOException("Not a valid MultiMC modpack")); + if (testPath(candidate)) return candidate; + throw new IOException("Not a valid MultiMC modpack"); + } + public static Modpack readMultiMCModpackManifest(Path modpackFile, Charset encoding) throws IOException { - MultiMCManifest manifest = MultiMCManifest.readMultiMCModpackManifest(modpackFile, encoding); try (FileSystem fs = CompressingUtils.readonly(modpackFile).setEncoding(encoding).build()) { - Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny() - .orElseThrow(() -> new IOException("Not a valid MultiMC modpack")); - String name = StringUtils.removeSuffix(root.normalize().getFileName().toString(), "/"); + Path root = getRootPath(fs.getPath("/")); + MultiMCManifest manifest = MultiMCManifest.readMultiMCModpackManifest(root); + String name = FileUtils.getName(root, FileUtils.getNameWithoutExtension(modpackFile)); Path instancePath = root.resolve("instance.cfg"); if (Files.notExists(instancePath)) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCManifest.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCManifest.java index ee8dee290..885469b5c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCManifest.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCManifest.java @@ -52,21 +52,24 @@ public final class MultiMCManifest { return components; } - public static MultiMCManifest readMultiMCModpackManifest(Path zipFile, Charset encoding) throws IOException { - try (FileSystem fs = CompressingUtils.readonly(zipFile).setEncoding(encoding).build()) { - Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny() - .orElseThrow(() -> new IOException("Not a valid MultiMC modpack")); - Path mmcPack = root.resolve("mmc-pack.json"); - if (Files.notExists(mmcPack)) - return null; - String json = IOUtils.readFullyAsString(Files.newInputStream(mmcPack)); - MultiMCManifest manifest = JsonUtils.fromNonNullJson(json, MultiMCManifest.class); + /** + * Read MultiMC modpack manifest from zip file + * @param root root path in zip file (Path root is a path of ZipFileSystem) + * @return the MultiMC modpack manifest. + * @throws IOException if zip file is malformed + * @throws com.google.gson.JsonParseException if manifest is malformed. + */ + public static MultiMCManifest readMultiMCModpackManifest(Path root) throws IOException { + Path mmcPack = root.resolve("mmc-pack.json"); + if (Files.notExists(mmcPack)) + return null; + String json = IOUtils.readFullyAsString(Files.newInputStream(mmcPack)); + MultiMCManifest manifest = JsonUtils.fromNonNullJson(json, MultiMCManifest.class); - if (manifest.getComponents() == null) - throw new IOException("mmc-pack.json malformed."); + if (manifest.getComponents() == null) + throw new IOException("mmc-pack.json malformed."); - return manifest; - } + return manifest; } public static final class MultiMCManifestCachedRequires { diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java index 6095604ec..85006d860 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MultiMCModpackInstallTask.java @@ -135,8 +135,7 @@ public final class MultiMCModpackInstallTask extends Task { Version version = repository.readVersionJson(name); try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(zipFile.toPath())) { - Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny() - .orElseThrow(() -> new IOException("Not a valid MultiMC modpack")); + Path root = MultiMCInstanceConfiguration.getRootPath(fs.getPath("/")); Path patches = root.resolve("patches"); if (Files.exists(patches)) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java index 23d6138ec..077ae0ca0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/FileUtils.java @@ -100,6 +100,11 @@ public final class FileUtils { return StringUtils.removeSuffix(path.getFileName().toString(), "/", "\\"); } + public static String getName(Path path, String candidate) { + if (path.getFileName() == null) return candidate; + else return getName(path); + } + public static String readText(File file) throws IOException { return readText(file, UTF_8); }