diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java index 434b739b6f..40faa018ca 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java @@ -21,17 +21,27 @@ import org.jackhuang.hmcl.auth.AuthInfo; import org.jackhuang.hmcl.launch.DefaultLauncher; import org.jackhuang.hmcl.launch.ProcessListener; +import org.jackhuang.hmcl.ui.Controllers; +import org.jackhuang.hmcl.ui.FXUtils; +import org.jackhuang.hmcl.ui.construct.MessageDialogPane; import org.jackhuang.hmcl.util.i18n.LocaleUtils; import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.platform.ManagedProcess; import org.jackhuang.hmcl.util.versioning.GameVersionNumber; +import java.io.File; import java.io.IOException; -import java.nio.file.*; -import java.util.*; +import java.nio.file.FileVisitOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.stream.Stream; import static org.jackhuang.hmcl.setting.ConfigHolder.config; +import static org.jackhuang.hmcl.util.i18n.I18n.i18n; import static org.jackhuang.hmcl.util.logging.Logger.LOG; /** @@ -62,8 +72,16 @@ protected Map getConfigurations() { private void generateOptionsTxt() { if (config().isDisableAutoGameOptions()) return; - Path runDir = repository.getRunDirectory(version.getId()); + HMCLGameRepository repository = (HMCLGameRepository) this.repository; + if (repository.getGameDirectoryType(version.getId()) == GameDirectoryType.ROOT_FOLDER) { + Path versionRoot = repository.getVersionRoot(version.getId()); + String[] subdirs = {"resourcepacks", "saves", "mods", "shaderpacks", "crash-report"}; + + if (Arrays.stream(subdirs).anyMatch(dir -> Files.exists(versionRoot.resolve(dir)))) { + runDir = switchWorkingDirectory(repository, version); + } + } Path optionsFile = runDir.resolve("options.txt"); Path configFolder = runDir.resolve("config"); @@ -88,7 +106,7 @@ private void generateOptionsTxt() { * 1.11 ~ 1.12 : zh_cn works fine, zh_CN will display Chinese but the language setting will incorrectly show English as selected * 1.13+ : zh_cn works fine, zh_CN will automatically switch to English */ - GameVersionNumber gameVersion = GameVersionNumber.asGameVersion(repository.getGameVersion(version)); + GameVersionNumber gameVersion = GameVersionNumber.asGameVersion(this.repository.getGameVersion(version)); if (gameVersion.compareTo("1.1") < 0) return; @@ -107,6 +125,32 @@ private void generateOptionsTxt() { } } + private Path switchWorkingDirectory(HMCLGameRepository repository, Version version) { + CompletableFuture future = new CompletableFuture<>(); + + var dialog = new MessageDialogPane.Builder( + i18n("launcher.info.switch_working_directory.content", File.separatorChar, version.getId()), + i18n("launcher.info.switch_working_directory.title"), MessageDialogPane.MessageType.QUESTION) + .yesOrNo(() -> { + repository.getVersionSetting(version.getId()).setGameDirType(GameDirectoryType.VERSION_FOLDER); + future.complete(repository.getVersionRoot(version.getId())); + }, () -> { + future.complete(repository.getBaseDirectory()); + }).addCancel(i18n("Dialog.this_launch_only.button"), () -> { + future.complete(repository.getVersionRoot(version.getId())); + }) + .addCancel(() -> { + // TODO: Cancel all the task of Launch Minecraft + }).build(); + FXUtils.runInFX(() -> Controllers.dialog(dialog)); + + try { + return future.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + private static String normalizedLanguageTag(Locale locale, GameVersionNumber gameVersion) { String region = locale.getCountry(); diff --git a/HMCL/src/main/resources/assets/lang/I18N.properties b/HMCL/src/main/resources/assets/lang/I18N.properties index b0f28fcb58..af0432257d 100644 --- a/HMCL/src/main/resources/assets/lang/I18N.properties +++ b/HMCL/src/main/resources/assets/lang/I18N.properties @@ -376,6 +376,8 @@ download.speed.byte_per_second=%d B/s download.speed.kibibyte_per_second=%.1f KiB/s download.speed.megabyte_per_second=%.1f MiB/s +Dialog.this_launch_only.button=This launch only + exception.access_denied=HMCL is unable to access the file "%s". It may be locked by another process.\n\ \n\ For Windows users, you can open "Resource Monitor" to check if another process is currently using it. If so, you can try again after terminating that process.\n\ @@ -829,6 +831,7 @@ launch.state.modpack=Downloading required files launch.state.waiting_launching=Waiting for the game to launch launch.invalid_java=Invalid Java path. Please reset the Java path. + launcher=Launcher launcher.agreement=ToS and EULA launcher.agreement.accept=Accept @@ -852,6 +855,9 @@ launcher.crash=Hello Minecraft! Launcher has encountered a fatal error! Please c launcher.crash.java_internal_error=Hello Minecraft! Launcher has encountered a fatal error because your Java is corrupted. Please uninstall your Java and download a suitable Java here. launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher has encountered a fatal error! Your launcher is outdated. Please update your launcher! launcher.update_java=Please update your Java version. +launcher.info.switch_working_directory.title=Instance files detected +# %1$s = java.io.File.separator, %2$s = version root (Don't ends with java.io.File.separator) +launcher.info.switch_working_directory.content=Existing game files were detected in ".minecraft%1$sversions%1$s%2$s", but the Working Directory is currently set to "Default".\n\nTo use these files, the setting in "Game Settings → Working Directory" should be "Isolated". Would you like to switch to Isolated mode? libraries.download=Downloading Libraries diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh.properties b/HMCL/src/main/resources/assets/lang/I18N_zh.properties index 7066f0d73a..2a9acff3a8 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh.properties @@ -367,6 +367,8 @@ download.speed.byte_per_second=%d B/s download.speed.kibibyte_per_second=%.1f KiB/s download.speed.megabyte_per_second=%.1f MiB/s +Dialog.this_launch_only.button=僅限本次啟動 + exception.access_denied=無法存取檔案「%s」。因為 HMCL 沒有對該檔案的訪問權限,或者該檔案已被其他程式開啟。\n\ 請你檢查目前作業系統帳戶是否能訪存取檔案,比如非管理員使用者可能不能訪問其他帳戶的個人目錄內的檔案。\n\ 對於 Windows 使用者,你還可以嘗試透過資源監視器查看是否有程式占用了該檔案。如果是,你可以關閉占用此檔案的程式,或者重啟電腦再試。 @@ -651,6 +653,9 @@ launcher.crash=Hello Minecraft! Launcher 遇到了無法處理的錯誤。請複 launcher.crash.java_internal_error=Hello Minecraft! Launcher 由於目前 Java 損壞而無法繼續執行。請移除目前 Java,點擊 此處 安裝合適的 Java 版本。 launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher 遇到了無法處理的錯誤。已偵測到你的啟動器不是最新版本,請更新後重試! launcher.update_java=請更新你的 Java +launcher.info.switch_working_directory.title=偵測到實例檔案 +# %1$s = java.io.File.separator, %2$s = version root (Don't ends with java.io.File.separator) +launcher.info.switch_working_directory.content=在「.minecraft%1$sversions%1$s%2$s」中偵測到既有遊戲檔案,但目前執行路徑設定為「預設」。\n\n要使用這些檔案,請在「(全域/實例特定) 遊戲設定 → 執行路徑」中選取「各實例獨立」。你是否要切換到「各實例獨立」模式? libraries.download=下載依賴庫 diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 7bcaf8ce54..ea2ba69403 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -369,6 +369,8 @@ download.speed.byte_per_second=%d B/s download.speed.kibibyte_per_second=%.1f KiB/s download.speed.megabyte_per_second=%.1f MiB/s +Dialog.this_launch_only.button=仅本次启动 + exception.access_denied=无法访问文件“%s”。HMCL 没有对该文件的访问权限,或者该文件已被其他程序打开。\n\ 请你检查当前操作系统账户是否能访问该文件,比如非管理员用户可能无法访问其他账户的个人文件夹内的文件。\n\ 对于 Windows 用户,你还可以尝试通过资源监视器查看是否有程序占用了该文件。如果是,请关闭占用该文件的程序,或者重启电脑再试。\n\ @@ -655,6 +657,9 @@ launcher.crash=Hello Minecraft! Launcher 遇到了无法处理的错误。请复 launcher.crash.java_internal_error=Hello Minecraft! Launcher 由于当前 Java 损坏而无法继续运行。请卸载当前 Java,点击 此处 安装合适的 Java 版本。 launcher.crash.hmcl_out_dated=Hello Minecraft! Launcher 遇到了无法处理的错误。已检测到你的启动器不是最新版本,请更新后再试。 launcher.update_java=请更新你的 Java。\n你可以访问 https://docs.hmcl.net/help.html 页面寻求帮助。 +launcher.info.switch_working_directory.title=检测到实例文件 +# %1$s = java.io.File.separator, %2$s = version root (Don't ends with java.io.File.separator) +launcher.info.switch_working_directory.content=在“.minecraft%1$sversions%1$s%2$s”中检测到既有游戏文件,但目前“版本隔离”设置为“默认”。\n\n要使用这些文件,请在“(全局/实例特定) 游戏设置 → 版本隔离”中选择“各实例独立”。\n\n你是否要切换到“各实例独立”模式? libraries.download=下载依赖库 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java index dacf26181b..2e40e59609 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/game/LaunchOptions.java @@ -90,7 +90,7 @@ public String getVersionName() { } /** - * Will shown in the left bottom corner of the main menu of Minecraft. + * Will be shown in the left bottom corner of the main menu of Minecraft. * null if use Version.versionType. */ public String getVersionType() {