fix(multiplayer): get ip from hiper log.

This commit is contained in:
huanghongxun 2022-09-12 23:05:13 +08:00
parent b69c400a08
commit 662b42c40f
3 changed files with 41 additions and 9 deletions

View File

@ -19,6 +19,7 @@ package org.jackhuang.hmcl.ui.multiplayer;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import jdk.nashorn.internal.parser.JSONParser;
import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.event.Event; import org.jackhuang.hmcl.event.Event;
import org.jackhuang.hmcl.event.EventManager; import org.jackhuang.hmcl.event.EventManager;
@ -26,6 +27,7 @@ import org.jackhuang.hmcl.task.FileDownloadTask;
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.util.Lang; import org.jackhuang.hmcl.util.Lang;
import org.jackhuang.hmcl.util.gson.JsonUtils;
import org.jackhuang.hmcl.util.io.ChecksumMismatchException; import org.jackhuang.hmcl.util.io.ChecksumMismatchException;
import org.jackhuang.hmcl.util.io.FileUtils; import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.HttpRequest; import org.jackhuang.hmcl.util.io.HttpRequest;
@ -50,8 +52,7 @@ import java.util.logging.Level;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.jackhuang.hmcl.util.Lang.mapOf; import static org.jackhuang.hmcl.util.Lang.*;
import static org.jackhuang.hmcl.util.Lang.wrap;
import static org.jackhuang.hmcl.util.Logging.LOG; import static org.jackhuang.hmcl.util.Logging.LOG;
import static org.jackhuang.hmcl.util.Pair.pair; import static org.jackhuang.hmcl.util.Pair.pair;
@ -188,7 +189,7 @@ public final class MultiplayerManager {
// 下载 HiPer 配置文件 // 下载 HiPer 配置文件
String certFileContent; String certFileContent;
try { try {
certFileContent = HttpRequest.GET(String.format("https://cert.mcer.cn/%s.yml", token)).getString(); certFileContent = HttpRequest.GET(String.format("https://cert.mcer.cn/%s.yml", token)).getString() + "\nlogging:\n format: json\n file_path: ./hiper.log";
} catch (IOException e) { } catch (IOException e) {
throw new HiperInvalidTokenException(); throw new HiperInvalidTokenException();
} }
@ -219,6 +220,7 @@ public final class MultiplayerManager {
private final EventManager<HiperExitEvent> onExit = new EventManager<>(); private final EventManager<HiperExitEvent> onExit = new EventManager<>();
private final EventManager<HiperIPEvent> onIPAllocated = new EventManager<>(); private final EventManager<HiperIPEvent> onIPAllocated = new EventManager<>();
private final BufferedWriter writer; private final BufferedWriter writer;
private int error = 0;
HiperSession(Process process, List<String> commands) { HiperSession(Process process, List<String> commands) {
super(process, commands); super(process, commands);
@ -237,8 +239,30 @@ public final class MultiplayerManager {
private void onLog(String log) { private void onLog(String log) {
LOG.info("[Hiper] " + log); LOG.info("[Hiper] " + log);
if (log.contains("IP")) { if (log.contains("failed to load config")) {
// TODO error = HiperExitEvent.INVALID_CONFIGURATION;
return;
}
try {
Map<?, ?> logJson = JsonUtils.fromNonNullJson(log, Map.class);
String msg = "";
if (logJson.containsKey("msg")) {
msg = tryCast(logJson.get("msg"), String.class).orElse("");
if (msg.contains("Failed to get a tun/tap device")) {
error = HiperExitEvent.FAILED_GET_DEVICE;
}
}
if (logJson.containsKey("network")) {
Map<?, ?> network = tryCast(logJson.get("network"), Map.class).orElse(Collections.emptyMap());
if (network.containsKey("IP") && msg.contains("Main HostMap created")) {
Optional<String> ip = tryCast(network.get("IP"), String.class);
ip.ifPresent(s -> onIPAllocated.fireEvent(new HiperIPEvent(this, s)));
}
}
} catch (JsonParseException e) {
LOG.log(Level.WARNING, "Failed to parse hiper log: " + log, e);
} }
} }
@ -246,7 +270,11 @@ public final class MultiplayerManager {
try { try {
int exitCode = getProcess().waitFor(); int exitCode = getProcess().waitFor();
LOG.info("Hiper exited with exitcode " + exitCode); LOG.info("Hiper exited with exitcode " + exitCode);
if (error != 0) {
onExit.fireEvent(new HiperExitEvent(this, error));
} else {
onExit.fireEvent(new HiperExitEvent(this, exitCode)); onExit.fireEvent(new HiperExitEvent(this, exitCode));
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
onExit.fireEvent(new HiperExitEvent(this, HiperExitEvent.INTERRUPTED)); onExit.fireEvent(new HiperExitEvent(this, HiperExitEvent.INTERRUPTED));
} finally { } finally {
@ -283,9 +311,9 @@ public final class MultiplayerManager {
} }
public static final int INTERRUPTED = -1; public static final int INTERRUPTED = -1;
public static final int INVALID_CONFIGURATION = -2;
public static final int INVALID_CONFIGURATION = 1; public static final int CERTIFICATE_EXPIRED = -3;
public static final int CERTIFICATE_EXPIRED = 11; public static final int FAILED_GET_DEVICE = -4;
} }
public static class HiperIPEvent extends Event { public static class HiperIPEvent extends Event {

View File

@ -251,6 +251,9 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP
case MultiplayerManager.HiperExitEvent.INTERRUPTED: case MultiplayerManager.HiperExitEvent.INTERRUPTED:
// do nothing // do nothing
break; break;
case MultiplayerManager.HiperExitEvent.FAILED_GET_DEVICE:
Controllers.dialog(i18n("multiplayer.error.failed_get_device"));
break;
default: default:
Controllers.dialog(i18n("multiplayer.exit", event.getExitCode())); Controllers.dialog(i18n("multiplayer.exit", event.getExitCode()));
break; break;

View File

@ -690,6 +690,7 @@ multiplayer.download=正在下载依赖
multiplayer.download.failed=初始化失败,部分文件未能完成下载 multiplayer.download.failed=初始化失败,部分文件未能完成下载
multiplayer.download.success=多人联机初始化完成 multiplayer.download.success=多人联机初始化完成
multiplayer.download.unsupported=多人联机依赖不支持当前系统或平台 multiplayer.download.unsupported=多人联机依赖不支持当前系统或平台
multiplayer.error.failed_get_device=HiPer 无法创建网络设备,可能是缺少 root 权限。
multiplayer.error.file_not_found=找不到 HiPer 程序。该程序应该在进入多人联机页面时完成下载。请重启 HMCL 再试。\n请检查你电脑的杀毒软件是否将 HiPer 标记为病毒,如果是,请恢复 HiPer。 multiplayer.error.file_not_found=找不到 HiPer 程序。该程序应该在进入多人联机页面时完成下载。请重启 HMCL 再试。\n请检查你电脑的杀毒软件是否将 HiPer 标记为病毒,如果是,请恢复 HiPer。
multiplayer.exit=HiPer 意外退出,退出码 %d multiplayer.exit=HiPer 意外退出,退出码 %d
multiplayer.hint=多人联机功能处于实验阶段,如果有问题请前往 mcer.cn 反馈 multiplayer.hint=多人联机功能处于实验阶段,如果有问题请前往 mcer.cn 反馈