Fix importing fabric multimc instance

This commit is contained in:
huanghongxun
2019-04-28 14:18:04 +08:00
parent e0abf3e0c1
commit 55d38f2b36
4 changed files with 38 additions and 19 deletions

View File

@@ -20,6 +20,7 @@ package org.jackhuang.hmcl.mod;
import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.StringUtils;
import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.CompressingUtils;
import org.jackhuang.hmcl.util.io.FileUtils;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -264,12 +265,23 @@ public final class MultiMCInstanceConfiguration {
return mmcPack; return mmcPack;
} }
public static Modpack readMultiMCModpackManifest(Path modpackFile, Charset encoding) throws IOException { private static boolean testPath(Path root) {
MultiMCManifest manifest = MultiMCManifest.readMultiMCModpackManifest(modpackFile, encoding); return Files.exists(root.resolve("instance.cfg"));
try (FileSystem fs = CompressingUtils.readonly(modpackFile).setEncoding(encoding).build()) { }
Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny()
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")); .orElseThrow(() -> new IOException("Not a valid MultiMC modpack"));
String name = StringUtils.removeSuffix(root.normalize().getFileName().toString(), "/"); if (testPath(candidate)) return candidate;
throw new IOException("Not a valid MultiMC modpack");
}
public static Modpack readMultiMCModpackManifest(Path modpackFile, Charset encoding) throws IOException {
try (FileSystem fs = CompressingUtils.readonly(modpackFile).setEncoding(encoding).build()) {
Path root = getRootPath(fs.getPath("/"));
MultiMCManifest manifest = MultiMCManifest.readMultiMCModpackManifest(root);
String name = FileUtils.getName(root, FileUtils.getNameWithoutExtension(modpackFile));
Path instancePath = root.resolve("instance.cfg"); Path instancePath = root.resolve("instance.cfg");
if (Files.notExists(instancePath)) if (Files.notExists(instancePath))

View File

@@ -52,10 +52,14 @@ public final class MultiMCManifest {
return components; return components;
} }
public static MultiMCManifest readMultiMCModpackManifest(Path zipFile, Charset encoding) throws IOException { /**
try (FileSystem fs = CompressingUtils.readonly(zipFile).setEncoding(encoding).build()) { * Read MultiMC modpack manifest from zip file
Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny() * @param root root path in zip file (Path root is a path of ZipFileSystem)
.orElseThrow(() -> new IOException("Not a valid MultiMC modpack")); * @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"); Path mmcPack = root.resolve("mmc-pack.json");
if (Files.notExists(mmcPack)) if (Files.notExists(mmcPack))
return null; return null;
@@ -67,7 +71,6 @@ public final class MultiMCManifest {
return manifest; return manifest;
} }
}
public static final class MultiMCManifestCachedRequires { public static final class MultiMCManifestCachedRequires {
@SerializedName("equals") @SerializedName("equals")

View File

@@ -135,8 +135,7 @@ public final class MultiMCModpackInstallTask extends Task {
Version version = repository.readVersionJson(name); Version version = repository.readVersionJson(name);
try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(zipFile.toPath())) { try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(zipFile.toPath())) {
Path root = Files.list(fs.getPath("/")).filter(Files::isDirectory).findAny() Path root = MultiMCInstanceConfiguration.getRootPath(fs.getPath("/"));
.orElseThrow(() -> new IOException("Not a valid MultiMC modpack"));
Path patches = root.resolve("patches"); Path patches = root.resolve("patches");
if (Files.exists(patches)) if (Files.exists(patches))

View File

@@ -100,6 +100,11 @@ public final class FileUtils {
return StringUtils.removeSuffix(path.getFileName().toString(), "/", "\\"); 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 { public static String readText(File file) throws IOException {
return readText(file, UTF_8); return readText(file, UTF_8);
} }