fix(multiplayer): bind to 0.0.0.0 instead of 127.0.0.1.
This commit is contained in:
@@ -57,7 +57,7 @@ public class LocalServerBroadcaster implements Runnable {
|
||||
byte[] data = String.format("[MOTD]%s[/MOTD][AD]%d[/AD]", i18n("multiplayer.session.name.motd", session.getName()), port).getBytes(StandardCharsets.UTF_8);
|
||||
DatagramPacket packet = new DatagramPacket(data, 0, data.length, broadcastAddress, 4445);
|
||||
socket.send(packet);
|
||||
LOG.fine("Broadcast server 127.0.0.1:" + port);
|
||||
LOG.fine("Broadcast server 0.0.0.0:" + port);
|
||||
} catch (IOException e) {
|
||||
LOG.log(Level.WARNING, "Failed to send motd packet", e);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class LocalServerDetector extends Thread {
|
||||
}
|
||||
|
||||
String response = new String(packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8);
|
||||
LOG.fine("Local server broadcast message: " + response);
|
||||
LOG.fine("Local server " + packet.getAddress() + ":" + packet.getPort() + " broadcast message: " + response);
|
||||
onDetectedLanServer.fireEvent(new DetectedLanServerEvent(this, PingResponse.parsePingResponse(response)));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ import static org.jackhuang.hmcl.util.Logging.LOG;
|
||||
*/
|
||||
public final class MultiplayerManager {
|
||||
private static final String CATO_DOWNLOAD_URL = "https://files.huangyuhui.net/maven/";
|
||||
static final String CATO_VERSION = "1.0.8";
|
||||
static final String CATO_VERSION = "1.0.9";
|
||||
private static final String CATO_PATH = getCatoPath();
|
||||
|
||||
private MultiplayerManager() {
|
||||
@@ -96,8 +96,8 @@ public final class MultiplayerManager {
|
||||
String[] commands = new String[]{exe.toString(),
|
||||
"--token", StringUtils.isBlank(token) ? "new" : token,
|
||||
"--id", peer,
|
||||
"--local", String.format("127.0.0.1:%d", localPort),
|
||||
"--remote", String.format("127.0.0.1:%d", remotePort),
|
||||
"--local", String.format("0.0.0.0:%d", localPort),
|
||||
"--remote", String.format("0.0.0.0:%d", remotePort),
|
||||
"--mode", "relay"};
|
||||
Process process;
|
||||
try {
|
||||
@@ -130,7 +130,7 @@ public final class MultiplayerManager {
|
||||
client.onConnected().register(connectedEvent -> {
|
||||
try {
|
||||
int port = findAvailablePort();
|
||||
writer.write(String.format("net add %s 127.0.0.1:%d 127.0.0.1:%d p2p\n", peer, port, connectedEvent.getPort()));
|
||||
writer.write(String.format("net add %s 0.0.0.0:%d 0.0.0.0:%d p2p\n", peer, port, connectedEvent.getPort()));
|
||||
future.complete(session);
|
||||
} catch (IOException e) {
|
||||
future.completeExceptionally(e);
|
||||
@@ -154,7 +154,7 @@ public final class MultiplayerManager {
|
||||
|
||||
String[] commands = new String[]{exe.toString(),
|
||||
"--token", StringUtils.isBlank(token) ? "new" : token,
|
||||
"--allows", String.format("127.0.0.1:%d,127.0.0.1:%d", port, server.getPort()),
|
||||
"--allows", String.format("0.0.0.0:%d/0.0.0.0:%d", port, server.getPort()),
|
||||
"--mode", "relay"};
|
||||
Process process = new ProcessBuilder()
|
||||
.command(commands)
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.multiplayer;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import de.javawi.jstun.test.DiscoveryInfo;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.SkinBase;
|
||||
@@ -172,16 +174,22 @@ public class MultiplayerPageSkin extends SkinBase<MultiplayerPage> {
|
||||
masterPane.getChildren().setAll(label);
|
||||
}
|
||||
|
||||
VBox slavePane = new VBox(8);
|
||||
BorderPane slavePane = new BorderPane();
|
||||
{
|
||||
HintPane slaveHintPane = new HintPane();
|
||||
slaveHintPane.setText(i18n("multiplayer.state.slave.hint"));
|
||||
slavePane.setTop(slaveHintPane);
|
||||
|
||||
Label label = new Label();
|
||||
label.textProperty().bind(Bindings.createStringBinding(() ->
|
||||
i18n("multiplayer.state.slave", control.getSession() == null ? "" : control.getSession().getName(), control.getPort()),
|
||||
i18n("multiplayer.state.slave", control.getSession() == null ? "" : control.getSession().getName(), "0.0.0.0:" + control.getPort()),
|
||||
control.sessionProperty(), control.portProperty()));
|
||||
slavePane.getChildren().setAll(slaveHintPane, label);
|
||||
BorderPane.setAlignment(label, Pos.CENTER_LEFT);
|
||||
slavePane.setCenter(label);
|
||||
|
||||
JFXButton copyButton = new JFXButton(i18n("multiplayer.state.slave.copy"));
|
||||
copyButton.setOnAction(e -> FXUtils.copyText("0.0.0.0:" + control.getPort()));
|
||||
slavePane.setRight(copyButton);
|
||||
}
|
||||
|
||||
FXUtils.onChangeAndOperate(getSkinnable().multiplayerStateProperty(), state -> {
|
||||
|
||||
@@ -643,6 +643,7 @@ multiplayer.state.disconnected=Not created/entered a multiplayer session
|
||||
multiplayer.state.disconnected.hint=Someone should create a multiplayer session, and others join the session to play the game together.
|
||||
multiplayer.state.master=Created room: %1$s, port: %2$d
|
||||
multiplayer.state.slave=Joined room: %1$s, address: %2$s
|
||||
multiplayer.state.slave.copy=Copy address
|
||||
multiplayer.state.slave.hint=After joining multiplayer room, you should get to multiplayer page in Minecraft and connect to the "HMCL Multiplayer Session" server, or manually add a server with address shown below.
|
||||
|
||||
datapack=Datapacks
|
||||
|
||||
@@ -641,7 +641,8 @@ multiplayer.state.connecting=連接中
|
||||
multiplayer.state.disconnected=未創建/加入房間
|
||||
multiplayer.state.disconnected.hint=多人聯機功能需要先有一位玩家創建房間後,其他玩家加入房間後繼續遊戲。
|
||||
multiplayer.state.master=你已創建房間:%1$s,埠號 %2$d
|
||||
multiplayer.state.slave=你已加入房間: %1$s,地址為 %2$s
|
||||
multiplayer.state.slave=你已加入房間: %1$s,位址為 %2$s
|
||||
multiplayer.state.slave.copy=拷貝位址
|
||||
multiplayer.state.slave.hint=加入房間後,你需要在 Minecraft 的多人遊戲頁面選擇 HMCL 多人聯機房間伺服器,或者手動添加下方的地址的伺服器。
|
||||
|
||||
datapack=資料包
|
||||
|
||||
@@ -642,6 +642,7 @@ multiplayer.state.disconnected=未创建/加入房间
|
||||
multiplayer.state.disconnected.hint=多人联机功能需要先有一位玩家创建房间后,其他玩家加入房间后继续游戏。
|
||||
multiplayer.state.master=你已创建房间:%1$s,端口号 %2$d
|
||||
multiplayer.state.slave=你已加入房间: %1$s,地址为 %2$s
|
||||
multiplayer.state.slave.copy=拷贝地址
|
||||
multiplayer.state.slave.hint=加入房间后,你需要在 Minecraft 的多人游戏页面选择 HMCL 多人联机房间服务器,或者手动添加下方的地址的服务器。
|
||||
|
||||
datapack=数据包
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.multiplayer;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
|
||||
|
||||
public class LocalServerBroadcastTest {
|
||||
|
||||
@Test
|
||||
@Ignore("for manually testing")
|
||||
public void test() {
|
||||
int port = 12345;
|
||||
DatagramSocket socket;
|
||||
InetAddress broadcastAddress;
|
||||
try {
|
||||
socket = new DatagramSocket();
|
||||
broadcastAddress = InetAddress.getByName("224.0.2.60");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
byte[] data = String.format("[MOTD]%s[/MOTD][AD]%d[/AD]", i18n("multiplayer.session.name.motd", "Test server"), port).getBytes(StandardCharsets.UTF_8);
|
||||
DatagramPacket packet = new DatagramPacket(data, 0, data.length, broadcastAddress, 4445);
|
||||
socket.send(packet);
|
||||
System.out.println("Broadcast server 127.0.0.1:" + port);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(1500);
|
||||
} catch (InterruptedException ignored) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void printLocalAddress() throws IOException {
|
||||
DatagramSocket socket = new DatagramSocket(new InetSocketAddress((InetAddress) null, 4444));
|
||||
System.out.println(socket.getLocalAddress());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.ui.multiplayer;
|
||||
|
||||
import org.jackhuang.hmcl.util.Lang;
|
||||
import org.jackhuang.hmcl.util.Logging;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.SocketException;
|
||||
|
||||
public class LocalServerDetectorTest {
|
||||
|
||||
@Test
|
||||
@Ignore("for manually testing")
|
||||
public void test() {
|
||||
try {
|
||||
for (NetworkInterface networkInterface : Lang.toIterable(NetworkInterface.getNetworkInterfaces())) {
|
||||
System.out.println(networkInterface.getName());
|
||||
for (InetAddress address : Lang.toIterable(networkInterface.getInetAddresses())) {
|
||||
System.out.println(address);
|
||||
}
|
||||
}
|
||||
} catch (SocketException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Logging.initForTest();
|
||||
LocalServerDetector detector = new LocalServerDetector(3);
|
||||
detector.run();
|
||||
}
|
||||
}
|
||||
@@ -330,6 +330,25 @@ public final class Lang {
|
||||
return optional.map(Stream::of).orElseGet(Stream::empty);
|
||||
}
|
||||
|
||||
public static <T> Iterable<T> toIterable(Enumeration<T> enumeration) {
|
||||
if (enumeration == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
return () -> new Iterator<T>() {
|
||||
public boolean hasNext() {
|
||||
return enumeration.hasMoreElements();
|
||||
}
|
||||
|
||||
public T next() {
|
||||
return enumeration.nextElement();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> Iterable<T> toIterable(Stream<T> stream) {
|
||||
return stream::iterator;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
* Copyright (C) 2021 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -72,6 +72,16 @@ public final class Logging {
|
||||
LOG.addHandler(streamHandler);
|
||||
}
|
||||
|
||||
public static void initForTest() {
|
||||
LOG.setLevel(Level.ALL);
|
||||
LOG.setUseParentHandlers(false);
|
||||
|
||||
ConsoleHandler consoleHandler = new ConsoleHandler();
|
||||
consoleHandler.setFormatter(DefaultFormatter.INSTANCE);
|
||||
consoleHandler.setLevel(Level.FINER);
|
||||
LOG.addHandler(consoleHandler);
|
||||
}
|
||||
|
||||
public static byte[] getRawLogs() {
|
||||
return storedLogs.toByteArray();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user