更新微软账户登录对话框 (#5531)

This commit is contained in:
Glavo
2026-02-14 20:38:07 +08:00
committed by GitHub
parent b0cd184e22
commit eea072cea5
17 changed files with 267 additions and 242 deletions

View File

@@ -60,6 +60,7 @@ dependencies {
implementation(libs.twelvemonkeys.imageio.webp) implementation(libs.twelvemonkeys.imageio.webp)
implementation(libs.java.info) implementation(libs.java.info)
implementation(libs.monet.fx) implementation(libs.monet.fx)
implementation(libs.nayuki.qrcodegen)
if (launcherExe.isBlank()) { if (launcherExe.isBlank()) {
implementation(libs.hmclauncher) implementation(libs.hmclauncher)

View File

@@ -273,27 +273,16 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
btnAccept.disableProperty().unbind(); btnAccept.disableProperty().unbind();
detailsContainer.getChildren().remove(detailsPane); detailsContainer.getChildren().remove(detailsPane);
lblErrorMessage.setText(""); lblErrorMessage.setText("");
lblErrorMessage.setVisible(true); setActions(lblErrorMessage, actions);
actions.setVisible(true);
actions.setManaged(true);
} }
if (factory == Accounts.FACTORY_MICROSOFT) { if (factory == Accounts.FACTORY_MICROSOFT) {
VBox vbox = new VBox(8); detailsPane = new MicrosoftAccountLoginPane(true);
detailsPane = vbox; setActions();
HintPane hintPane = new HintPane(MessageDialogPane.MessageType.INFO);
hintPane.setText(i18n("account.methods.microsoft.hint"));
vbox.getChildren().addAll(new MicrosoftAccountLoginPane(true));
btnAccept.setOnAction(e -> {
fireEvent(new DialogCloseEvent());
Controllers.dialog(new MicrosoftAccountLoginPane());
});
actions.setManaged(false);
actions.setVisible(false);
btnAccept.setDisable(false);
} else { } else {
detailsPane = new AccountDetailsInputPane(factory, btnAccept::fire); detailsPane = new AccountDetailsInputPane(factory, btnAccept::fire);
btnAccept.disableProperty().bind(((AccountDetailsInputPane) detailsPane).validProperty().not()); btnAccept.disableProperty().bind(((AccountDetailsInputPane) detailsPane).validProperty().not());
setActions(lblErrorMessage, actions);
} }
detailsContainer.getChildren().add(detailsPane); detailsContainer.getChildren().add(detailsPane);

File diff suppressed because one or more lines are too long

View File

@@ -30,6 +30,7 @@ import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
import java.util.Locale; import java.util.Locale;
import java.util.function.Consumer;
public class HintPane extends VBox { public class HintPane extends VBox {
private final Text label = new Text(); private final Text label = new Text();
@@ -66,7 +67,11 @@ public class HintPane extends VBox {
} }
public void setSegment(String segment) { public void setSegment(String segment) {
flow.getChildren().setAll(FXUtils.parseSegment(segment, Controllers::onHyperlinkAction)); this.setSegment(segment, Controllers::onHyperlinkAction);
}
public void setSegment(String segment, Consumer<String> hyperlinkAction) {
flow.getChildren().setAll(FXUtils.parseSegment(segment, hyperlinkAction));
} }
public void setChildren(Node... children) { public void setChildren(Node... children) {

View File

@@ -0,0 +1,48 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2026 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.util;
import io.nayuki.qrcodegen.QrCode;
/// @author Glavo
public final class QrCodeUtils {
public static String toSVGPath(QrCode qr) {
return toSVGPath(qr, 0);
}
public static String toSVGPath(QrCode qr, int border) {
int actualSize = qr.size + border * 2;
var builder = new StringBuilder(qr.size * qr.size * 12);
builder.append('M').append(actualSize).append(' ').append(actualSize).append("ZM0 0Z");
for (int y = 0; y < qr.size; y++) {
for (int x = 0; x < qr.size; x++) {
if (qr.getModule(x, y)) {
if (x != 0 || y != 0)
builder.append(' ');
builder.append("M").append(x + border).append(',').append(y + border).append("h1v1h-1z");
}
}
}
return builder.toString();
}
private QrCodeUtils() {
}
}

View File

@@ -578,6 +578,10 @@
* * * *
******************************************************************************/ ******************************************************************************/
.microsoft-login-dialog:bodyonly {
-fx-padding: 0px 0px 0px 0px;
}
.method-title { .method-title {
-fx-text-fill: -monet-on-surface; -fx-text-fill: -monet-on-surface;
-fx-font-weight: bold; -fx-font-weight: bold;
@@ -594,6 +598,7 @@
.code-box { .code-box {
-fx-background-color: -monet-surface-variant; -fx-background-color: -monet-surface-variant;
-fx-background-radius: 6; -fx-background-radius: 6;
-fx-padding: 0 10 0 10;
-fx-alignment: center; -fx-alignment: center;
} }

View File

@@ -118,13 +118,10 @@ account.methods.microsoft.error.wrong_verify_method=Failed to log in. Please try
account.methods.microsoft.logging_in=Logging in... account.methods.microsoft.logging_in=Logging in...
account.methods.microsoft.makegameidsettings=Create Profile / Edit Profile Name account.methods.microsoft.makegameidsettings=Create Profile / Edit Profile Name
account.methods.microsoft.hint=Click the "Log in" button to start adding your Microsoft account. account.methods.microsoft.hint=Click the "Log in" button to start adding your Microsoft account.
account.methods.microsoft.methods.or=Or account.methods.microsoft.methods.device=Log In with QR Code
account.methods.microsoft.methods.device=Log in on another device account.methods.microsoft.methods.device.hint=Scan QR code or visit <a href="%s">%s</a> to complete login, enter <b>%s</b> in the opened page.
account.methods.microsoft.methods.device.hint=Scan the QR code on another device, or visit \n %s \n to complete log in account.methods.microsoft.methods.browser=Log In via Browser
account.methods.microsoft.methods.device.copy=Copy code account.methods.microsoft.methods.browser.hint=Click the "Log in" button or <a href="%s">copy the link</a> and paste it into the browser to log in.
account.methods.microsoft.methods.browser=Log in via browser (Recommended)
account.methods.microsoft.methods.browser.copy_open=Copy link and visit in browser
account.methods.microsoft.methods.browser.hint=Click the following button to copy and open the browser to log in
account.methods.microsoft.manual=<b>If your internet connection is bad, it may cause web pages to load slowly or fail to load altogether.\nYou may try again later or switch to a different internet connection.</b> account.methods.microsoft.manual=<b>If your internet connection is bad, it may cause web pages to load slowly or fail to load altogether.\nYou may try again later or switch to a different internet connection.</b>
account.methods.microsoft.profile=Account Profile account.methods.microsoft.profile=Account Profile
account.methods.microsoft.purchase=Buy Minecraft account.methods.microsoft.purchase=Buy Minecraft
@@ -144,7 +141,6 @@ account.methods.offline.uuid.hint=UUID is a unique identifier for Minecraft play
\n\ \n\
This option is for advanced users only. We do not recommend changing this option unless you know what you are doing. This option is for advanced users only. We do not recommend changing this option unless you know what you are doing.
account.methods.offline.uuid.malformed=Invalid format. account.methods.offline.uuid.malformed=Invalid format.
account.methods.forgot_password=Forgot Password
account.methods.ban_query=Ban Query account.methods.ban_query=Ban Query
account.missing=No Accounts account.missing=No Accounts
account.missing.add=Click here to add one. account.missing.add=Click here to add one.

View File

@@ -120,7 +120,6 @@ account.methods.offline.uuid.hint=UUID هو معرف فريد للاعبي Minec
\n\ \n\
هذا الخيار للمستخدمين المتقدمين فقط. لا نوصي بتغيير هذا الخيار ما لم تعرف ما تفعله. هذا الخيار للمستخدمين المتقدمين فقط. لا نوصي بتغيير هذا الخيار ما لم تعرف ما تفعله.
account.methods.offline.uuid.malformed=تنسيق غير صالح. account.methods.offline.uuid.malformed=تنسيق غير صالح.
account.methods.forgot_password=نسيت كلمة المرور
account.methods.ban_query=استعلام الحظر account.methods.ban_query=استعلام الحظر
account.missing=لا توجد حسابات account.missing=لا توجد حسابات
account.missing.add=انقر هنا لإضافة واحد. account.missing.add=انقر هنا لإضافة واحد.

View File

@@ -123,7 +123,6 @@ account.methods.offline.uuid.hint=UUID es un identificador único para los jugad
\n\ \n\
Esta opción es sólo para usuarios avanzados. No recomendamos editar esta opción a menos que sepas lo que estás haciendo. Esta opción es sólo para usuarios avanzados. No recomendamos editar esta opción a menos que sepas lo que estás haciendo.
account.methods.offline.uuid.malformed=Formato no válido. account.methods.offline.uuid.malformed=Formato no válido.
account.methods.forgot_password=Olvidé mi contraseña
account.methods.ban_query=Consulta de bloqueo de cuentas account.methods.ban_query=Consulta de bloqueo de cuentas
account.missing=No hay cuentas account.missing=No hay cuentas
account.missing.add=Haga clic aquí para añadir una. account.missing.add=Haga clic aquí para añadir una.

View File

@@ -91,7 +91,6 @@ account.methods.microsoft.birth=誕生日の設定を編集する方法...
account.methods.microsoft.deauthorize=アカウントのバインドを解除 account.methods.microsoft.deauthorize=アカウントのバインドを解除
account.methods.microsoft.close_page=Microsoftアカウントの認証が終了しました。後で終了するログイン手順がいくつか残っています。このページを今すぐ閉じることができます。 account.methods.microsoft.close_page=Microsoftアカウントの認証が終了しました。後で終了するログイン手順がいくつか残っています。このページを今すぐ閉じることができます。
account.methods.microsoft.logging_in=ログイン... account.methods.microsoft.logging_in=ログイン...
account.methods.forgot_password=パスワードをお忘れの方
account.methods.microsoft.makegameidsettings=プロファイルを作成/プロフィール名を編集する account.methods.microsoft.makegameidsettings=プロファイルを作成/プロフィール名を編集する
account.methods.microsoft.profile=アカウントプロファイル.. account.methods.microsoft.profile=アカウントプロファイル..
account.methods.microsoft.purchase=Minecraftを購入する account.methods.microsoft.purchase=Minecraftを購入する

View File

@@ -110,7 +110,6 @@ account.methods.microsoft.logging_in=方登入……
account.methods.microsoft.makegameidsettings=添檔 / 書檔之名 account.methods.microsoft.makegameidsettings=添檔 / 書檔之名
account.methods.microsoft.profile=纂戶簿訊息 account.methods.microsoft.profile=纂戶簿訊息
account.methods.microsoft.purchase=買礦藝 account.methods.microsoft.purchase=買礦藝
account.methods.forgot_password=亡符節
account.methods.ban_query=檢戶簿羈否 account.methods.ban_query=檢戶簿羈否
account.methods.microsoft.snapshot.website=官網 account.methods.microsoft.snapshot.website=官網
account.methods.offline=離綫之式 account.methods.offline=離綫之式

View File

@@ -122,7 +122,6 @@ account.methods.offline.name.invalid=Для имени пользователя
account.methods.offline.uuid=UUID account.methods.offline.uuid=UUID
account.methods.offline.uuid.hint=UUID - это уникальный идентификатор игрового персонажа в Minecraft. Способ генерации UUID различается в разных лаунчерах игр. Изменение UUID на тот, который генерируется другим лаунчером гарантирует, что игровые блоки/предметы в рюкзаке вашего офлайн аккаунта останутся. Этот параметр предназначен для экспертов. Если вы не знаете что делаете, мы не советуем вам изменять этот параметр. Эта опция не требуется для присоединения к серверам. account.methods.offline.uuid.hint=UUID - это уникальный идентификатор игрового персонажа в Minecraft. Способ генерации UUID различается в разных лаунчерах игр. Изменение UUID на тот, который генерируется другим лаунчером гарантирует, что игровые блоки/предметы в рюкзаке вашего офлайн аккаунта останутся. Этот параметр предназначен для экспертов. Если вы не знаете что делаете, мы не советуем вам изменять этот параметр. Эта опция не требуется для присоединения к серверам.
account.methods.offline.uuid.malformed=Недопустимый формат. account.methods.offline.uuid.malformed=Недопустимый формат.
account.methods.forgot_password=Забыли пароль
account.methods.ban_query=Просмотреть аккаунт заблокирован account.methods.ban_query=Просмотреть аккаунт заблокирован
account.missing=Нет аккаунтов account.missing=Нет аккаунтов
account.missing.add=Нажмите здесь, чтобы добавить. account.missing.add=Нажмите здесь, чтобы добавить.

View File

@@ -120,7 +120,6 @@ account.methods.offline.uuid.hint=UUID - це унікальний іденти
\n\ \n\
Ця опція призначена лише для досвідчених користувачів. Ми не рекомендуємо змінювати цю опцію, якщо ви не знаєте, що робите. Ця опція призначена лише для досвідчених користувачів. Ми не рекомендуємо змінювати цю опцію, якщо ви не знаєте, що робите.
account.methods.offline.uuid.malformed=Недійсний формат. account.methods.offline.uuid.malformed=Недійсний формат.
account.methods.forgot_password=Забули пароль
account.methods.ban_query=Запит блокування account.methods.ban_query=Запит блокування
account.missing=Немає облікових записів account.missing=Немає облікових записів
account.missing.add=Натисніть тут, щоб додати. account.missing.add=Натисніть тут, щоб додати.

View File

@@ -117,17 +117,13 @@ account.methods.microsoft.error.wrong_verify_method=登入失敗。請在 Micros
account.methods.microsoft.logging_in=登入中…… account.methods.microsoft.logging_in=登入中……
account.methods.microsoft.makegameidsettings=建立檔案 / 編輯檔案名稱 account.methods.microsoft.makegameidsettings=建立檔案 / 編輯檔案名稱
account.methods.microsoft.hint=點擊「登入」按鈕開始新增 Microsoft 帳戶。 account.methods.microsoft.hint=點擊「登入」按鈕開始新增 Microsoft 帳戶。
account.methods.microsoft.methods.or= account.methods.microsoft.methods.device=掃描 QR Code 登入
account.methods.microsoft.methods.device=在其他裝置登入 account.methods.microsoft.methods.device.hint=掃描 QR Code 或訪問 <a href="%s">%s</a>,在開啟的頁面中輸入 <b>%s</b> 完成登入
account.methods.microsoft.methods.device.hint=在其他裝置掃描 QR Code或開啟 \n %s \n 完成登入 account.methods.microsoft.methods.browser=在瀏覽器中登入
account.methods.microsoft.methods.device.copy=複製代碼 account.methods.microsoft.methods.browser.hint=點擊「登入」按鈕或者<a href="%s">複製連結</a>並在瀏覽器中貼上以登入。
account.methods.microsoft.methods.browser=在瀏覽器登入 (推薦)
account.methods.microsoft.methods.browser.copy_open=複製連結並在瀏覽器中開啟
account.methods.microsoft.methods.browser.hint=點擊下方按鈕複製連結並開啟瀏覽器以登入
account.methods.microsoft.manual=<b>若網路環境不佳,可能會導致網頁載入緩慢甚至無法載入,請稍後再試或更換網路環境後再試。</b> account.methods.microsoft.manual=<b>若網路環境不佳,可能會導致網頁載入緩慢甚至無法載入,請稍後再試或更換網路環境後再試。</b>
account.methods.microsoft.profile=編輯帳戶個人資訊 account.methods.microsoft.profile=編輯帳戶個人資訊
account.methods.microsoft.purchase=購買 Minecraft account.methods.microsoft.purchase=購買 Minecraft
account.methods.forgot_password=忘記密碼
account.methods.ban_query=查詢帳戶是否被封禁 account.methods.ban_query=查詢帳戶是否被封禁
account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL。請下載 <a href="https://hmcl.huangyuhui.net/download">官方版本</a> 進行登入。 account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL。請下載 <a href="https://hmcl.huangyuhui.net/download">官方版本</a> 進行登入。
account.methods.microsoft.snapshot.tooltip=你正在使用第三方提供的 HMCL。請下載官方版本來重新整理帳戶。 account.methods.microsoft.snapshot.tooltip=你正在使用第三方提供的 HMCL。請下載官方版本來重新整理帳戶。

View File

@@ -118,18 +118,14 @@ account.methods.microsoft.error.wrong_verify_method=登录失败。请在微软
account.methods.microsoft.logging_in=登录中…… account.methods.microsoft.logging_in=登录中……
account.methods.microsoft.makegameidsettings=创建档案 / 编辑档案名称 account.methods.microsoft.makegameidsettings=创建档案 / 编辑档案名称
account.methods.microsoft.hint=点击“登录”按钮开始添加微软账户。 account.methods.microsoft.hint=点击“登录”按钮开始添加微软账户。
account.methods.microsoft.methods.or= account.methods.microsoft.methods.device=扫描二维码登录
account.methods.microsoft.methods.device=在其他设备登录 account.methods.microsoft.methods.device.hint=扫描二维码或访问 <a href="%s">%s</a>,在打开的页面中输入 <b>%s</b> 完成登录
account.methods.microsoft.methods.device.hint=在其他设备扫描二维码,或打开 \n %s \n 完成登录 account.methods.microsoft.methods.browser=在浏览器登录
account.methods.microsoft.methods.device.copy=复制代码 account.methods.microsoft.methods.browser.hint=点击“登录”按钮或者<a href="%s">复制链接</a>并在浏览器中粘贴以登录。
account.methods.microsoft.methods.browser=在浏览器登录 (推荐)
account.methods.microsoft.methods.browser.copy_open=复制链接并打开浏览器
account.methods.microsoft.methods.browser.hint=点击下方按钮复制链接并打开浏览器登录
account.methods.microsoft.manual=<b>若网络环境不佳,可能会导致网页加载缓慢甚至无法加载,请使用网络代理并重试。</b>\n\ account.methods.microsoft.manual=<b>若网络环境不佳,可能会导致网页加载缓慢甚至无法加载,请使用网络代理并重试。</b>\n\
如遇到问题,你可以点击右上角帮助按钮进行求助。 如遇到问题,你可以点击右上角帮助按钮进行求助。
account.methods.microsoft.profile=编辑账户个人信息 account.methods.microsoft.profile=编辑账户个人信息
account.methods.microsoft.purchase=购买 Minecraft account.methods.microsoft.purchase=购买 Minecraft
account.methods.forgot_password=忘记密码
account.methods.ban_query=检测账户是否被封禁 account.methods.ban_query=检测账户是否被封禁
account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL。请下载 <a href="https://hmcl.huangyuhui.net/download">官方版本</a> 来登录微软账户。 account.methods.microsoft.snapshot=你正在使用第三方提供的 HMCL。请下载 <a href="https://hmcl.huangyuhui.net/download">官方版本</a> 来登录微软账户。
account.methods.microsoft.snapshot.tooltip=你正在使用第三方提供的 HMCL。请下载官方版本来刷新账户。 account.methods.microsoft.snapshot.tooltip=你正在使用第三方提供的 HMCL。请下载官方版本来刷新账户。

View File

@@ -545,6 +545,15 @@ public final class StringUtils {
return builder.toString(); return builder.toString();
} }
public static String escapeXmlAttribute(String str) {
return str
.replace("&", "&amp;")
.replace("\"", "&quot;")
.replace("<", "&lt;")
.replace(">", "&gt;")
.replace("'", "&apos;");
}
public static String repeats(char ch, int repeat) { public static String repeats(char ch, int repeat) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
for (int i = 0; i < repeat; i++) { for (int i = 0; i < repeat; i++) {

View File

@@ -19,6 +19,7 @@ java-info = "1.0"
authlib-injector = "1.2.7" authlib-injector = "1.2.7"
monet-fx = "0.4.0" monet-fx = "0.4.0"
terracotta = "0.4.2" terracotta = "0.4.2"
nayuki-qrcodegen = "1.8.0"
# testing # testing
junit = "6.0.1" junit = "6.0.1"
@@ -49,6 +50,7 @@ pci-ids = { module = "org.glavo:pci-ids", version.ref = "pci-ids" }
java-info = { module = "org.glavo:java-info", version.ref = "java-info" } java-info = { module = "org.glavo:java-info", version.ref = "java-info" }
authlib-injector = { module = "org.glavo.hmcl:authlib-injector", version.ref = "authlib-injector" } authlib-injector = { module = "org.glavo.hmcl:authlib-injector", version.ref = "authlib-injector" }
monet-fx = { module = "org.glavo:MonetFX", version.ref = "monet-fx" } monet-fx = { module = "org.glavo:MonetFX", version.ref = "monet-fx" }
nayuki-qrcodegen = { module = "io.nayuki:qrcodegen", version.ref = "nayuki-qrcodegen" }
# testing # testing
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }