mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-09 03:46:18 -04:00
feat: copy link when web browser cannot be opened.
This commit is contained in:
parent
3327899cf6
commit
98c6651793
@ -41,6 +41,8 @@ public final class MicrosoftAuthenticationServer extends NanoHTTPD implements Mi
|
|||||||
private final int port;
|
private final int port;
|
||||||
private final CompletableFuture<String> future = new CompletableFuture<>();
|
private final CompletableFuture<String> future = new CompletableFuture<>();
|
||||||
|
|
||||||
|
public static String lastlyOpenedURL;
|
||||||
|
|
||||||
private MicrosoftAuthenticationServer(int port) {
|
private MicrosoftAuthenticationServer(int port) {
|
||||||
super(port);
|
super(port);
|
||||||
|
|
||||||
@ -107,7 +109,7 @@ public final class MicrosoftAuthenticationServer extends NanoHTTPD implements Mi
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void openBrowser(String url) throws IOException {
|
public void openBrowser(String url) throws IOException {
|
||||||
// TODO: error!
|
lastlyOpenedURL = url;
|
||||||
FXUtils.openLink(url);
|
FXUtils.openLink(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +272,10 @@ public final class Controllers {
|
|||||||
decorator.getNavigator().navigate(node, ContainerAnimations.FADE.getAnimationProducer());
|
decorator.getNavigator().navigate(node, ContainerAnimations.FADE.getAnimationProducer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void showToast(String content) {
|
||||||
|
decorator.showToast(content);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isStopped() {
|
public static boolean isStopped() {
|
||||||
return decorator == null;
|
return decorator == null;
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,7 @@ import javafx.scene.image.Image;
|
|||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.image.PixelWriter;
|
import javafx.scene.image.PixelWriter;
|
||||||
import javafx.scene.image.WritableImage;
|
import javafx.scene.image.WritableImage;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.*;
|
||||||
import javafx.scene.input.KeyEvent;
|
|
||||||
import javafx.scene.input.TransferMode;
|
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.shape.Rectangle;
|
import javafx.scene.shape.Rectangle;
|
||||||
@ -70,6 +68,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import static org.jackhuang.hmcl.util.Lang.thread;
|
import static org.jackhuang.hmcl.util.Lang.thread;
|
||||||
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
import static org.jackhuang.hmcl.util.Lang.tryCast;
|
||||||
|
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||||
|
|
||||||
public final class FXUtils {
|
public final class FXUtils {
|
||||||
private FXUtils() {
|
private FXUtils() {
|
||||||
@ -613,4 +612,12 @@ public final class FXUtils {
|
|||||||
}
|
}
|
||||||
return wr;
|
return wr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void copyText(String text) {
|
||||||
|
ClipboardContent content = new ClipboardContent();
|
||||||
|
content.putString(text);
|
||||||
|
Clipboard.getSystemClipboard().setContent(content);
|
||||||
|
|
||||||
|
Controllers.showToast(i18n("message.copied"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ import com.jfoenix.validation.base.ValidatorBase;
|
|||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.NamedArg;
|
import javafx.beans.NamedArg;
|
||||||
import javafx.beans.binding.BooleanBinding;
|
import javafx.beans.binding.BooleanBinding;
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.geometry.HPos;
|
import javafx.geometry.HPos;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
@ -36,10 +38,12 @@ import org.jackhuang.hmcl.auth.CharacterSelector;
|
|||||||
import org.jackhuang.hmcl.auth.NoSelectedCharacterException;
|
import org.jackhuang.hmcl.auth.NoSelectedCharacterException;
|
||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccountFactory;
|
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorAccountFactory;
|
||||||
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
|
import org.jackhuang.hmcl.auth.authlibinjector.AuthlibInjectorServer;
|
||||||
|
import org.jackhuang.hmcl.auth.microsoft.MicrosoftAccountFactory;
|
||||||
import org.jackhuang.hmcl.auth.offline.OfflineAccountFactory;
|
import org.jackhuang.hmcl.auth.offline.OfflineAccountFactory;
|
||||||
import org.jackhuang.hmcl.auth.yggdrasil.GameProfile;
|
import org.jackhuang.hmcl.auth.yggdrasil.GameProfile;
|
||||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory;
|
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilAccountFactory;
|
||||||
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
|
import org.jackhuang.hmcl.auth.yggdrasil.YggdrasilService;
|
||||||
|
import org.jackhuang.hmcl.game.MicrosoftAuthenticationServer;
|
||||||
import org.jackhuang.hmcl.game.TexturesLoader;
|
import org.jackhuang.hmcl.game.TexturesLoader;
|
||||||
import org.jackhuang.hmcl.setting.Accounts;
|
import org.jackhuang.hmcl.setting.Accounts;
|
||||||
import org.jackhuang.hmcl.setting.Theme;
|
import org.jackhuang.hmcl.setting.Theme;
|
||||||
@ -82,6 +86,8 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
private Node detailsPane; // AccountDetailsInputPane for Offline / Mojang / authlib-injector, Label for Microsoft
|
private Node detailsPane; // AccountDetailsInputPane for Offline / Mojang / authlib-injector, Label for Microsoft
|
||||||
private final Pane detailsContainer;
|
private final Pane detailsContainer;
|
||||||
|
|
||||||
|
private final BooleanProperty logging = new SimpleBooleanProperty();
|
||||||
|
|
||||||
private TaskExecutor loginTask;
|
private TaskExecutor loginTask;
|
||||||
|
|
||||||
public CreateAccountPane() {
|
public CreateAccountPane() {
|
||||||
@ -185,7 +191,10 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
private void onAccept() {
|
private void onAccept() {
|
||||||
spinner.showSpinner();
|
spinner.showSpinner();
|
||||||
lblErrorMessage.setText("");
|
lblErrorMessage.setText("");
|
||||||
body.setDisable(true);
|
|
||||||
|
if (!(factory instanceof MicrosoftAccountFactory)) {
|
||||||
|
body.setDisable(true);
|
||||||
|
}
|
||||||
|
|
||||||
String username;
|
String username;
|
||||||
String password;
|
String password;
|
||||||
@ -201,6 +210,8 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
additionalData = null;
|
additionalData = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logging.set(true);
|
||||||
|
|
||||||
loginTask = Task.supplyAsync(() -> factory.create(new DialogCharacterSelector(), username, password, null, additionalData))
|
loginTask = Task.supplyAsync(() -> factory.create(new DialogCharacterSelector(), username, password, null, additionalData))
|
||||||
.whenComplete(Schedulers.javafx(), account -> {
|
.whenComplete(Schedulers.javafx(), account -> {
|
||||||
int oldIndex = Accounts.getAccounts().indexOf(account);
|
int oldIndex = Accounts.getAccounts().indexOf(account);
|
||||||
@ -243,9 +254,17 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
|
|||||||
lblErrorMessage.setText("");
|
lblErrorMessage.setText("");
|
||||||
}
|
}
|
||||||
if (factory == Accounts.FACTORY_MICROSOFT) {
|
if (factory == Accounts.FACTORY_MICROSOFT) {
|
||||||
Label lblTip = new Label(i18n("account.methods.microsoft.manual")); // TODO
|
HintPane hintPane = new HintPane(MessageDialogPane.MessageType.INFORMATION);
|
||||||
lblTip.setWrapText(true);
|
hintPane.textProperty().bind(BindingMapping.of(logging).map(logging ->
|
||||||
detailsPane = lblTip;
|
logging
|
||||||
|
? i18n("account.methods.microsoft.manual")
|
||||||
|
: i18n("account.methods.microsoft.hint")));
|
||||||
|
hintPane.setOnMouseClicked(e -> {
|
||||||
|
if (logging.get() && MicrosoftAuthenticationServer.lastlyOpenedURL != null) {
|
||||||
|
FXUtils.copyText(MicrosoftAuthenticationServer.lastlyOpenedURL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
detailsPane = hintPane;
|
||||||
btnAccept.setDisable(false);
|
btnAccept.setDisable(false);
|
||||||
} else {
|
} else {
|
||||||
detailsPane = new AccountDetailsInputPane(factory, btnAccept::fire);
|
detailsPane = new AccountDetailsInputPane(factory, btnAccept::fire);
|
||||||
|
@ -33,7 +33,6 @@ import org.jackhuang.hmcl.setting.Theme;
|
|||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
|
||||||
|
|
||||||
public class MenuUpDownButton extends Control {
|
public class MenuUpDownButton extends Control {
|
||||||
|
|
||||||
private final BooleanProperty selected = new SimpleBooleanProperty(this, "selected");
|
private final BooleanProperty selected = new SimpleBooleanProperty(this, "selected");
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.decorator;
|
package org.jackhuang.hmcl.ui.decorator;
|
||||||
|
|
||||||
|
import com.jfoenix.controls.JFXSnackbar;
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
@ -54,6 +55,7 @@ public class Decorator extends Control {
|
|||||||
private final Stage primaryStage;
|
private final Stage primaryStage;
|
||||||
private Navigation.NavigationDirection navigationDirection = Navigation.NavigationDirection.START;
|
private Navigation.NavigationDirection navigationDirection = Navigation.NavigationDirection.START;
|
||||||
private StackPane drawerWrapper;
|
private StackPane drawerWrapper;
|
||||||
|
private final JFXSnackbar snackbar = new JFXSnackbar();
|
||||||
|
|
||||||
private final ReadOnlyBooleanWrapper allowMove = new ReadOnlyBooleanWrapper();
|
private final ReadOnlyBooleanWrapper allowMove = new ReadOnlyBooleanWrapper();
|
||||||
private final ReadOnlyBooleanWrapper dragging = new ReadOnlyBooleanWrapper();
|
private final ReadOnlyBooleanWrapper dragging = new ReadOnlyBooleanWrapper();
|
||||||
@ -214,6 +216,10 @@ public class Decorator extends Control {
|
|||||||
return onRefreshNavButtonAction;
|
return onRefreshNavButtonAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JFXSnackbar getSnackbar() {
|
||||||
|
return snackbar;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Skin<?> createDefaultSkin() {
|
protected Skin<?> createDefaultSkin() {
|
||||||
return new DecoratorSkin(this);
|
return new DecoratorSkin(this);
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package org.jackhuang.hmcl.ui.decorator;
|
package org.jackhuang.hmcl.ui.decorator;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXDialog;
|
import com.jfoenix.controls.JFXDialog;
|
||||||
|
import com.jfoenix.controls.JFXSnackbar;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
@ -363,6 +364,12 @@ public class DecoratorController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==== Toast ====
|
||||||
|
|
||||||
|
public void showToast(String content) {
|
||||||
|
decorator.getSnackbar().fireEvent(new JFXSnackbar.SnackbarEvent(content, null, 2000L, false, null));
|
||||||
|
}
|
||||||
|
|
||||||
// ==== Wizard ====
|
// ==== Wizard ====
|
||||||
|
|
||||||
public void startWizard(WizardProvider wizardProvider) {
|
public void startWizard(WizardProvider wizardProvider) {
|
||||||
|
@ -89,6 +89,8 @@ public class DecoratorSkin extends SkinBase<Decorator> {
|
|||||||
clip.setArcHeight(8);
|
clip.setArcHeight(8);
|
||||||
parent.setClip(clip);
|
parent.setClip(clip);
|
||||||
|
|
||||||
|
skinnable.getSnackbar().registerSnackbarContainer(parent);
|
||||||
|
|
||||||
root.addEventFilter(MouseEvent.MOUSE_RELEASED, this::onMouseReleased);
|
root.addEventFilter(MouseEvent.MOUSE_RELEASED, this::onMouseReleased);
|
||||||
root.addEventFilter(MouseEvent.MOUSE_DRAGGED, this::onMouseDragged);
|
root.addEventFilter(MouseEvent.MOUSE_DRAGGED, this::onMouseDragged);
|
||||||
root.addEventFilter(MouseEvent.MOUSE_MOVED, this::onMouseMoved);
|
root.addEventFilter(MouseEvent.MOUSE_MOVED, this::onMouseMoved);
|
||||||
|
@ -21,9 +21,6 @@ import org.jackhuang.hmcl.Metadata;
|
|||||||
import org.jackhuang.hmcl.game.Artifact;
|
import org.jackhuang.hmcl.game.Artifact;
|
||||||
import org.jackhuang.hmcl.task.FileDownloadTask;
|
import org.jackhuang.hmcl.task.FileDownloadTask;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
import org.jackhuang.hmcl.task.TaskExecutor;
|
|
||||||
import org.jackhuang.hmcl.ui.Controllers;
|
|
||||||
import org.jackhuang.hmcl.ui.construct.TaskExecutorDialogPane;
|
|
||||||
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
import org.jackhuang.hmcl.util.io.NetworkUtils;
|
||||||
import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
import org.jackhuang.hmcl.util.platform.ManagedProcess;
|
||||||
|
|
||||||
@ -33,16 +30,17 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cato Management.
|
* Cato Management.
|
||||||
*/
|
*/
|
||||||
public class MultiplayerManager {
|
public final class MultiplayerManager {
|
||||||
private static final String CATO_DOWNLOAD_URL = "https://hmcl.huangyuhui.net/maven/";
|
private static final String CATO_DOWNLOAD_URL = "https://hmcl.huangyuhui.net/maven/";
|
||||||
private static final String CATO_VERSION = "2021-09-01";
|
private static final String CATO_VERSION = "2021-09-01";
|
||||||
private static final Artifact CATO_ARTIFACT = new Artifact("cato", "cato", CATO_VERSION);
|
private static final Artifact CATO_ARTIFACT = new Artifact("cato", "cato", CATO_VERSION);
|
||||||
|
|
||||||
|
private MultiplayerManager() {
|
||||||
|
}
|
||||||
|
|
||||||
public static void fetchIdAndToken() {
|
public static void fetchIdAndToken() {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,8 @@ account.methods.microsoft.error.missing_xbox_account=Your Microsoft account is n
|
|||||||
account.methods.microsoft.error.no_character=Account is missing a Minecraft Java profile. While the Microsoft account is valid, it does not own the game.
|
account.methods.microsoft.error.no_character=Account is missing a Minecraft Java profile. While the Microsoft account is valid, it does not own the game.
|
||||||
account.methods.microsoft.error.unknown=Failed to log in. Microsoft respond with error code %d.
|
account.methods.microsoft.error.unknown=Failed to log in. Microsoft respond with error code %d.
|
||||||
account.methods.microsoft.logging_in=Logging in...
|
account.methods.microsoft.logging_in=Logging in...
|
||||||
account.methods.microsoft.manual=You should finish authorization in the newly opened browser window. If the browser window failed to show, you can click here to copy the URL, and manually open it in your browser.
|
account.methods.microsoft.hint=You should click "login" button and continue login process in newly opened browser window.
|
||||||
|
account.methods.microsoft.manual=After clicking "login" button, you should finish authorization in the newly opened browser window. If the browser window failed to show, you can click here to copy the URL, and manually open it in your browser.
|
||||||
account.methods.microsoft.waiting_browser=Waiting for authorization in opened browser window...
|
account.methods.microsoft.waiting_browser=Waiting for authorization in opened browser window...
|
||||||
account.methods.offline=Offline
|
account.methods.offline=Offline
|
||||||
account.methods.offline.uuid=UUID
|
account.methods.offline.uuid=UUID
|
||||||
@ -394,6 +395,7 @@ logwindow.export_game_crash_logs=Export game crash info
|
|||||||
main_page=Home
|
main_page=Home
|
||||||
|
|
||||||
message.confirm=Confirm
|
message.confirm=Confirm
|
||||||
|
message.copied=Copied to clipboard
|
||||||
message.doing=Please wait
|
message.doing=Please wait
|
||||||
message.downloading=Downloading...
|
message.downloading=Downloading...
|
||||||
message.error=Error
|
message.error=Error
|
||||||
@ -489,6 +491,7 @@ mods.not_modded=You should install a modloader first (Fabric, Forge or LiteLoade
|
|||||||
mods.url=Official Page
|
mods.url=Official Page
|
||||||
|
|
||||||
multiplayer=Multiplayer
|
multiplayer=Multiplayer
|
||||||
|
multiplayer.download=Downloading dependencies for multiplayer
|
||||||
multiplayer.nat=Network Type Detection
|
multiplayer.nat=Network Type Detection
|
||||||
multiplayer.nat.hint=Network type detection will make it clear whether your network fulfills our requirement for multiplayer mode.
|
multiplayer.nat.hint=Network type detection will make it clear whether your network fulfills our requirement for multiplayer mode.
|
||||||
multiplayer.nat.latency=Latency
|
multiplayer.nat.latency=Latency
|
||||||
@ -503,7 +506,8 @@ multiplayer.nat.type.port_restricted_cone=Medium (Port Restricted Cone)
|
|||||||
multiplayer.nat.type.restricted_cone=Medium (Restricted Cone)
|
multiplayer.nat.type.restricted_cone=Medium (Restricted Cone)
|
||||||
multiplayer.nat.type.symmetric=Bad (Symmetric)
|
multiplayer.nat.type.symmetric=Bad (Symmetric)
|
||||||
multiplayer.nat.type.symmetric_udp_firewall=Bad (Symmetric with UDP Firewall)
|
multiplayer.nat.type.symmetric_udp_firewall=Bad (Symmetric with UDP Firewall)
|
||||||
multiplayer.nat.type.unknown=Unknownn
|
multiplayer.nat.type.unknown=Unknown
|
||||||
|
multiplayer.powered_by=Powered by cato
|
||||||
multiplayer.room=Room
|
multiplayer.room=Room
|
||||||
multiplayer.room.name.format=%1$s's Room
|
multiplayer.room.name.format=%1$s's Room
|
||||||
multiplayer.room.close=Close Room
|
multiplayer.room.close=Close Room
|
||||||
|
@ -74,8 +74,8 @@ account.methods.microsoft.error.missing_xbox_account=你的微軟帳號尚未關
|
|||||||
account.methods.microsoft.error.no_character=該帳號沒有包含 Minecraft Java 版購買記錄
|
account.methods.microsoft.error.no_character=該帳號沒有包含 Minecraft Java 版購買記錄
|
||||||
account.methods.microsoft.error.unknown=登錄失敗,錯誤碼:%d
|
account.methods.microsoft.error.unknown=登錄失敗,錯誤碼:%d
|
||||||
account.methods.microsoft.logging_in=登錄中...
|
account.methods.microsoft.logging_in=登錄中...
|
||||||
account.methods.microsoft.hint=點擊確定以登錄
|
account.methods.microsoft.hint=您需要點擊登錄按鈕,並在新打開的瀏覽器窗口中完成登錄。
|
||||||
account.methods.microsoft.manual=您需要在新打開的瀏覽器窗口中完成登錄。若頁面未能打開,您可以點擊此處複製連結,並手動在瀏覽器中打開網頁。
|
account.methods.microsoft.manual=若登錄頁面未能打開,您可以點擊此處複製連結,並手動在瀏覽器中打開網頁。
|
||||||
account.methods.microsoft.waiting_browser=等待在新打開的瀏覽器窗口中完成登錄...
|
account.methods.microsoft.waiting_browser=等待在新打開的瀏覽器窗口中完成登錄...
|
||||||
account.methods.offline=離線模式
|
account.methods.offline=離線模式
|
||||||
account.methods.offline.uuid=UUID
|
account.methods.offline.uuid=UUID
|
||||||
@ -380,6 +380,7 @@ logwindow.export_game_crash_logs=導出遊戲崩潰訊息
|
|||||||
main_page=首頁
|
main_page=首頁
|
||||||
|
|
||||||
message.confirm=提示
|
message.confirm=提示
|
||||||
|
message.copied=已複製到剪貼板
|
||||||
message.doing=請耐心等待
|
message.doing=請耐心等待
|
||||||
message.downloading=正在下載…
|
message.downloading=正在下載…
|
||||||
message.error=錯誤
|
message.error=錯誤
|
||||||
@ -464,6 +465,7 @@ mods.name=名稱
|
|||||||
mods.not_modded=你需要先在自動安裝頁面安裝 Fabric、Forge 或 LiteLoader 才能進行模組管理。
|
mods.not_modded=你需要先在自動安裝頁面安裝 Fabric、Forge 或 LiteLoader 才能進行模組管理。
|
||||||
|
|
||||||
multiplayer=聯機
|
multiplayer=聯機
|
||||||
|
multiplayer.download=正在下載依賴
|
||||||
multiplayer.nat=網路檢測
|
multiplayer.nat=網路檢測
|
||||||
multiplayer.nat.hint=執行網路檢測可以讓你更清楚裡的網路狀況是否符合聯機功能的需求。不符合聯機功能運行條件的網路狀況將可能導致聯機失敗。
|
multiplayer.nat.hint=執行網路檢測可以讓你更清楚裡的網路狀況是否符合聯機功能的需求。不符合聯機功能運行條件的網路狀況將可能導致聯機失敗。
|
||||||
multiplayer.nat.latency=延遲
|
multiplayer.nat.latency=延遲
|
||||||
@ -479,6 +481,7 @@ multiplayer.nat.type.restricted_cone=中(受限圓錐型)
|
|||||||
multiplayer.nat.type.symmetric=差(對稱型)
|
multiplayer.nat.type.symmetric=差(對稱型)
|
||||||
multiplayer.nat.type.symmetric_udp_firewall=差(對稱型+防火牆)
|
multiplayer.nat.type.symmetric_udp_firewall=差(對稱型+防火牆)
|
||||||
multiplayer.nat.type.unknown=未知
|
multiplayer.nat.type.unknown=未知
|
||||||
|
multiplayer.powered_by=由 cato 提供技術支持
|
||||||
multiplayer.room=房間
|
multiplayer.room=房間
|
||||||
multiplayer.room.name.format=%1$s 的房間
|
multiplayer.room.name.format=%1$s 的房間
|
||||||
multiplayer.room.close=關閉房間
|
multiplayer.room.close=關閉房間
|
||||||
|
@ -80,8 +80,8 @@ account.methods.microsoft.error.missing_xbox_account=你的微软账号尚未关
|
|||||||
account.methods.microsoft.error.no_character=该账号没有包含 Minecraft Java 版购买记录
|
account.methods.microsoft.error.no_character=该账号没有包含 Minecraft Java 版购买记录
|
||||||
account.methods.microsoft.error.unknown=登录失败,错误码:%d
|
account.methods.microsoft.error.unknown=登录失败,错误码:%d
|
||||||
account.methods.microsoft.logging_in=登录中...
|
account.methods.microsoft.logging_in=登录中...
|
||||||
account.methods.microsoft.hint=点击确定以登录
|
account.methods.microsoft.hint=您需要点击登录按钮,并在新打开的浏览器窗口中完成登录。
|
||||||
account.methods.microsoft.manual=您需要在新打开的浏览器窗口中完成登录。若页面未能打开,您可以点击此处复制链接,并手动在浏览器中打开网页。
|
account.methods.microsoft.manual=若登录页面未能打开,您可以点击此处复制链接,并手动在浏览器中打开网页。
|
||||||
account.methods.microsoft.waiting_browser=等待在新打开的浏览器窗口中完成登录...
|
account.methods.microsoft.waiting_browser=等待在新打开的浏览器窗口中完成登录...
|
||||||
account.methods.offline=离线模式
|
account.methods.offline=离线模式
|
||||||
account.methods.offline.uuid=UUID
|
account.methods.offline.uuid=UUID
|
||||||
@ -400,6 +400,7 @@ logwindow.export_game_crash_logs=导出游戏崩溃信息
|
|||||||
main_page=主页
|
main_page=主页
|
||||||
|
|
||||||
message.confirm=提示
|
message.confirm=提示
|
||||||
|
message.copied=已复制到剪贴板
|
||||||
message.doing=请耐心等待
|
message.doing=请耐心等待
|
||||||
message.downloading=正在下载
|
message.downloading=正在下载
|
||||||
message.error=错误
|
message.error=错误
|
||||||
@ -496,6 +497,7 @@ mods.not_modded=你需要先在自动安装页面安装 Fabric、Forge 或 LiteL
|
|||||||
mods.url=官方页面
|
mods.url=官方页面
|
||||||
|
|
||||||
multiplayer=联机
|
multiplayer=联机
|
||||||
|
multiplayer.download=正在下载依赖
|
||||||
multiplayer.nat=网络检测
|
multiplayer.nat=网络检测
|
||||||
multiplayer.nat.hint=执行网络检测可以让你更清楚里的网络状况是否符合联机功能的需求。不符合联机功能运行条件的网络状况将可能导致联机失败。
|
multiplayer.nat.hint=执行网络检测可以让你更清楚里的网络状况是否符合联机功能的需求。不符合联机功能运行条件的网络状况将可能导致联机失败。
|
||||||
multiplayer.nat.latency=延迟
|
multiplayer.nat.latency=延迟
|
||||||
@ -511,6 +513,7 @@ multiplayer.nat.type.restricted_cone=中(受限圆锥型)
|
|||||||
multiplayer.nat.type.symmetric=差(对称型)
|
multiplayer.nat.type.symmetric=差(对称型)
|
||||||
multiplayer.nat.type.symmetric_udp_firewall=差(对称型+防火墙)
|
multiplayer.nat.type.symmetric_udp_firewall=差(对称型+防火墙)
|
||||||
multiplayer.nat.type.unknown=未知
|
multiplayer.nat.type.unknown=未知
|
||||||
|
multiplayer.powered_by=由 cato 提供技术支持
|
||||||
multiplayer.room=房间
|
multiplayer.room=房间
|
||||||
multiplayer.room.name.format=%1$s 的房间
|
multiplayer.room.name.format=%1$s 的房间
|
||||||
multiplayer.room.close=关闭房间
|
multiplayer.room.close=关闭房间
|
||||||
|
Loading…
x
Reference in New Issue
Block a user