Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 73 additions & 7 deletions HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
*/
package org.jackhuang.hmcl.game;

import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.auth.AuthInfo;
import org.jackhuang.hmcl.launch.DefaultLauncher;
Expand All @@ -26,12 +30,16 @@
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.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
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;

/**
Expand Down Expand Up @@ -62,8 +70,18 @@ protected Map<String, String> getConfigurations() {
private void generateOptionsTxt() {
if (config().isDisableAutoGameOptions())
return;

Path runDir = repository.getRunDirectory(version.getId());
HMCLGameRepository HMCLRepository = (HMCLGameRepository) repository;
if (HMCLRepository.getGameDirectoryType(version.getId()) == GameDirectoryType.ROOT_FOLDER) {
if (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"))
) {
runDir = switchWorkingDirectory(HMCLRepository, version);
}
}
Path optionsFile = runDir.resolve("options.txt");
Path configFolder = runDir.resolve("config");

Expand All @@ -82,12 +100,12 @@ private void generateOptionsTxt() {
Locale locale = Locale.getDefault();

/*
* 1.0 : No language option, do not set for these versions
* 1.1 ~ 1.5 : zh_CN works fine, zh_cn will crash (the last two letters must be uppercase, otherwise it will cause an NPE crash)
* 1.6 ~ 1.10 : zh_CN works fine, zh_cn will automatically switch to English
* 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
*/
* 1.0 : No language option, do not set for these versions
* 1.1 ~ 1.5 : zh_CN works fine, zh_cn will crash (the last two letters must be uppercase, otherwise it will cause an NPE crash)
* 1.6 ~ 1.10 : zh_CN works fine, zh_cn will automatically switch to English
* 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));
if (gameVersion.compareTo("1.1") < 0)
return;
Expand All @@ -107,6 +125,54 @@ private void generateOptionsTxt() {
}
}

private Path switchWorkingDirectory(HMCLGameRepository HMCLRepository, Version version) {
if (Platform.isFxApplicationThread()) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION,
String.format(i18n("launcher.info.switch_working_directory.content"), File.separatorChar, version.getId()),
ButtonType.YES, ButtonType.NO, new ButtonType(i18n("Dialog.this_launch_only.button"), ButtonBar.ButtonData.APPLY)
);
alert.setTitle(i18n("launcher.info.switch_working_directory.title"));
switch (alert.showAndWait().orElse(ButtonType.YES).getButtonData()) {
case YES -> {
HMCLRepository.getVersionSetting(version.getId()).setGameDirType(GameDirectoryType.VERSION_FOLDER);
return HMCLRepository.getVersionRoot(version.getId());
}
case NO -> { return HMCLRepository.getBaseDirectory(); }
case APPLY -> HMCLRepository.getVersionRoot(version.getId());
default -> { return HMCLRepository.getBaseDirectory(); }
}
} else {
CompletableFuture<ButtonBar.ButtonData> buttonDataFuture = new CompletableFuture<>();

Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION,
String.format(i18n("launcher.info.switch_working_directory.content"), File.separatorChar, version.getId()),
ButtonType.YES, ButtonType.NO, new ButtonType(i18n("Dialog.this_launch_only.button"), ButtonBar.ButtonData.APPLY)
);
alert.setTitle(i18n("launcher.info.switch_working_directory.title"));
buttonDataFuture.complete(alert.showAndWait().orElse(ButtonType.YES).getButtonData());
});

ButtonBar.ButtonData result;
try {
result = buttonDataFuture.get();
} catch (InterruptedException | ExecutionException e) {
result = ButtonBar.ButtonData.YES;
}

switch (result) {
case YES -> {
HMCLRepository.getVersionSetting(version.getId()).setGameDirType(GameDirectoryType.VERSION_FOLDER);
return HMCLRepository.getVersionRoot(version.getId());
}
case NO -> { return HMCLRepository.getBaseDirectory(); }
case APPLY -> HMCLRepository.getVersionRoot(version.getId());
default -> { return HMCLRepository.getBaseDirectory(); }
}
}
return HMCLRepository.getVersionRoot(version.getId());
}

