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.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))

View File

@@ -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 {

View File

@@ -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))

View File

@@ -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);
}