mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-13 05:46:59 -04:00
feat: show migration hint when 410. Closes #1045.
This commit is contained in:
parent
0b2e9c3f62
commit
37cee9cebd
@ -340,14 +340,21 @@ public final class Accounts {
|
|||||||
RemoteAuthenticationException remoteException = (RemoteAuthenticationException) exception;
|
RemoteAuthenticationException remoteException = (RemoteAuthenticationException) exception;
|
||||||
String remoteMessage = remoteException.getRemoteMessage();
|
String remoteMessage = remoteException.getRemoteMessage();
|
||||||
if ("ForbiddenOperationException".equals(remoteException.getRemoteName()) && remoteMessage != null) {
|
if ("ForbiddenOperationException".equals(remoteException.getRemoteName()) && remoteMessage != null) {
|
||||||
if (remoteMessage.contains("Invalid credentials"))
|
if (remoteMessage.contains("Invalid credentials")) {
|
||||||
return i18n("account.failed.invalid_credentials");
|
return i18n("account.failed.invalid_credentials");
|
||||||
else if (remoteMessage.contains("Invalid token"))
|
} else if (remoteMessage.contains("Invalid token")) {
|
||||||
return i18n("account.failed.invalid_token");
|
return i18n("account.failed.invalid_token");
|
||||||
else if (remoteMessage.contains("Invalid username or password"))
|
} else if (remoteMessage.contains("Invalid username or password")) {
|
||||||
return i18n("account.failed.invalid_password");
|
return i18n("account.failed.invalid_password");
|
||||||
else
|
} else {
|
||||||
return remoteMessage;
|
return remoteMessage;
|
||||||
|
}
|
||||||
|
} else if ("ResourceException".equals(remoteException.getRemoteName()) && remoteMessage != null) {
|
||||||
|
if (remoteMessage.contains("The requested resource is no longer available")) {
|
||||||
|
return i18n("account.failed.migration");
|
||||||
|
} else {
|
||||||
|
return remoteMessage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return exception.getMessage();
|
return exception.getMessage();
|
||||||
} else if (exception instanceof AuthlibInjectorDownloadException) {
|
} else if (exception instanceof AuthlibInjectorDownloadException) {
|
||||||
|
@ -17,50 +17,106 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.account;
|
package org.jackhuang.hmcl.ui.account;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXButton;
|
||||||
|
import com.jfoenix.controls.JFXDialogLayout;
|
||||||
import com.jfoenix.controls.JFXPasswordField;
|
import com.jfoenix.controls.JFXPasswordField;
|
||||||
import com.jfoenix.controls.JFXProgressBar;
|
import com.jfoenix.controls.JFXProgressBar;
|
||||||
import javafx.fxml.FXML;
|
import javafx.geometry.Insets;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
import org.jackhuang.hmcl.auth.Account;
|
import org.jackhuang.hmcl.auth.Account;
|
||||||
import org.jackhuang.hmcl.auth.AuthInfo;
|
import org.jackhuang.hmcl.auth.AuthInfo;
|
||||||
import org.jackhuang.hmcl.auth.NoSelectedCharacterException;
|
import org.jackhuang.hmcl.auth.NoSelectedCharacterException;
|
||||||
|
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccount;
|
||||||
|
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccount;
|
||||||
|
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
|
||||||
import org.jackhuang.hmcl.setting.Accounts;
|
import org.jackhuang.hmcl.setting.Accounts;
|
||||||
import org.jackhuang.hmcl.task.Schedulers;
|
import org.jackhuang.hmcl.task.Schedulers;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
import org.jackhuang.hmcl.ui.construct.DialogCloseEvent;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.JFXHyperlink;
|
||||||
|
import org.jackhuang.hmcl.ui.construct.RequiredValidator;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
import static org.jackhuang.hmcl.ui.FXUtils.onEscPressed;
|
||||||
import static org.jackhuang.hmcl.util.Logging.LOG;
|
import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||||
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
public class AccountLoginPane extends StackPane {
|
public class AccountLoginPane extends StackPane {
|
||||||
private final Account oldAccount;
|
private final Account oldAccount;
|
||||||
private final Consumer<AuthInfo> success;
|
private final Consumer<AuthInfo> success;
|
||||||
private final Runnable failed;
|
private final Runnable failed;
|
||||||
|
|
||||||
@FXML private Label lblUsername;
|
private final JFXPasswordField txtPassword;
|
||||||
@FXML private JFXPasswordField txtPassword;
|
private final Label lblCreationWarning = new Label();
|
||||||
@FXML private Label lblCreationWarning;
|
private final JFXProgressBar progressBar;
|
||||||
@FXML private JFXProgressBar progressBar;
|
|
||||||
|
|
||||||
public AccountLoginPane(Account oldAccount, Consumer<AuthInfo> success, Runnable failed) {
|
public AccountLoginPane(Account oldAccount, Consumer<AuthInfo> success, Runnable failed) {
|
||||||
this.oldAccount = oldAccount;
|
this.oldAccount = oldAccount;
|
||||||
this.success = success;
|
this.success = success;
|
||||||
this.failed = failed;
|
this.failed = failed;
|
||||||
|
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/account-login.fxml");
|
progressBar = new JFXProgressBar();
|
||||||
|
StackPane.setAlignment(progressBar, Pos.TOP_CENTER);
|
||||||
|
progressBar.setVisible(false);
|
||||||
|
|
||||||
lblUsername.setText(oldAccount.getUsername());
|
JFXDialogLayout dialogLayout = new JFXDialogLayout();
|
||||||
txtPassword.setOnAction(e -> onAccept());
|
|
||||||
|
{
|
||||||
|
dialogLayout.setHeading(new Label(i18n("login.enter_password")));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
VBox body = new VBox(15);
|
||||||
|
body.setPadding(new Insets(15, 0, 0, 0));
|
||||||
|
|
||||||
|
Label usernameLabel = new Label(oldAccount.getUsername());
|
||||||
|
|
||||||
|
txtPassword = new JFXPasswordField();
|
||||||
|
txtPassword.setOnAction(e -> onAccept());
|
||||||
|
txtPassword.getValidators().add(new RequiredValidator());
|
||||||
|
txtPassword.setLabelFloat(true);
|
||||||
|
txtPassword.setPromptText(i18n("account.password"));
|
||||||
|
|
||||||
|
body.getChildren().setAll(usernameLabel, txtPassword);
|
||||||
|
|
||||||
|
if (oldAccount instanceof YggdrasilAccount && !(oldAccount instanceof AuthlibInjectorAccount)) {
|
||||||
|
HBox linkPane = new HBox(8);
|
||||||
|
body.getChildren().add(linkPane);
|
||||||
|
|
||||||
|
JFXHyperlink migrationLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration"));
|
||||||
|
migrationLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PROFILE_URL));
|
||||||
|
|
||||||
|
JFXHyperlink migrationHowLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration.how"));
|
||||||
|
migrationHowLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.MIGRATION_FAQ_URL));
|
||||||
|
|
||||||
|
linkPane.getChildren().setAll(migrationLink, migrationLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialogLayout.setBody(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
JFXButton acceptButton = new JFXButton(i18n("button.ok"));
|
||||||
|
acceptButton.setOnAction(e -> onAccept());
|
||||||
|
acceptButton.getStyleClass().add("dialog-accept");
|
||||||
|
|
||||||
|
JFXButton cancelButton = new JFXButton(i18n("button.cancel"));
|
||||||
|
cancelButton.setOnAction(e -> onCancel());
|
||||||
|
cancelButton.getStyleClass().add("dialog-cancel");
|
||||||
|
|
||||||
|
dialogLayout.setActions(lblCreationWarning, acceptButton, cancelButton);
|
||||||
|
}
|
||||||
|
|
||||||
onEscPressed(this, this::onCancel);
|
onEscPressed(this, this::onCancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
private void onAccept() {
|
private void onAccept() {
|
||||||
String password = txtPassword.getText();
|
String password = txtPassword.getText();
|
||||||
progressBar.setVisible(true);
|
progressBar.setVisible(true);
|
||||||
@ -81,7 +137,6 @@ public class AccountLoginPane extends StackPane {
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
private void onCancel() {
|
private void onCancel() {
|
||||||
failed.run();
|
failed.run();
|
||||||
fireEvent(new DialogCloseEvent());
|
fireEvent(new DialogCloseEvent());
|
||||||
|
@ -277,7 +277,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
JFXHyperlink profileLink = new JFXHyperlink(i18n("account.methods.microsoft.profile"));
|
JFXHyperlink profileLink = new JFXHyperlink(i18n("account.methods.microsoft.profile"));
|
||||||
profileLink.setOnAction(e -> FXUtils.openLink("https://account.live.com/editprof.aspx"));
|
profileLink.setOnAction(e -> FXUtils.openLink("https://account.live.com/editprof.aspx"));
|
||||||
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
||||||
purchaseLink.setOnAction(e -> FXUtils.openLink("https://www.minecraft.net/zh-hans/store/minecraft-java-edition"));
|
purchaseLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PURCHASE_URL));
|
||||||
box.getChildren().setAll(profileLink, birthLink, purchaseLink);
|
box.getChildren().setAll(profileLink, birthLink, purchaseLink);
|
||||||
GridPane.setColumnSpan(box, 2);
|
GridPane.setColumnSpan(box, 2);
|
||||||
|
|
||||||
@ -418,13 +418,17 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
if (factory instanceof YggdrasilAccountFactory) {
|
if (factory instanceof YggdrasilAccountFactory) {
|
||||||
HBox box = new HBox();
|
HBox box = new HBox();
|
||||||
GridPane.setColumnSpan(box, 2);
|
GridPane.setColumnSpan(box, 2);
|
||||||
|
|
||||||
JFXHyperlink migrationLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration"));
|
JFXHyperlink migrationLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration"));
|
||||||
migrationLink.setOnAction(e -> FXUtils.openLink("https://help.minecraft.net/hc/en-us/articles/360050865492-JAVA-Account-Migration-FAQ"));
|
migrationLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PROFILE_URL));
|
||||||
|
|
||||||
|
JFXHyperlink migrationHowLink = new JFXHyperlink(i18n("account.methods.yggdrasil.migration.how"));
|
||||||
|
migrationHowLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.MIGRATION_FAQ_URL));
|
||||||
|
|
||||||
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
||||||
purchaseLink.setOnAction(e -> FXUtils.openLink("https://www.minecraft.net/zh-hans/store/minecraft-java-edition"));
|
purchaseLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PURCHASE_URL));
|
||||||
|
|
||||||
box.getChildren().setAll(migrationLink, purchaseLink);
|
box.getChildren().setAll(migrationLink, migrationHowLink, purchaseLink);
|
||||||
add(box, 0, rowIndex);
|
add(box, 0, rowIndex);
|
||||||
|
|
||||||
rowIndex++;
|
rowIndex++;
|
||||||
@ -432,7 +436,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
|
|
||||||
if (factory instanceof OfflineAccountFactory) {
|
if (factory instanceof OfflineAccountFactory) {
|
||||||
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
JFXHyperlink purchaseLink = new JFXHyperlink(i18n("account.methods.yggdrasil.purchase"));
|
||||||
purchaseLink.setOnAction(e -> FXUtils.openLink("https://www.minecraft.net/zh-hans/store/minecraft-java-edition"));
|
purchaseLink.setOnAction(e -> FXUtils.openLink(YggdrasilService.PURCHASE_URL));
|
||||||
HBox linkPane = new HBox(purchaseLink);
|
HBox linkPane = new HBox(purchaseLink);
|
||||||
GridPane.setColumnSpan(linkPane, 2);
|
GridPane.setColumnSpan(linkPane, 2);
|
||||||
add(linkPane, 0, rowIndex);
|
add(linkPane, 0, rowIndex);
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<?import com.jfoenix.controls.*?>
|
|
||||||
<?import com.jfoenix.validation.RequiredFieldValidator?>
|
|
||||||
<?import javafx.scene.control.Label?>
|
|
||||||
<?import javafx.scene.layout.StackPane?>
|
|
||||||
<?import javafx.scene.layout.VBox?>
|
|
||||||
<fx:root xmlns="http://javafx.com/javafx"
|
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
|
||||||
type="StackPane">
|
|
||||||
<JFXDialogLayout>
|
|
||||||
<heading>
|
|
||||||
<Label text="%login.enter_password" />
|
|
||||||
</heading>
|
|
||||||
<body>
|
|
||||||
<VBox spacing="15" style="-fx-padding: 15 0 0 0;">
|
|
||||||
<Label fx:id="lblUsername" />
|
|
||||||
<JFXPasswordField fx:id="txtPassword" promptText="%account.password" labelFloat="true">
|
|
||||||
<validators>
|
|
||||||
<RequiredFieldValidator message="Input Required!">
|
|
||||||
</RequiredFieldValidator>
|
|
||||||
</validators>
|
|
||||||
</JFXPasswordField>
|
|
||||||
</VBox>
|
|
||||||
</body>
|
|
||||||
<actions>
|
|
||||||
<Label fx:id="lblCreationWarning" />
|
|
||||||
<JFXButton onMouseClicked="#onAccept" text="%button.ok" styleClass="dialog-accept"/>
|
|
||||||
<JFXButton onMouseClicked="#onCancel" text="%button.cancel" styleClass="dialog-cancel"/>
|
|
||||||
</actions>
|
|
||||||
</JFXDialogLayout>
|
|
||||||
<JFXProgressBar fx:id="progressBar" visible="false" StackPane.alignment="TOP_CENTER"/>
|
|
||||||
</fx:root>
|
|
@ -61,6 +61,7 @@ account.failed.injector_download_failure=Failed to download authlib-injector. Ch
|
|||||||
account.failed.invalid_credentials=Incorrect password, or you are forbidden to login temporarily.
|
account.failed.invalid_credentials=Incorrect password, or you are forbidden to login temporarily.
|
||||||
account.failed.invalid_password=Invalid password
|
account.failed.invalid_password=Invalid password
|
||||||
account.failed.invalid_token=Please log out and re-enter your password to login.
|
account.failed.invalid_token=Please log out and re-enter your password to login.
|
||||||
|
account.failed.migration=Your account needs to be migrated to a Microsoft account. If already migrated, you should login your migrated Microsoft account instead.
|
||||||
account.failed.no_character=No character in this account.
|
account.failed.no_character=No character in this account.
|
||||||
account.failed.server_response_malformed=Invalid server response. The authentication server may have an error.
|
account.failed.server_response_malformed=Invalid server response. The authentication server may have an error.
|
||||||
account.injector.add=Add an authentication server
|
account.injector.add=Add an authentication server
|
||||||
@ -96,7 +97,8 @@ account.methods.offline.uuid=UUID
|
|||||||
account.methods.offline.uuid.hint=UUID is the unique identifier to the game character in Minecraft. The way that UUID is generated varies from different game launchers. Changing UUID to the one generated by other launcher would promise that game blocks/items in the backpack of your offline account remain. This option is for expert. Unless you know what you are doing, we do not suggest you to change this option.
|
account.methods.offline.uuid.hint=UUID is the unique identifier to the game character in Minecraft. The way that UUID is generated varies from different game launchers. Changing UUID to the one generated by other launcher would promise that game blocks/items in the backpack of your offline account remain. This option is for expert. Unless you know what you are doing, we do not suggest you to change this option.
|
||||||
account.methods.offline.uuid.malformed=Malformed
|
account.methods.offline.uuid.malformed=Malformed
|
||||||
account.methods.yggdrasil=Mojang
|
account.methods.yggdrasil=Mojang
|
||||||
account.methods.yggdrasil.migration=How to migrate to Microsoft Account?
|
account.methods.yggdrasil.migration=Migrate to Microsoft Account
|
||||||
|
account.methods.yggdrasil.migration.how=How to migrate to Microsoft Account?
|
||||||
account.methods.yggdrasil.purchase=Purchase Minecraft
|
account.methods.yggdrasil.purchase=Purchase Minecraft
|
||||||
account.missing=No Account
|
account.missing=No Account
|
||||||
account.missing.add=Click here to add
|
account.missing.add=Click here to add
|
||||||
|
@ -61,6 +61,7 @@ account.failed.injector_download_failure=無法下載 authlib-injector,請檢
|
|||||||
account.failed.invalid_credentials=您的使用者名稱或密碼錯誤,或者登入次數過多被暫時禁止登入,請稍後再試
|
account.failed.invalid_credentials=您的使用者名稱或密碼錯誤,或者登入次數過多被暫時禁止登入,請稍後再試
|
||||||
account.failed.invalid_password=密碼無效
|
account.failed.invalid_password=密碼無效
|
||||||
account.failed.invalid_token=請嘗試登出並重新輸入密碼登入
|
account.failed.invalid_token=請嘗試登出並重新輸入密碼登入
|
||||||
|
account.failed.migration=你的帳號需要被遷移至微軟帳號。如果你已經遷移,你需要使用微軟登錄方式登錄遷移後的微軟帳號。
|
||||||
account.failed.no_character=該帳戶沒有角色
|
account.failed.no_character=該帳戶沒有角色
|
||||||
account.failed.server_response_malformed=無法解析認證伺服器回應,可能是伺服器故障
|
account.failed.server_response_malformed=無法解析認證伺服器回應,可能是伺服器故障
|
||||||
account.injector.add=新增認證伺服器
|
account.injector.add=新增認證伺服器
|
||||||
@ -96,7 +97,8 @@ account.methods.offline.uuid=UUID
|
|||||||
account.methods.offline.uuid.hint=UUID 是 Minecraft 對玩家角色的唯一標識符,每個啟動器生成 UUID 的方式可能不同。通過修改 UUID 選項至原啟動器所生成的 UUID,你可以保證在切換啟動器後,遊戲還能將你的遊戲角色識別為給定 UUID 所對應的角色,從而保留原來角色的背包物品。UUID 選項為高級選項,除非你知道你在做什麼,否則你不需要調整該選項。
|
account.methods.offline.uuid.hint=UUID 是 Minecraft 對玩家角色的唯一標識符,每個啟動器生成 UUID 的方式可能不同。通過修改 UUID 選項至原啟動器所生成的 UUID,你可以保證在切換啟動器後,遊戲還能將你的遊戲角色識別為給定 UUID 所對應的角色,從而保留原來角色的背包物品。UUID 選項為高級選項,除非你知道你在做什麼,否則你不需要調整該選項。
|
||||||
account.methods.offline.uuid.malformed=格式錯誤
|
account.methods.offline.uuid.malformed=格式錯誤
|
||||||
account.methods.yggdrasil=正版登入
|
account.methods.yggdrasil=正版登入
|
||||||
account.methods.yggdrasil.migration=如何遷移至微軟帳戶?
|
account.methods.yggdrasil.migration=遷移至微軟帳戶
|
||||||
|
account.methods.yggdrasil.migration.how=如何遷移至微軟帳戶?
|
||||||
account.methods.yggdrasil.purchase=購買 Minecraft
|
account.methods.yggdrasil.purchase=購買 Minecraft
|
||||||
account.missing=沒有遊戲帳戶
|
account.missing=沒有遊戲帳戶
|
||||||
account.missing.add=按一下此處加入帳戶
|
account.missing.add=按一下此處加入帳戶
|
||||||
|
@ -61,6 +61,7 @@ account.failed.injector_download_failure=无法下载 authlib-injector,请检
|
|||||||
account.failed.invalid_credentials=您的用户名或密码错误,或者登录次数过多被暂时禁止登录,请稍后再试
|
account.failed.invalid_credentials=您的用户名或密码错误,或者登录次数过多被暂时禁止登录,请稍后再试
|
||||||
account.failed.invalid_password=无效的密码
|
account.failed.invalid_password=无效的密码
|
||||||
account.failed.invalid_token=请尝试登出并重新输入密码登录
|
account.failed.invalid_token=请尝试登出并重新输入密码登录
|
||||||
|
account.failed.migration=你的帐号需要被迁移至微软帐号。如果你已经迁移,你需要使用微软登录方式登录迁移后的微软帐号。
|
||||||
account.failed.no_character=该帐号没有角色
|
account.failed.no_character=该帐号没有角色
|
||||||
account.failed.server_response_malformed=无法解析认证服务器响应,可能是服务器故障
|
account.failed.server_response_malformed=无法解析认证服务器响应,可能是服务器故障
|
||||||
account.injector.add=添加认证服务器
|
account.injector.add=添加认证服务器
|
||||||
@ -96,7 +97,8 @@ account.methods.offline.uuid=UUID
|
|||||||
account.methods.offline.uuid.hint=UUID 是 Minecraft 对玩家角色的唯一标识符,每个启动器生成 UUID 的方式可能不同。通过修改 UUID 选项至原启动器所生成的 UUID,你可以保证在切换启动器后,游戏还能将你的游戏角色识别为给定 UUID 所对应的角色,从而保留原来角色的背包物品。UUID 选项为高级选项,除非你知道你在做什么,否则你不需要调整该选项。
|
account.methods.offline.uuid.hint=UUID 是 Minecraft 对玩家角色的唯一标识符,每个启动器生成 UUID 的方式可能不同。通过修改 UUID 选项至原启动器所生成的 UUID,你可以保证在切换启动器后,游戏还能将你的游戏角色识别为给定 UUID 所对应的角色,从而保留原来角色的背包物品。UUID 选项为高级选项,除非你知道你在做什么,否则你不需要调整该选项。
|
||||||
account.methods.offline.uuid.malformed=格式错误
|
account.methods.offline.uuid.malformed=格式错误
|
||||||
account.methods.yggdrasil=Mojang 帐户
|
account.methods.yggdrasil=Mojang 帐户
|
||||||
account.methods.yggdrasil.migration=如何迁移至微软帐户?
|
account.methods.yggdrasil.migration=迁移至微软账户
|
||||||
|
account.methods.yggdrasil.migration.how=如何迁移至微软帐户?
|
||||||
account.methods.yggdrasil.purchase=购买 Minecraft
|
account.methods.yggdrasil.purchase=购买 Minecraft
|
||||||
account.missing=没有游戏帐户
|
account.missing=没有游戏帐户
|
||||||
account.missing.add=点击此处添加帐户
|
account.missing.add=点击此处添加帐户
|
||||||
|
@ -272,4 +272,7 @@ public class YggdrasilService {
|
|||||||
.registerTypeAdapterFactory(ValidationTypeAdapterFactory.INSTANCE)
|
.registerTypeAdapterFactory(ValidationTypeAdapterFactory.INSTANCE)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
|
public static final String PROFILE_URL = "https://www.minecraft.net/profile";
|
||||||
|
public static final String MIGRATION_FAQ_URL = "https://help.minecraft.net/hc/en-us/articles/360050865492-JAVA-Account-Migration-FAQ";
|
||||||
|
public static final String PURCHASE_URL = "https://www.minecraft.net/zh-hans/store/minecraft-java-edition";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user