private static String normalizedLanguageTag(Locale locale, GameVersionNumber gameVersion) {
String region = locale.getCountry();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ private void loadLocalVersionSetting(String id) {
VersionSetting versionSetting = JsonUtils.fromJsonFile(file, VersionSetting.class);
initLocalVersionSetting(id, versionSetting);
} catch (Exception ex) {
// If [JsonParseException], [IOException] or [NullPointerException] happens, the json file is malformed and needed to be recreated.
// If [JsonParseException], [IOException] or [NullPointerException] happens, the JSON file is malformed and needed to be recreated.
initLocalVersionSetting(id, new VersionSetting());
}
}
Expand Down Expand Up @@ -231,7 +231,7 @@ private VersionSetting initLocalVersionSetting(String id, VersionSetting vs) {
* Get the version setting for version id.
*
* @param id version id
* @return corresponding version setting, null if the version has no its own version setting.
* @return corresponding version setting, null if the version does not have its own version setting.
*/
@Nullable
public VersionSetting getLocalVersionSetting(String id) {
Expand Down
6 changes: 6 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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\
Expand Down Expand Up @@ -827,6 +829,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
Expand All @@ -850,6 +853,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 <a href="https://bell-sw.com/pages/downloads/#downloads">here</a>.
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=Would you like to switch the Working Directory?
# %1$s = java.io.File.separator, %2$s = version root (Don't ends with java.io.File.separator)
launcher.info.switch_working_directory.content=We detected unexpected content in .minecraft%1$sversions%1$s%2$s. It's likely you selected "Isolated" mode, but it was switched to "Default" mode automatically or manually. The choice to readjust to "Isolated" mode is available to you.\nRe-adjust to 'Isolated' mode and make it effective for this launch, press "Yes". if you want to retain current version settings, press "No". if you want make it effective for this launch only, press "This launch only".

libraries.download=Downloading Libraries

Expand Down
5 changes: 5 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_ja.properties
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ download.javafx.notes=ネットワークを介したHMCLに必要なコンポー
download.javafx.component=ダウンロード中のモジュール %s
download.javafx.prepare=ダウンロードする準備ができました

Dialog.this_launch_only.button=今回のみ

exception.access_denied=ファイル %s にアクセスできないので、HMCL がファイルにアクセスできないか、ファイルが他のプログラムによって開かれています。\n\
例えば、管理者でないユーザーは、他のアカウントの個人フォルダーにあるファイルにアクセスできない場合があります。\n\
Windowsユーザーの場合、リソースモニターでプログラムがファイルを占有しているかどうかを確認し、もしそうなら、このファイルを占有している関連プログラムを閉じるか、コンピュータを再起動して、もう一度試してみることも可能です。
Expand Down Expand Up @@ -539,6 +541,9 @@ launcher.contact=お問い合わせ
launcher.crash=Hello Minecraft!ランチャーがクラッシュしました!次のコンテンツをコピーして、MCBBS、Baidu Tieba、GitHub、またはMinecraftForumを介してフィードバックを送信してください。
launcher.crash.hmcl_out_dated=Hello Minecraft!ランチャーがクラッシュしました!ランチャーが古くなっています。ランチャーを更新してください!
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「隔離」モードに再調整し、今回の起動で有効にするには「はい」を、現在のバージョン設定を維持するには「いいえ」を、今回の起動のみに有効にするには「今回のみ」を押してください。

login.empty_username=ユーザー名を設定していません!
login.enter_password=パスワードを入力してください。
Expand Down
5 changes: 5 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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 使用者,你還可以嘗試透過資源監視器查看是否有程式占用了該檔案。如果是,你可以關閉占用此檔案的程式,或者重啟電腦再試。
Expand Down Expand Up @@ -649,6 +651,9 @@ launcher.crash=Hello Minecraft! Launcher 遇到了無法處理的錯誤。請複
launcher.crash.java_internal_error=Hello Minecraft! Launcher 由於目前 Java 損壞而無法繼續執行。請移除目前 Java,點擊 <a href="https://bell-sw.com/pages/downloads/#downloads">此處</a> 安裝合適的 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若想重新調整為「隔離」模式並在本次啟動中生效,請按「是」;若想保留目前版本設定,請按「否」;若想僅對本次啟動生效,請按「僅本次啟動」。

libraries.download=下載依賴庫

Expand Down
5 changes: 5 additions & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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\
Expand Down Expand Up @@ -653,6 +655,9 @@ launcher.crash=Hello Minecraft! Launcher 遇到了无法处理的错误。请复
launcher.crash.java_internal_error=Hello Minecraft! Launcher 由于当前 Java 损坏而无法继续运行。请卸载当前 Java,点击 <a href="https://bell-sw.com/pages/downloads/#downloads">此处</a> 安装合适的 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若想重新调整为“隔离”模式并在本次启动中生效,请按“是”;若想保留当前版本设置,请按“否”;若想仅对本次启动生效,请按“仅本次启动”。

libraries.download=下载依赖库

Expand Down