From 097530773c4f69f94f6408ad9763e1a3977f7eca Mon Sep 17 00:00:00 2001 From: ToobLac Date: Sun, 17 May 2026 18:54:29 +0800 Subject: [PATCH 1/9] update --- .../ui/export/ModpackFileSelectionPage.java | 19 +++++++++++++++---- .../org/jackhuang/hmcl/util/io/FileUtils.java | 8 ++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java index ed7664a9da8..18b8fd9aecb 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java @@ -110,19 +110,25 @@ private CheckBoxTreeItem getTreeItem(Path file, String basePath) { state = ModAdviser.ModSuggestion.HIDDEN; } - if (isDirectory && fileName.equals(version + "-natives")) // Ignore -natives - state = ModAdviser.ModSuggestion.HIDDEN; + if (isDirectory) { + if (fileName.equals(version + "-natives")) { // Ignore -natives + state = ModAdviser.ModSuggestion.HIDDEN; + } + if (fileName.startsWith("natives-")) { // Ignore natives-os-arch + state = ModAdviser.ModSuggestion.HIDDEN; + } + } if (state == ModAdviser.ModSuggestion.HIDDEN) return null; } - CheckBoxTreeItem node = new CheckBoxTreeItem<>(StringUtils.substringAfterLast(basePath, "/")); + CheckBoxTreeItem node = new CheckBoxTreeItem<>(""); if (state == ModAdviser.ModSuggestion.SUGGESTED) node.setSelected(true); if (isDirectory) { try (var stream = Files.list(file)) { - stream.forEach(it -> { + stream.sorted(FileUtils.dirFirstComparator).forEach(it -> { CheckBoxTreeItem subNode = getTreeItem(it, basePath + "/" + FileUtils.getName(it)); if (subNode != null) { node.setSelected(subNode.isSelected() || node.isSelected()); @@ -150,6 +156,11 @@ private CheckBoxTreeItem getTreeItem(Path file, String basePath) { checkBox.indeterminateProperty().bindBidirectional(node.indeterminateProperty()); graphic.getChildren().add(checkBox); + { + Label text = new Label(StringUtils.substringAfter(basePath, '/')); + text.setMouseTransparent(true); + graphic.getChildren().add(text); + } if (TRANSLATION.containsKey(basePath)) { Label comment = new Label(TRANSLATION.get(basePath)); comment.setStyle("-fx-text-fill: -monet-on-surface-variant;"); 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 bce609927db..b91cf42c263 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 @@ -49,6 +49,14 @@ public final class FileUtils { private FileUtils() { } + public static final Comparator dirFirstComparator = (p1, p2) -> { + if (p1 == null) return p2 == null ? 0 : -1; + if (p2 == null) return 1; + if (!p1.getParent().equals(p2.getParent())) return p1.compareTo(p2); + if (Files.isDirectory(p1) == Files.isDirectory(p2)) return p1.compareTo(p2); + return Files.isDirectory(p1) ? -1 : 1; + }; + public static @Nullable Path toPath(@Nullable File file) { try { return file != null ? file.toPath() : null; From be54dab2249af9e1178834c327957fc0a170f11e Mon Sep 17 00:00:00 2001 From: ToobLac Date: Sun, 17 May 2026 18:57:57 +0800 Subject: [PATCH 2/9] update --- .../hmcl/ui/export/ModpackFileSelectionPage.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java index 18b8fd9aecb..e47f737e44e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java @@ -65,7 +65,7 @@ public ModpackFileSelectionPage(WizardController controller, Profile profile, St this.adviser = adviser; JFXTreeView treeView = new JFXTreeView<>(); - rootNode = getTreeItem(profile.getRepository().getRunDirectory(version), "minecraft"); + rootNode = getTreeItem(profile.getRepository().getRunDirectory(version), "minecraft", 0); treeView.setRoot(rootNode); treeView.setSelectionModel(new NoneMultipleSelectionModel<>()); onEscPressed(treeView, () -> controller.onPrev(true)); @@ -86,7 +86,7 @@ public ModpackFileSelectionPage(WizardController controller, Profile profile, St this.setBottom(nextPane); } - private CheckBoxTreeItem getTreeItem(Path file, String basePath) { + private CheckBoxTreeItem getTreeItem(Path file, String basePath, int level) { if (Files.notExists(file)) return null; @@ -114,7 +114,7 @@ private CheckBoxTreeItem getTreeItem(Path file, String basePath) { if (fileName.equals(version + "-natives")) { // Ignore -natives state = ModAdviser.ModSuggestion.HIDDEN; } - if (fileName.startsWith("natives-")) { // Ignore natives-os-arch + if (level == 1 && fileName.startsWith("natives-")) { // Ignore natives-os-arch state = ModAdviser.ModSuggestion.HIDDEN; } } @@ -129,7 +129,7 @@ private CheckBoxTreeItem getTreeItem(Path file, String basePath) { if (isDirectory) { try (var stream = Files.list(file)) { stream.sorted(FileUtils.dirFirstComparator).forEach(it -> { - CheckBoxTreeItem subNode = getTreeItem(it, basePath + "/" + FileUtils.getName(it)); + CheckBoxTreeItem subNode = getTreeItem(it, basePath + "/" + FileUtils.getName(it), level + 1); if (subNode != null) { node.setSelected(subNode.isSelected() || node.isSelected()); if (!subNode.isSelected()) { From 9494e4ecc5ee37c013b6c5012b83601e17b000fa Mon Sep 17 00:00:00 2001 From: ToobLac Date: Mon, 18 May 2026 19:48:57 +0800 Subject: [PATCH 3/9] Fix #6116 --- .../jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java | 2 +- .../src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java index e47f737e44e..0dc22ecec3a 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java @@ -157,7 +157,7 @@ private CheckBoxTreeItem getTreeItem(Path file, String basePath, int lev graphic.getChildren().add(checkBox); { - Label text = new Label(StringUtils.substringAfter(basePath, '/')); + Label text = new Label(level == 0 ? version : StringUtils.substringAfter(basePath, '/')); text.setMouseTransparent(true); graphic.getChildren().add(text); } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java index 837bdbcb02d..c3ba932c1ae 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java @@ -19,7 +19,6 @@ import org.jackhuang.hmcl.util.Lang; -import java.io.File; import java.util.List; /** @@ -74,7 +73,7 @@ enum ModSuggestion { "optionsof.txt" /* OptiFine */, "journeymap" /* JourneyMap */, "optionsshaders.txt", - "mods" + File.separator + "VoxelMods"); + "mods/VoxelMods"); static ModAdviser.ModSuggestion suggestMod(String fileName, boolean isDirectory) { if (match(MODPACK_BLACK_LIST, fileName, isDirectory)) @@ -88,7 +87,7 @@ static ModAdviser.ModSuggestion suggestMod(String fileName, boolean isDirectory) static boolean match(List l, String fileName, boolean isDirectory) { for (String s : l) if (isDirectory) { - if (fileName.startsWith(s + File.separator)) + if (fileName.startsWith(s + '/')) return true; } else { if (s.startsWith("regex:")) { From 8a704006cb40c545789053ce01b9e2ff7590893a Mon Sep 17 00:00:00 2001 From: ToobLac Date: Mon, 18 May 2026 20:18:19 +0800 Subject: [PATCH 4/9] update --- .../main/java/org/jackhuang/hmcl/mod/Modpack.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java index 07876ebf817..5fe755ee80e 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java @@ -121,10 +121,23 @@ public Modpack setManifest(ModpackManifest manifest) { public abstract Task getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl); + private static boolean match(List l, String fileName) { + for (String s : l) { + if (s.startsWith("regex:")) { + if (fileName.matches(s.substring("regex:".length()))) + return true; + } else { + if (fileName.equals(s)) + return true; + } + } + return false; + } + public static boolean acceptFile(String path, List blackList, List whiteList) { if (path.isEmpty()) return true; - if (ModAdviser.match(blackList, path, false)) + if (match(blackList, path)) return false; if (whiteList == null || whiteList.isEmpty()) return true; From 52ce469a7f10967ced2b5ca73767cd19e1364cc0 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Mon, 18 May 2026 20:19:49 +0800 Subject: [PATCH 5/9] update --- HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java index c3ba932c1ae..28c31d959e5 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java @@ -84,6 +84,7 @@ static ModAdviser.ModSuggestion suggestMod(String fileName, boolean isDirectory) return ModAdviser.ModSuggestion.SUGGESTED; } + /// @param fileName "fileName/" for directories and "fileName" for files, regardless of the operating system static boolean match(List l, String fileName, boolean isDirectory) { for (String s : l) if (isDirectory) { From 559abecb2d382e920bd131dac0422c8ee0e2e2d1 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Mon, 18 May 2026 22:18:55 +0800 Subject: [PATCH 6/9] update --- .../ui/export/ModpackFileSelectionPage.java | 71 +++++++++++-------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java index 0dc22ecec3a..d0fca5d4205 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java @@ -57,7 +57,7 @@ public final class ModpackFileSelectionPage extends BorderPane implements Wizard private final WizardController controller; private final String version; private final ModAdviser adviser; - private final CheckBoxTreeItem rootNode; + private final ModpackFileTreeItem rootNode; public ModpackFileSelectionPage(WizardController controller, Profile profile, String version, ModAdviser adviser) { this.controller = controller; @@ -86,7 +86,7 @@ public ModpackFileSelectionPage(WizardController controller, Profile profile, St this.setBottom(nextPane); } - private CheckBoxTreeItem getTreeItem(Path file, String basePath, int level) { + private ModpackFileTreeItem getTreeItem(Path file, String basePath, int level) { if (Files.notExists(file)) return null; @@ -122,14 +122,14 @@ private CheckBoxTreeItem getTreeItem(Path file, String basePath, int lev return null; } - CheckBoxTreeItem node = new CheckBoxTreeItem<>(""); + ModpackFileTreeItem node = new ModpackFileTreeItem(level == 0 ? version : StringUtils.substringAfterLast(basePath, '/'), basePath); if (state == ModAdviser.ModSuggestion.SUGGESTED) node.setSelected(true); if (isDirectory) { try (var stream = Files.list(file)) { stream.sorted(FileUtils.dirFirstComparator).forEach(it -> { - CheckBoxTreeItem subNode = getTreeItem(it, basePath + "/" + FileUtils.getName(it), level + 1); + ModpackFileTreeItem subNode = getTreeItem(it, basePath + "/" + FileUtils.getName(it), level + 1); if (subNode != null) { node.setSelected(subNode.isSelected() || node.isSelected()); if (!subNode.isSelected()) { @@ -150,38 +150,17 @@ private CheckBoxTreeItem getTreeItem(Path file, String basePath, int lev } } - HBox graphic = new HBox(); - JFXCheckBox checkBox = new JFXCheckBox(); - checkBox.selectedProperty().bindBidirectional(node.selectedProperty()); - checkBox.indeterminateProperty().bindBidirectional(node.indeterminateProperty()); - graphic.getChildren().add(checkBox); - - { - Label text = new Label(level == 0 ? version : StringUtils.substringAfter(basePath, '/')); - text.setMouseTransparent(true); - graphic.getChildren().add(text); - } - if (TRANSLATION.containsKey(basePath)) { - Label comment = new Label(TRANSLATION.get(basePath)); - comment.setStyle("-fx-text-fill: -monet-on-surface-variant;"); - comment.setMouseTransparent(true); - graphic.getChildren().add(comment); - } - graphic.setPickOnBounds(false); - node.setExpanded("minecraft".equals(basePath)); - node.setGraphic(graphic); - return node; } - private void getFilesNeeded(CheckBoxTreeItem node, String basePath, List list) { + private void getFilesNeeded(ModpackFileTreeItem node, String basePath, List list) { if (node == null) return; if (node.isSelected() || node.isIndeterminate()) { if (basePath.length() > "minecraft/".length()) list.add(StringUtils.substringAfter(basePath, "minecraft/")); for (TreeItem child : node.getChildren()) { - if (child instanceof CheckBoxTreeItem) { - getFilesNeeded(((CheckBoxTreeItem) child), basePath + "/" + child.getValue(), list); + if (child instanceof ModpackFileTreeItem mChild) { + getFilesNeeded(mChild, basePath + "/" + mChild.getFileName(), list); } } } @@ -221,4 +200,40 @@ public String getTitle() { pair("minecraft/blueprints", i18n("modpack.files.blueprints")), pair("minecraft/scripts", i18n("modpack.files.scripts")) ); + + private static final class ModpackFileTreeItem extends CheckBoxTreeItem { + + private final String fileName; + + public ModpackFileTreeItem(String fileName, String basePath) { + this.fileName = fileName; + + HBox graphic = new HBox(); + JFXCheckBox checkBox = new JFXCheckBox(); + checkBox.selectedProperty().bindBidirectional(this.selectedProperty()); + checkBox.indeterminateProperty().bindBidirectional(this.indeterminateProperty()); + graphic.getChildren().add(checkBox); + + { + Label text = new Label(fileName); + text.setMouseTransparent(true); + graphic.getChildren().add(text); + } + if (TRANSLATION.containsKey(basePath)) { + Label comment = new Label(TRANSLATION.get(basePath)); + comment.setStyle("-fx-text-fill: -monet-on-surface-variant;"); + comment.setMouseTransparent(true); + graphic.getChildren().add(comment); + } + graphic.setPickOnBounds(false); + this.setExpanded("minecraft".equals(basePath)); + this.setValue(""); // To disable the default display of text + this.setGraphic(graphic); + } + + public String getFileName() { + return fileName; + } + + } } From c4b30c4e9017891e1a19dce26c633cb3e135cc77 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Mon, 18 May 2026 22:25:14 +0800 Subject: [PATCH 7/9] update --- .../hmcl/ui/export/ModpackFileSelectionPage.java | 6 +++++- .../main/java/org/jackhuang/hmcl/util/io/FileUtils.java | 8 -------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java index d0fca5d4205..b90c6bb76c0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java @@ -33,6 +33,7 @@ import org.jackhuang.hmcl.ui.construct.NoneMultipleSelectionModel; import org.jackhuang.hmcl.ui.wizard.WizardController; import org.jackhuang.hmcl.ui.wizard.WizardPage; +import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.SettingsMap; import org.jackhuang.hmcl.util.StringUtils; import org.jackhuang.hmcl.util.io.FileUtils; @@ -128,7 +129,10 @@ private ModpackFileTreeItem getTreeItem(Path file, String basePath, int level) { if (isDirectory) { try (var stream = Files.list(file)) { - stream.sorted(FileUtils.dirFirstComparator).forEach(it -> { + stream.map(path -> Pair.pair(path, Files.isDirectory(path))).sorted((p1, p2) -> { + if (p1.value() == p2.value()) return p1.key().compareTo(p2.key()); + return p1.value() ? -1 : 1; + }).map(Pair::key).forEach(it -> { ModpackFileTreeItem subNode = getTreeItem(it, basePath + "/" + FileUtils.getName(it), level + 1); if (subNode != null) { node.setSelected(subNode.isSelected() || node.isSelected()); 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 b91cf42c263..bce609927db 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 @@ -49,14 +49,6 @@ public final class FileUtils { private FileUtils() { } - public static final Comparator dirFirstComparator = (p1, p2) -> { - if (p1 == null) return p2 == null ? 0 : -1; - if (p2 == null) return 1; - if (!p1.getParent().equals(p2.getParent())) return p1.compareTo(p2); - if (Files.isDirectory(p1) == Files.isDirectory(p2)) return p1.compareTo(p2); - return Files.isDirectory(p1) ? -1 : 1; - }; - public static @Nullable Path toPath(@Nullable File file) { try { return file != null ? file.toPath() : null; From e13e1a662792301e3a610f3e801ede064a235572 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Thu, 21 May 2026 20:12:43 +0800 Subject: [PATCH 8/9] Update HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java index b90c6bb76c0..2e86e0ca6db 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/export/ModpackFileSelectionPage.java @@ -130,7 +130,7 @@ private ModpackFileTreeItem getTreeItem(Path file, String basePath, int level) { if (isDirectory) { try (var stream = Files.list(file)) { stream.map(path -> Pair.pair(path, Files.isDirectory(path))).sorted((p1, p2) -> { - if (p1.value() == p2.value()) return p1.key().compareTo(p2.key()); + if (p1.value() == p2.value()) return FileUtils.getName(p1.key()).compareToIgnoreCase(FileUtils.getName(p2.key())); return p1.value() ? -1 : 1; }).map(Pair::key).forEach(it -> { ModpackFileTreeItem subNode = getTreeItem(it, basePath + "/" + FileUtils.getName(it), level + 1); From 9943f386f5c797e7855184763cb1629eafbd29c8 Mon Sep 17 00:00:00 2001 From: ToobLac Date: Fri, 22 May 2026 22:23:00 +0800 Subject: [PATCH 9/9] update --- .../org/jackhuang/hmcl/mod/ModAdviser.java | 23 +++---------------- .../java/org/jackhuang/hmcl/mod/Modpack.java | 16 ++----------- .../org/jackhuang/hmcl/util/io/FileUtils.java | 18 +++++++++++++++ 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java index 28c31d959e5..bc4dce5d607 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/ModAdviser.java @@ -18,6 +18,7 @@ package org.jackhuang.hmcl.mod; import org.jackhuang.hmcl.util.Lang; +import org.jackhuang.hmcl.util.io.FileUtils; import java.util.List; @@ -76,29 +77,11 @@ enum ModSuggestion { "mods/VoxelMods"); static ModAdviser.ModSuggestion suggestMod(String fileName, boolean isDirectory) { - if (match(MODPACK_BLACK_LIST, fileName, isDirectory)) + if (FileUtils.match(MODPACK_BLACK_LIST, fileName, isDirectory)) return ModAdviser.ModSuggestion.HIDDEN; - if (match(MODPACK_SUGGESTED_BLACK_LIST, fileName, isDirectory)) + if (FileUtils.match(MODPACK_SUGGESTED_BLACK_LIST, fileName, isDirectory)) return ModAdviser.ModSuggestion.NORMAL; else return ModAdviser.ModSuggestion.SUGGESTED; } - - /// @param fileName "fileName/" for directories and "fileName" for files, regardless of the operating system - static boolean match(List l, String fileName, boolean isDirectory) { - for (String s : l) - if (isDirectory) { - if (fileName.startsWith(s + '/')) - return true; - } else { - if (s.startsWith("regex:")) { - if (fileName.matches(s.substring("regex:".length()))) - return true; - } else { - if (fileName.equals(s)) - return true; - } - } - return false; - } } diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java index 5fe755ee80e..7d876ded372 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/mod/Modpack.java @@ -19,6 +19,7 @@ import org.jackhuang.hmcl.download.DefaultDependencyManager; import org.jackhuang.hmcl.task.Task; +import org.jackhuang.hmcl.util.io.FileUtils; import java.nio.charset.Charset; import java.nio.file.Path; @@ -121,23 +122,10 @@ public Modpack setManifest(ModpackManifest manifest) { public abstract Task getInstallTask(DefaultDependencyManager dependencyManager, Path zipFile, String name, String iconUrl); - private static boolean match(List l, String fileName) { - for (String s : l) { - if (s.startsWith("regex:")) { - if (fileName.matches(s.substring("regex:".length()))) - return true; - } else { - if (fileName.equals(s)) - return true; - } - } - return false; - } - public static boolean acceptFile(String path, List blackList, List whiteList) { if (path.isEmpty()) return true; - if (match(blackList, path)) + if (FileUtils.match(blackList, path, false)) return false; if (whiteList == null || whiteList.isEmpty()) return true; 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 93718aaedb6..8a4fb5a0126 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 @@ -563,4 +563,22 @@ public static EnumSet parsePosixFilePermission(int unixMode return permissions; } + + /// @param fileName must be "fileName/" for directories or "fileName" for files, regardless of the operating system + public static boolean match(List l, String fileName, boolean isDirectory) { + for (String s : l) + if (isDirectory) { + if (fileName.startsWith(s + '/')) + return true; + } else { + if (s.startsWith("regex:")) { + if (fileName.matches(s.substring("regex:".length()))) + return true; + } else { + if (fileName.equals(s)) + return true; + } + } + return false; + } }