Skip to content

Conversation

@deepsleep-v3
Copy link

@deepsleep-v3 deepsleep-v3 commented Jan 19, 2026

  1. “Switch Working Directory

先讲一个小故事,我电脑之前C:空间太少,重装系统了,资料被format了,我转移了我的MC资料到我的U盘。但!我没转移我的hmcl.json,所以,VersionSetting也无了。到最后,我启动MC的时候,资源包、模组都丢了,一看,没开“各版本隔离”,于是,deepsleep-v3像是下定了某种决心,他马上就fork了HMCL-dev/HMCL,并且clone到他的电脑……

所以我就把这个弹窗做出来了,由于个人精力原因,暂只翻译了en_US、zh-Hant、zh-CN。原理是HMCLGameLauncher生成options.txt的函数(generateOptionsTxt)里getRunDirectory()时先检测repository是否instanceof HMCLGameRepository,再创建变量,再检测:

Files.exists(Path.of(HMCLRepository.getVersionRoot(version.getId()).toString(), "resourcepacks")) ||
Files.exists(Path.of(HMCLRepository.getVersionRoot(version.getId()).toString(), "saves")) ||
Files.exists(Path.of(HMCLRepository.getVersionRoot(version.getId()).toString(), "mods")) ||
Files.exists(Path.of(HMCLRepository.getVersionRoot(version.getId()).toString(), "shaderpacks")) || 
Files.exists(Path.of(HMCLRepository.getVersionRoot(version.getId()).toString(), "crash-report"))

(代码写的有点烂,请见谅😳)

Added a confirmation dialog when unexpected folders (resourcepacks, saves, mods, shaderpacks, crash-report) are detected in the version root, prompting the user to switch to 'Isolated' mode. Updated I18N.properties with new dialog strings for this feature.
Replaces manual string concatenation with Path.of() using varargs for directory checks in the ROOT_FOLDER case, improving code readability and reliability.
Added logic to process the user's selection from the working directory switch alert dialog, updating the game directory type or returning the appropriate directory based on the chosen button.
## 问题描述
在后台线程中直接调用JavaFX的Alert组件会导致`IllegalStateException: Not on FX application thread`异常,影响程序稳定性。

## 修改内容
- 将原有的直接Alert调用包装在`Platform.runLater()`中,确保UI操作在JavaFX应用程序线程执行
- 使用`CompletableFuture`在JavaFX线程和非JavaFX线程之间传递用户选择结果
- 保持原有的业务逻辑和对话框选项不变
- 添加异常处理,在对话框异常时使用默认值继续执行

## 技术细节
1. 创建`CompletableFuture<ButtonData>`用于接收用户选择
2. 在`Platform.runLater()`中:
   - 创建Confirmation类型的Alert对话框
   - 设置三个按钮选项:是、否、仅本次启动
   - 使用`showAndWait()`等待用户响应
   - 将用户选择的按钮数据传递给CompletableFuture
3. 在后台线程中使用`future.get()`阻塞等待用户选择
4. 根据按钮数据执行相应的目录设置逻辑

## 影响范围
- 修复启动器在非JavaFX线程中询问工作目录切换的问题
- 确保线程安全的同时保持原有功能不变
- 提升程序在多线程环境下的稳定性

## 测试要点
✅ 在后台线程中调用此代码段能正常显示对话框
✅ 对话框的三个按钮功能与之前一致
✅ 异常情况下能使用默认值继续执行
✅ 不会出现线程阻塞或死锁问题

## 关联问题
修复了在多线程环境下可能导致的UI崩溃问题
@deepsleep-v3 deepsleep-v3 changed the title 为HMCL启动时添加“Switch Working Directory”并修复文档的一些语法错误 feat+fix:为HMCL启动时添加“Switch Working Directory”并修复文档的一些语法错误 Jan 19, 2026
Copy link
Member

@burningtnt burningtnt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

粗略的(在没有真正看代码逻辑的情况下)看了一眼,我认为你这里有一堆问题需要改动。

此外,简体中文和繁体中文的翻译是必须的。如果你不能熟练使用繁体中文,可使用机器翻译提供初稿,并注明需要社区成员在 PR 合并前检查润色。

@deepsleep-v3
Copy link
Author

粗略的(在没有真正看代码逻辑的情况下)看了一眼,我认为你这里有一堆问题需要改动。

此外,简体中文和繁体中文的翻译是必须的。如果你不能熟练使用繁体中文,可使用机器翻译提供初稿,并注明需要社区成员在 PR 合并前检查润色。

√ 已解决

Copy link
Contributor

@3gf8jv4dv 3gf8jv4dv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

说实话,这个弹窗不是太美观,也不适配深色模式。可否改成下面列出的 PR 中更新的形式?

Copy link
Member

@burningtnt burningtnt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

显然你关闭了根本没解决的问题。此外,如果你不了解相关语言,请不要翻译非完全支持语言(比如日语)

deepsleep-v3 and others added 9 commits January 20, 2026 08:06
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
@3gf8jv4dv
Copy link
Contributor

3gf8jv4dv commented Jan 21, 2026

几点意见:

你可以在你的 fork 里创建一个分支 (以上游最新 main 分支为基础),把你发现的语法错误在那个分支里改了,再发个 PR。这样 Glavo 可以马上把那个简单的 PR 合了,而不是放在这里拖着。同时建议之后一个 PR 专注于一件事情,尽量不要搞大杂烩。

此外,由于目前你是通过 fork 的 main 分支提交本 PR,所以尽量不要误操作 (如同步上游/删除 fork),这会导致你的 PR 变乱或被 GitHub 关闭。同时建议之后的 PR 专门开一个分支来提交。

回到 PR 本身。现在的对话框中,「OK (确定)」和「Cancel (取消)」容易造成歧义,且在聚焦于对话框时按 Esc 会触发游戏启动流程 (即「This launch only (仅本次启动/僅限本次啟動)」的作用)。这与一般用户的认知和习惯不符。

注:点击图片可放大。
Image

所以,希望按钮能够重新分类为四个:

  1. Yes (是) — 更改版本隔离设置为「各实例独立」并启动游戏
  2. No (否) — 不更改版本隔离设置并启动游戏
  3. This launch only (仅本次启动/僅限本次啟動) — 这个应该不言自明
  4. Cancel (取消) — 不更改任何设置,也不启动游戏

Edited: 订正一些描述。

@deepsleep-v3
Copy link
Author

几点意见:

你可以在你的 fork 里创建一个分支 (以上游最新 main 分支为基础),把你发现的语法错误在那个分支里改了,再发个 PR。这样 Glavo 可以马上把那个简单的 PR 合了,而不是放在这里拖着。同时建议之后一个 PR 专注于一件事情,尽量不要搞大杂烩。

此外,由于目前你是通过 fork 的 main 分支提交本 PR,所以尽量不要误操作 (如同步上游/删除 fork),这会导致你的 PR 变乱或被 GitHub 关闭。同时建议之后的 PR 专门开一个分支来提交。

回到 PR 本身。现在的对话框中,「OK (确定)」和「Cancel (取消)」容易造成歧义,且在聚焦于对话框时按 Esc 会触发游戏启动流程 (即「This launch only (仅本次启动/僅限本次啟動)」的作用)。这与一般用户的认知和习惯不符。

注:点击图片可放大。 Image

所以,希望按钮能够重新分类为四个:

  1. Yes (是) — 更改版本隔离设置为「各实例独立」并启动游戏
  2. No (否) — 不更改版本隔离设置并启动游戏
  3. This launch only (仅本次启动/僅限本次啟動) — 这个应该不言自明
  4. Cancel (取消) — 不更改任何设置,也不启动游戏

Edited: 订正一些描述。

OK在改

import org.jackhuang.hmcl.util.platform.ManagedProcess;
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;

import java.awt.*;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HMCL 在正常加载时不应使用 AWT

@deepsleep-v3 deepsleep-v3 requested a review from CiiLu January 24, 2026 09:38
@deepsleep-v3 deepsleep-v3 changed the title feat+fix:为HMCL启动时添加“Switch Working Directory”并修复文档的一些语法错误 feat+fix:为HMCL启动时添加“Instance files detected” Jan 24, 2026
@burningtnt
Copy link
Member

如果我们能有 99% 的把握认为用户应当开启版本隔离,我们可以使用非侵入性式的 Toast 提醒用户,不必迫使用户做出决定。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants