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
17 changes: 16 additions & 1 deletion HMCL/src/main/java/org/jackhuang/hmcl/game/OAuthServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@

import java.io.IOException;
import java.security.SecureRandom;
import java.util.*;
import java.util.Base64;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

Expand Down Expand Up @@ -172,6 +175,7 @@ public void close() {

public static class Factory implements OAuth.Callback {
public final EventManager<GrantDeviceCodeEvent> onGrantDeviceCode = new EventManager<>();
public final EventManager<LoginCompletedDeviceCodeEvent> onLoginCompletedDeviceCode = new EventManager<>();
public final EventManager<OpenBrowserEvent> onOpenBrowserAuthorizationCode = new EventManager<>();
public final EventManager<OpenBrowserEvent> onOpenBrowserDevice = new EventManager<>();

Expand Down Expand Up @@ -199,6 +203,11 @@ public void grantDeviceCode(String userCode, String verificationURI) {
onGrantDeviceCode.fireEvent(new GrantDeviceCodeEvent(this, userCode, verificationURI));
}

@Override
public void loginCompletedDeviceCode() {
onLoginCompletedDeviceCode.fireEvent(new LoginCompletedDeviceCodeEvent(this));
}

@Override
public void openBrowser(OAuth.GrantFlow grantFlow, String url) throws IOException {
lastlyOpenedURL = url;
Expand Down Expand Up @@ -235,6 +244,12 @@ public String getVerificationUri() {
}
}

public static class LoginCompletedDeviceCodeEvent extends Event {
public LoginCompletedDeviceCodeEvent(Object source) {
super(source);
}
}

public static class OpenBrowserEvent extends Event {
private final String url;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ public MicrosoftAccountLoginPane(Account account, Consumer<AuthInfo> callback, R
step.set(new Step.WaitForScanQrCode(event.getUserCode(), event.getVerificationUri()));
}));

holder.registerWeak(Accounts.OAUTH_CALLBACK.onLoginCompletedDeviceCode, event -> Platform.runLater(() -> {
if (step.get() instanceof Step.WaitForScanQrCode)
step.set(new Step.DeviceLoginCompleted());
}));

this.step.set(Accounts.OAUTH_CALLBACK.getClientId().isEmpty()
? new Step.Init()
: new Step.StartAuthorizationCodeLogin());
Expand Down Expand Up @@ -220,6 +225,13 @@ private void onStep(Step currentStep) {
codeBox.setMaxWidth(USE_PREF_SIZE);

rootContainer.getChildren().addAll(deviceHint, new Group(qrCode), codeBox);
} else if (currentStep instanceof Step.DeviceLoginCompleted) {
loginButtonSpinner.setLoading(true);

var hintPane = new HintPane(MessageDialogPane.MessageType.INFO);
hintPane.setSegment(i18n("account.methods.microsoft.methods.device.hint.completed"));

rootContainer.getChildren().addAll(hintPane);
} else if (currentStep instanceof Step.LoginFailed failed) {
btnLogin.setOnAction(e -> this.step.set(new Step.StartAuthorizationCodeLogin()));
loginButtonSpinner.setLoading(false);
Expand Down Expand Up @@ -312,6 +324,10 @@ record WaitForScanQrCode(String userCode, String verificationUri) implements Ste

}

record DeviceLoginCompleted() implements Step {

}

record LoginFailed(String message) implements Step {
}
}
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ 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.methods.device=Log In with QR Code
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.completed=Microsoft account authorization is now completed. There are some extra works for us, just wait for a while.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

英文翻译中的 "extra works" 存在语法错误("work" 在此处作为不可数名词)。建议使用更地道的表达方式。

account.methods.microsoft.methods.device.hint.completed=Microsoft account authorization is now complete. We are finishing the login process, please wait a moment.

account.methods.microsoft.methods.browser=Log In via Browser
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.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>
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ account.methods.microsoft.makegameidsettings=建立檔案 / 編輯檔案名稱
account.methods.microsoft.hint=點擊「登入」按鈕開始新增 Microsoft 帳戶。
account.methods.microsoft.methods.device=掃描 QR Code 登入
account.methods.microsoft.methods.device.hint=掃描 QR Code 或訪問 <a href="%s">%s</a>,在開啟的頁面中輸入 <b>%s</b> 完成登入。
account.methods.microsoft.methods.device.hint.completed=已完成微软帳戶授權。其余登入步驟將由啟動器自動執行,请稍等。
Copy link
Copy Markdown
Contributor

@3gf8jv4dv 3gf8jv4dv May 13, 2026

Choose a reason for hiding this comment

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

Suggested change
account.methods.microsoft.methods.device.hint.completed=已完成微软帳戶授權。其余登入步驟將由啟動器自動執行,请稍等
account.methods.microsoft.methods.device.hint.completed=已完成 Microsoft 帳戶授權。其餘登入步驟將由啟動器自動執行,請稍候

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

繁体中文资源文件 (I18N_zh.properties) 中混入了简体中文汉字(“微软”、“其余”、“请”)。为了保持一致性,建议将其转换为繁体中文,并参考同文件其他条目(如第 122 行)将“微软”统一为 “Microsoft”。

account.methods.microsoft.methods.device.hint.completed=已完成 Microsoft 帳戶授權。其餘登入步驟將由啟動器自動執行,請稍等。

account.methods.microsoft.methods.browser=在瀏覽器中登入
account.methods.microsoft.methods.browser.hint=點擊「登入」按鈕或者<a href="%s">複製連結</a>並在瀏覽器中貼上以登入。
account.methods.microsoft.manual=<b>若網路環境不佳,可能會導致網頁載入緩慢甚至無法載入,請稍後再試或更換網路環境後再試。</b>
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ account.methods.microsoft.makegameidsettings=创建档案 / 编辑档案名称
account.methods.microsoft.hint=点击“登录”按钮开始添加微软账户。
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.completed=已完成微软账户授权。其余登录步骤将由启动器自动执行,请稍等。
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
account.methods.microsoft.methods.device.hint.completed=已完成微软账户授权。其余登录步骤将由启动器自动执行,请稍等
account.methods.microsoft.methods.device.hint.completed=已完成微软账户授权。其余登录步骤将由启动器自动执行,请稍候

account.methods.microsoft.methods.browser=在浏览器登录
account.methods.microsoft.methods.browser.hint=点击“登录”按钮或者<a href="%s">复制链接</a>并在浏览器中粘贴以登录。
account.methods.microsoft.manual=<b>若网络环境不佳,可能会导致网页加载缓慢甚至无法加载,请使用网络代理并重试。</b>\n\
Expand Down
4 changes: 4 additions & 0 deletions HMCLCore/src/main/java/org/jackhuang/hmcl/auth/OAuth.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ private Result authenticateDevice(Options options) throws IOException, Interrupt
continue;
}

options.callback.loginCompletedDeviceCode();

return new Result(tokenResponse.accessToken, tokenResponse.refreshToken);
}
}
Expand Down Expand Up @@ -268,6 +270,8 @@ public interface Callback {

void grantDeviceCode(String userCode, String verificationURI);

void loginCompletedDeviceCode();

/**
* Open browser
*
Expand Down