diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java index f0ee57074..f56fa460f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/MessageDialogPane.java @@ -176,8 +176,11 @@ public final class MessageDialogPane extends StackPane { @Override public void run() { - if (timeout < 0) { + if (timeout <= 0) { cancel(); + runInFX(() -> { + cancelButton.fire(); + }); return; } timeout -= 1000; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java index 81a6d5485..0f51f0537 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java @@ -46,6 +46,7 @@ import java.util.logging.Level; import static org.jackhuang.hmcl.setting.ConfigHolder.globalConfig; import static org.jackhuang.hmcl.ui.FXUtils.runInFX; +import static org.jackhuang.hmcl.util.Lang.resolveException; import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; @@ -215,7 +216,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP session.getServer().setOnClientAdding((client, resolveClient, rejectClient) -> { runInFX(() -> { Controllers.dialog(new MessageDialogPane.Builder(i18n("multiplayer.session.create.join.prompt", client.getUsername()), i18n("multiplayer.session.create.join"), MessageDialogPane.MessageType.INFO) - .yesOrNo(resolveClient, () -> rejectClient.accept("")) + .yesOrNo(resolveClient, () -> rejectClient.accept(i18n("multiplayer.session.join.wait_timeout"))) .cancelOnTimeout(30 * 1000) .build()); }); @@ -314,20 +315,21 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP resolve.run(); }, Platform::runLater) .exceptionally(throwable -> { - if (throwable instanceof CancellationException) { + Throwable resolved = resolveException(throwable); + if (resolved instanceof CancellationException) { LOG.info("Connection rejected by the server"); reject.accept(i18n("multiplayer.session.join.rejected")); return null; - } else if (throwable instanceof MultiplayerManager.CatoAlreadyStartedException) { + } else if (resolved instanceof MultiplayerManager.CatoAlreadyStartedException) { LOG.info("Cato already started"); reject.accept(i18n("multiplayer.session.error.already_started")); return null; - } else if (throwable instanceof MultiplayerManager.JoinRequestTimeoutException) { + } else if (resolved instanceof MultiplayerManager.JoinRequestTimeoutException) { LOG.info("Cato already started"); reject.accept(i18n("multiplayer.session.join.wait_timeout")); return null; } else { - LOG.log(Level.WARNING, "Failed to join sessoin"); + LOG.log(Level.WARNING, "Failed to join session", resolved); reject.accept(i18n("multiplayer.session.join.error")); } return null; @@ -389,7 +391,9 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP } private void stopCatoSession() { - getSession().stop(); + if (getSession() != null) { + getSession().stop(); + } clearCatoSession(); } diff --git a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties index 8163a6ead..9c21aa59f 100644 --- a/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties +++ b/HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties @@ -666,7 +666,7 @@ multiplayer.session.create.token.prompt=默认为临时 Token。你可以在 noi multiplayer.session.error.already_started=本地已经开启 cato 服务,请检查是否有其他 HMCL 正在运行联机服务。或者你可以在任务管理器里杀掉 cato 进程以继续。 multiplayer.session.expired=联机会话连续使用时间超过了 3 小时,你需要重新创建/加入房间以继续联机。 multiplayer.session.join=加入房间 -multiplayer.session.join.error=加入房间失败 +multiplayer.session.join.error=加入房间失败。如果你或对方的网络类型是差(对称型),可能无法使用联机功能。 multiplayer.session.join.hint=你需要向已经创建好房间的玩家索要邀请码以便加入多人联机房间 multiplayer.session.join.invitation_code=邀请码 multiplayer.session.join.invitation_code.error=邀请码不正确,请向开服玩家获取邀请码 diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/AsyncTaskExecutor.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/AsyncTaskExecutor.java index e01bc26c0..fb8277b82 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/task/AsyncTaskExecutor.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/task/AsyncTaskExecutor.java @@ -26,8 +26,7 @@ import java.util.Collections; import java.util.concurrent.*; import java.util.logging.Level; -import static org.jackhuang.hmcl.util.Lang.rethrow; -import static org.jackhuang.hmcl.util.Lang.wrap; +import static org.jackhuang.hmcl.util.Lang.*; /** * @@ -320,13 +319,6 @@ public final class AsyncTaskExecutor extends TaskExecutor { } } - private static Throwable resolveException(Throwable e) { - if (e instanceof ExecutionException || e instanceof CompletionException) - return resolveException(e.getCause()); - else - return e; - } - private void checkCancellation() { if (isCancelled()) { throw new CancellationException("Cancelled by user"); diff --git a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Lang.java b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Lang.java index 4ee4a5275..7c8bcad09 100644 --- a/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Lang.java +++ b/HMCLCore/src/main/java/org/jackhuang/hmcl/util/Lang.java @@ -377,6 +377,13 @@ public final class Lang { return task; } + public static Throwable resolveException(Throwable e) { + if (e instanceof ExecutionException || e instanceof CompletionException) + return resolveException(e.getCause()); + else + return e; + } + /** * This is a useful function to prevent exceptions being eaten when using CompletableFuture. * You can write: