diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/ManuallyCreatedModpackInstallTask.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/ManuallyCreatedModpackInstallTask.java index 9ad05840766..a07c864fadb 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/ManuallyCreatedModpackInstallTask.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/ManuallyCreatedModpackInstallTask.java @@ -18,11 +18,9 @@ package org.jackhuang.hmcl.game; import org.jackhuang.hmcl.task.Task; -import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.Unzipper; import java.nio.charset.Charset; -import java.nio.file.FileSystem; import java.nio.file.Path; import java.nio.file.Paths; @@ -44,19 +42,12 @@ public ManuallyCreatedModpackInstallTask(Path zipFile, Charset charset, String n @Override public void execute() throws Exception { - Path subdirectory; - try (FileSystem fs = CompressingUtils.readonly(zipFile).setEncoding(charset).build()) { - subdirectory = ModpackHelper.findMinecraftDirectoryInManuallyCreatedModpack(zipFile.toString(), fs); - } + String subdirectory = ModpackHelper.findMinecraftDirectoryInManuallyCreatedModpack(zipFile.toString(), zipFile); Path dest = Paths.get("externalgames").resolve(name); setResult(dest); - new Unzipper(zipFile, dest) - .setSubDirectory(subdirectory.toString()) - .setTerminateIfSubDirectoryNotExists() - .setEncoding(charset) - .unzip(); + new Unzipper(zipFile, dest).setSubDirectory(subdirectory).setTerminateIfSubDirectoryNotExists().setEncoding(charset).unzip(); } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java index 2f6723f28e8..17bd6197ada 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/ModpackHelper.java @@ -31,11 +31,7 @@ import org.jackhuang.hmcl.modpack.server.ServerModpackManifest; import org.jackhuang.hmcl.modpack.server.ServerModpackProvider; import org.jackhuang.hmcl.modpack.server.ServerModpackRemoteInstallTask; -import org.jackhuang.hmcl.setting.GameSettings; -import org.jackhuang.hmcl.setting.GameWindowType; -import org.jackhuang.hmcl.setting.JavaVersionType; -import org.jackhuang.hmcl.setting.GameDirectory; -import org.jackhuang.hmcl.setting.GameDirectoryManager; +import org.jackhuang.hmcl.setting.*; import org.jackhuang.hmcl.task.Schedulers; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.Lang; @@ -46,13 +42,13 @@ import org.jackhuang.hmcl.util.i18n.LocalizedText; import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.FileUtils; +import org.jackhuang.hmcl.util.tree.ArchiveFileTree; import org.jetbrains.annotations.NotNullByDefault; import org.jetbrains.annotations.Nullable; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.Charset; -import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -60,10 +56,8 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.stream.Stream; import static org.jackhuang.hmcl.util.Lang.mapOf; -import static org.jackhuang.hmcl.util.Lang.toIterable; import static org.jackhuang.hmcl.util.Pair.pair; /// Utilities for reading, installing, and applying modpack-specific game settings. @@ -114,8 +108,8 @@ public static Modpack readModpackManifest(Path file, Charset charset) throws Uns } catch (IOException ignored) { } - try (FileSystem fs = CompressingUtils.createReadOnlyZipFileSystem(file, charset)) { - findMinecraftDirectoryInManuallyCreatedModpack(file.toString(), fs); + try { + findMinecraftDirectoryInManuallyCreatedModpack(file.toString(), file); throw new ManuallyCreatedModpackException(file); } catch (IOException e) { // ignore it @@ -124,28 +118,35 @@ public static Modpack readModpackManifest(Path file, Charset charset) throws Uns throw new UnsupportedModpackException(file.toString()); } - public static Path findMinecraftDirectoryInManuallyCreatedModpack(String modpackName, FileSystem fs) throws IOException, UnsupportedModpackException { - Path root = fs.getPath("/"); - if (isMinecraftDirectory(root)) return root; - try (Stream firstLayer = Files.list(root)) { - for (Path dir : toIterable(firstLayer)) { - if (isMinecraftDirectory(dir)) return dir; + public static String findMinecraftDirectoryInManuallyCreatedModpack(String modpackName, Path zipPath) + throws IOException, UnsupportedModpackException { + + try (ArchiveFileTree tree = ArchiveFileTree.open(zipPath)) { + ArchiveFileTree.Dir rootDir = tree.getRoot(); + + if (isMinecraftDirectory(rootDir)) { + return ""; + } + - try (Stream secondLayer = Files.list(dir)) { - for (Path subdir : toIterable(secondLayer)) { - if (isMinecraftDirectory(subdir)) return subdir; + for (ArchiveFileTree.Dir firstLayer : rootDir.getSubDirs().values()) { + if (isMinecraftDirectory(firstLayer)) { + return firstLayer.getName(); + } + + for (ArchiveFileTree.Dir secondLayer : firstLayer.getSubDirs().values()) { + if (isMinecraftDirectory(secondLayer)) { + return firstLayer.getName() + "/" + secondLayer.getName(); } - } catch (IOException ignored) { } } - } catch (IOException ignored) { } + throw new UnsupportedModpackException(modpackName); } - private static boolean isMinecraftDirectory(Path path) { - return Files.isDirectory(path.resolve("versions")) && - (path.getFileName() == null || ".minecraft".equals(FileUtils.getName(path))); + private static boolean isMinecraftDirectory(ArchiveFileTree.Dir dir) { + return dir.getSubDirs().containsKey("versions") && (dir.isRoot() || ".minecraft".equals(dir.getName())); } public static ModpackConfiguration readModpackConfiguration(Path file) throws IOException {