From 9edfe296590f38e409d07805b536d29df029532c Mon Sep 17 00:00:00 2001 From: Burning_TNT <88144530+burningtnt@users.noreply.github.com> Date: Sat, 16 Nov 2024 23:29:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20#2969:=20=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E5=89=8D=E6=97=A5=E5=BF=97=E5=88=97=E5=87=BAmods?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E7=9A=84jar=E6=96=87=E4=BB=B6=20(#3125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Support #2969: 启动前日志列出mods目录的jar文件 * Support #2969: 启动前日志列出mods目录jar文件 * Support #2969: 启动前日志中使用字符画列出mods目录模组文件 * Support #2969: 启动前日志中使用字符画列出mods目录模组文件 * Support #2969: 启动前日志中使用字符画列出mods目录模组文件 * Support #2969: 日志列出mods目录时不再过滤文件后缀 * Support #2969: 启动时日志列出mods目录(代码优化) * Support #2969: 启动时日志列出mods目录(不再列出Zip内容) * Support #2969 * Fix: checkstyle --------- Co-authored-by: YELANDAOKONG --- .../jackhuang/hmcl/game/LauncherHelper.java | 14 ++- .../util/io/DirectoryStructurePrinter.java | 99 +++++++++++++++++++ .../org/jackhuang/hmcl/util/io/FileUtils.java | 14 +-- 3 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/DirectoryStructurePrinter.java diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java index 79205c479..e837fa1e2 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/LauncherHelper.java @@ -36,10 +36,14 @@ import org.jackhuang.hmcl.mod.ModpackProvider; import org.jackhuang.hmcl.setting.*; import org.jackhuang.hmcl.task.*; import org.jackhuang.hmcl.ui.*; -import org.jackhuang.hmcl.ui.construct.*; +import org.jackhuang.hmcl.ui.construct.DialogCloseEvent; +import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.ui.construct.MessageDialogPane.MessageType; +import org.jackhuang.hmcl.ui.construct.PromptDialogPane; +import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane; import org.jackhuang.hmcl.util.*; import org.jackhuang.hmcl.util.i18n.I18n; +import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.ResponseCodeException; import org.jackhuang.hmcl.util.platform.*; import org.jackhuang.hmcl.util.versioning.GameVersionNumber; @@ -60,9 +64,10 @@ import static javafx.application.Platform.runLater; import static javafx.application.Platform.setImplicitExit; import static org.jackhuang.hmcl.ui.FXUtils.runInFX; import static org.jackhuang.hmcl.util.Lang.resolveException; -import static org.jackhuang.hmcl.util.logging.Logger.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; -import static org.jackhuang.hmcl.util.platform.Platform.*; +import static org.jackhuang.hmcl.util.logging.Logger.LOG; +import static org.jackhuang.hmcl.util.platform.Platform.SYSTEM_PLATFORM; +import static org.jackhuang.hmcl.util.platform.Platform.isCompatibleWithX86Java; public final class LauncherHelper { @@ -178,6 +183,9 @@ public final class LauncherHelper { .thenComposeAsync(() -> logIn(account).withStage("launch.state.logging_in")) .thenComposeAsync(authInfo -> Task.supplyAsync(() -> { LaunchOptions launchOptions = repository.getLaunchOptions(selectedVersion, javaVersionRef.get(), profile.getGameDir(), javaAgents, scriptFile != null); + + LOG.info("Here's the structure of game mod directory:\n" + FileUtils.printFileStructure(repository.getModManager(selectedVersion).getModsDirectory(), 10)); + return new HMCLGameLauncher( repository, version.get(), diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/DirectoryStructurePrinter.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/DirectoryStructurePrinter.java new file mode 100644 index 000000000..a07ba372b --- /dev/null +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/io/DirectoryStructurePrinter.java @@ -0,0 +1,99 @@ +package org.jackhuang.hmcl.util.io; + +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.FileVisitor; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; + +final class DirectoryStructurePrinter { + private DirectoryStructurePrinter() { + } + + public static String list(Path path, int maxDepth) throws IOException { + StringBuilder output = new StringBuilder(128); + list(path, maxDepth, output); + output.setLength(output.length() - 1); + return output.toString(); + } + + private static void list(Path path, int maxDepth, StringBuilder output) throws IOException { + output.append("Filesystem structure of: ").append(path).append('\n'); + + if (!Files.exists(path)) { + pushMessage(output, "nonexistent path", 1); + return; + } + if (Files.isRegularFile(path)) { + pushMessage(output, "regular file path", 1); + return; + } + if (Files.isDirectory(path)) { + Files.walkFileTree(path, new FileVisitor() { + private boolean isFolderEmpty; + + private int depth = 1; + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) { + isFolderEmpty = true; + + pushFile(output, dir, depth); + if (depth == maxDepth) { + pushMessage(output, "too deep", depth); + return FileVisitResult.SKIP_SUBTREE; + } + + depth++; + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { + isFolderEmpty = false; + + pushFile(output, file, depth); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, IOException exc) { + visitFile(file, null); + + pushMessage(output, exc.toString(), depth); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) { + if (isFolderEmpty) { + pushMessage(output, "empty directory", depth); + } + + depth--; + return FileVisitResult.CONTINUE; + } + }); + return; + } + + pushMessage(output, "unknown file type", 1); + } + + private static void pushFile(StringBuilder output, Path file, int depth) { + output.append("|"); + for (int i = 1; i < depth; i++) { + output.append(" |"); + } + output.append("-> ").append(FileUtils.getName(file)).append('\n'); + } + + private static void pushMessage(StringBuilder output, String message, int depth) { + output.append("| "); + for (int i = 1; i < depth; i++) { + output.append(" | "); + } + output.append('<').append(message).append(">\n"); + } +} 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 baa444003..ba257a94c 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 @@ -30,11 +30,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.function.Predicate; import static java.nio.charset.StandardCharsets.UTF_8; @@ -199,7 +195,7 @@ public final class FileUtils { * It will create the file if it does not exist, or truncate the existing file to empty for rewriting. * All bytes in byte array will be written into the file in binary format. Existing data will be erased. * - * @param file the path to the file + * @param file the path to the file * @param data the data being written to file * @throws IOException if an I/O error occurs */ @@ -212,7 +208,7 @@ public final class FileUtils { * It will create the file if it does not exist, or truncate the existing file to empty for rewriting. * All bytes in byte array will be written into the file in binary format. Existing data will be erased. * - * @param file the path to the file + * @param file the path to the file * @param data the data being written to file * @throws IOException if an I/O error occurs */ @@ -591,4 +587,8 @@ public final class FileUtils { Files.move(tmpFile, file, StandardCopyOption.REPLACE_EXISTING); } + + public static String printFileStructure(Path path, int maxDepth) throws IOException { + return DirectoryStructurePrinter.list(path, maxDepth); + } }