From 93f72f6945b7b6cac858e46250bba3a0c116d4af Mon Sep 17 00:00:00 2001 From: Glavo Date: Tue, 6 Jan 2026 21:28:53 +0800 Subject: [PATCH 1/3] update --- .../hmcl/util/io/CompressingUtils.java | 23 +++++++++++++------ .../org/jackhuang/hmcl/util/io/Unzipper.java | 23 +------------------ 2 files changed, 17 insertions(+), 29 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java index 675f2f9a25..2027aeb36d 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java @@ -133,12 +133,25 @@ public static ZipFileTree openZipTree(Path zipFile) throws IOException { } public static ZipArchiveReader openZipFile(Path zipFile) throws IOException { + return openZipFileWithPossibleEncoding(zipFile, StandardCharsets.UTF_8); + } + + public static ZipArchiveReader openZipFile(Path zipFile, Charset charset) throws IOException { + return new ZipArchiveReader(zipFile, charset); + } + + public static ZipArchiveReader openZipFileWithPossibleEncoding(Path zipFile, Charset possibleEncoding) throws IOException { ZipArchiveReader zipReader = new ZipArchiveReader(Files.newByteChannel(zipFile)); + Charset suitableEncoding; try { - suitableEncoding = findSuitableEncoding(zipReader); - if (suitableEncoding == StandardCharsets.UTF_8) - return zipReader; + if (possibleEncoding != StandardCharsets.UTF_8 && CompressingUtils.testEncoding(zipReader, possibleEncoding)) { + suitableEncoding = possibleEncoding; + } else { + suitableEncoding = CompressingUtils.findSuitableEncoding(zipReader); + if (suitableEncoding == StandardCharsets.UTF_8) + return zipReader; + } } catch (Throwable e) { IOUtils.closeQuietly(zipReader, e); throw e; @@ -148,10 +161,6 @@ public static ZipArchiveReader openZipFile(Path zipFile) throws IOException { return new ZipArchiveReader(Files.newByteChannel(zipFile), suitableEncoding); } - public static ZipArchiveReader openZipFile(Path zipFile, Charset charset) throws IOException { - return new ZipArchiveReader(zipFile, charset); - } - public static final class Builder { private boolean autoDetectEncoding = false; private Charset encoding = StandardCharsets.UTF_8; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/Unzipper.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/Unzipper.java index 05542fdbd7..c5cf0c2d78 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/Unzipper.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/Unzipper.java @@ -80,27 +80,6 @@ public Unzipper setTerminateIfSubDirectoryNotExists() { return this; } - private ZipArchiveReader openReader() throws IOException { - ZipArchiveReader zipReader = new ZipArchiveReader(Files.newByteChannel(zipFile)); - - Charset suitableEncoding; - try { - if (encoding != StandardCharsets.UTF_8 && CompressingUtils.testEncoding(zipReader, encoding)) { - suitableEncoding = encoding; - } else { - suitableEncoding = CompressingUtils.findSuitableEncoding(zipReader); - if (suitableEncoding == StandardCharsets.UTF_8) - return zipReader; - } - } catch (Throwable e) { - IOUtils.closeQuietly(zipReader, e); - throw e; - } - - zipReader.close(); - return new ZipArchiveReader(Files.newByteChannel(zipFile), suitableEncoding); - } - /// Decompress the given zip file to a directory. /// /// @throws IOException if zip file is malformed or filesystem error. @@ -113,7 +92,7 @@ public void unzip() throws IOException { : new CopyOption[]{}; long entryCount = 0L; - try (ZipArchiveReader reader = openReader()) { + try (ZipArchiveReader reader = CompressingUtils.openZipFileWithPossibleEncoding(zipFile, encoding)) { String pathPrefix = StringUtils.addSuffix(subDirectory, "/"); for (ZipArchiveEntry entry : reader.getEntries()) { From b2aa43d61187302dc2a5dca7844d6c728b3f72e6 Mon Sep 17 00:00:00 2001 From: Glavo Date: Tue, 6 Jan 2026 21:32:59 +0800 Subject: [PATCH 2/3] update --- .../hmcl/mod/MinecraftInstanceTask.java | 13 +++++++++++++ .../jackhuang/hmcl/util/io/CompressingUtils.java | 3 +++ .../hmcl/util/tree/ArchiveFileTree.java | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java index d4bd61cacf..b2d8fb9fd0 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java @@ -17,11 +17,15 @@ */ package org.jackhuang.hmcl.mod; +import kala.compress.archivers.zip.ZipArchiveEntry; +import kala.compress.archivers.zip.ZipArchiveReader; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.DigestUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; import org.jackhuang.hmcl.util.io.CompressingUtils; import org.jackhuang.hmcl.util.io.FileUtils; +import org.jackhuang.hmcl.util.tree.ArchiveFileTree; +import org.jackhuang.hmcl.util.tree.ZipFileTree; import java.io.File; import java.io.IOException; @@ -57,6 +61,15 @@ public MinecraftInstanceTask(Path zipFile, Charset encoding, List subDir public void execute() throws Exception { List overrides = new ArrayList<>(); + try (var tree = new ZipFileTree(CompressingUtils.openZipFileWithPossibleEncoding(zipFile, encoding))) { + for (String subDirectory : subDirectories) { + ArchiveFileTree.Dir dir = tree.getDirectory(subDirectory); + if (dir != null) { + // TODO + } + } + } + try (FileSystem fs = CompressingUtils.readonly(zipFile).setEncoding(encoding).build()) { for (String subDirectory : subDirectories) { Path root = fs.getPath(subDirectory); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java index 2027aeb36d..d4875d909c 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/CompressingUtils.java @@ -141,6 +141,9 @@ public static ZipArchiveReader openZipFile(Path zipFile, Charset charset) throws } public static ZipArchiveReader openZipFileWithPossibleEncoding(Path zipFile, Charset possibleEncoding) throws IOException { + if (possibleEncoding == null) + possibleEncoding = StandardCharsets.UTF_8; + ZipArchiveReader zipReader = new ZipArchiveReader(Files.newByteChannel(zipFile)); Charset suitableEncoding; diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/tree/ArchiveFileTree.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/tree/ArchiveFileTree.java index c69adcd983..f96b898c42 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/tree/ArchiveFileTree.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/tree/ArchiveFileTree.java @@ -90,6 +90,22 @@ public Dir getRoot() { } } + public @Nullable Dir getDirectory(@NotNull String dirPath) { + Dir dir = root; + if (dirPath.isEmpty()) { + return dir; + } + String[] path = dirPath.split("/"); + for (String item : path) { + if (item.isEmpty()) + continue; + dir = dir.getSubDirs().get(item); + if (dir == null) + return null; + } + return dir; + } + protected void addEntry(E entry) throws IOException { String[] path = entry.getName().split("/"); List pathList = Arrays.asList(path); From efcc803ef167ccdd90e783cb19484927dd2974e1 Mon Sep 17 00:00:00 2001 From: Glavo Date: Tue, 6 Jan 2026 21:55:14 +0800 Subject: [PATCH 3/3] update --- .../hmcl/mod/MinecraftInstanceTask.java | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java index b2d8fb9fd0..88d8dc8d03 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/MinecraftInstanceTask.java @@ -18,7 +18,6 @@ package org.jackhuang.hmcl.mod; import kala.compress.archivers.zip.ZipArchiveEntry; -import kala.compress.archivers.zip.ZipArchiveReader; import org.jackhuang.hmcl.task.Task; import org.jackhuang.hmcl.util.DigestUtils; import org.jackhuang.hmcl.util.gson.JsonUtils; @@ -27,13 +26,13 @@ import org.jackhuang.hmcl.util.tree.ArchiveFileTree; import org.jackhuang.hmcl.util.tree.ZipFileTree; -import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.charset.Charset; import java.nio.file.*; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.List; +import java.util.Map; public final class MinecraftInstanceTask extends Task> { @@ -57,35 +56,42 @@ public MinecraftInstanceTask(Path zipFile, Charset encoding, List subDir this.version = version; } + private static void getOverrides(List overrides, + ZipFileTree tree, + ArchiveFileTree.Dir dir, + List names) throws IOException { + String prefix = String.join("/", names); + if (!prefix.isEmpty()) + prefix = prefix + "/"; + + for (Map.Entry entry : dir.getFiles().entrySet()) { + String hash; + try (InputStream input = tree.getInputStream(entry.getValue())) { + hash = DigestUtils.digestToString("SHA-1", input); + } + overrides.add(new ModpackConfiguration.FileInformation(prefix + entry.getKey(), hash)); + } + + for (ArchiveFileTree.Dir subDir : dir.getSubDirs().values()) { + names.add(subDir.getName()); + getOverrides(overrides, tree, subDir, names); + names.remove(names.size() - 1); + } + } + @Override public void execute() throws Exception { List overrides = new ArrayList<>(); try (var tree = new ZipFileTree(CompressingUtils.openZipFileWithPossibleEncoding(zipFile, encoding))) { for (String subDirectory : subDirectories) { - ArchiveFileTree.Dir dir = tree.getDirectory(subDirectory); - if (dir != null) { - // TODO - } + ArchiveFileTree.Dir root = tree.getDirectory(subDirectory); + if (root == null) + continue; + var names = new ArrayList(); + getOverrides(overrides, tree, root, names); } } - - try (FileSystem fs = CompressingUtils.readonly(zipFile).setEncoding(encoding).build()) { - for (String subDirectory : subDirectories) { - Path root = fs.getPath(subDirectory); - - if (Files.exists(root)) - Files.walkFileTree(root, new SimpleFileVisitor<>() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - String relativePath = root.relativize(file).normalize().toString().replace(File.separatorChar, '/'); - overrides.add(new ModpackConfiguration.FileInformation(relativePath, DigestUtils.digestToString("SHA-1", file))); - return FileVisitResult.CONTINUE; - } - }); - } - } - ModpackConfiguration configuration = new ModpackConfiguration<>(manifest, type, name, version, overrides); Files.createDirectories(jsonFile.getParent()); JsonUtils.writeToJsonFile(jsonFile, configuration);