Skip to content

Commit

Permalink
Merge remote-tracking branch 'private/playground/nethernet' into play…
Browse files Browse the repository at this point in the history
…ground/nethernet

# Conflicts:
#	core/src/main/java/com/rtm516/mcxboxbroadcast/core/webrtc/MinecraftDataHandler.java
  • Loading branch information
Tim203 committed Aug 21, 2024
2 parents 2feb504 + 419f7ca commit 67b4f05
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.rtm516.mcxboxbroadcast.manager;

import com.nukkitx.protocol.bedrock.BedrockClient;
import com.rtm516.mcxboxbroadcast.manager.database.model.Server;
import com.rtm516.mcxboxbroadcast.manager.database.repository.ServerCollection;
import com.rtm516.mcxboxbroadcast.manager.models.ServerContainer;
Expand All @@ -9,7 +8,6 @@
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
Expand All @@ -21,8 +19,6 @@ public class ServerManager {
private final BackendManager backendManager;
private final ServerCollection serverCollection;

private BedrockClient client;

@Autowired
public ServerManager(BackendManager backendManager, ServerCollection serverCollection) {
this.backendManager = backendManager;
Expand Down Expand Up @@ -85,28 +81,4 @@ public ObjectId firstServer() {

return addServer().server()._id();
}

/**
* Get the bedrock client for pinging or create a new one
*
* @return the bedrock client
*/
public BedrockClient bedrockClient() {
if (client != null && !client.getRakNet().isClosed()) {
return client;
}

try {
InetSocketAddress bindAddress = new InetSocketAddress("0.0.0.0", 0);
client = new BedrockClient(bindAddress);

client.bind().join();

return client;
} catch (Exception e) {
BackendManager.LOGGER.error("Error creating bedrock client for ping", e);
}

return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.rtm516.mcxboxbroadcast.manager.models;

import com.nukkitx.protocol.bedrock.BedrockPong;
import com.rtm516.mcxboxbroadcast.core.SessionInfo;
import com.rtm516.mcxboxbroadcast.core.ping.PingUtil;
import com.rtm516.mcxboxbroadcast.manager.ServerManager;
import com.rtm516.mcxboxbroadcast.manager.database.model.Server;
import com.rtm516.mcxboxbroadcast.manager.models.response.ServerInfoResponse;
import org.cloudburstmc.protocol.bedrock.BedrockPong;

import java.net.InetSocketAddress;
import java.util.Date;
Expand Down Expand Up @@ -57,15 +58,15 @@ public ServerInfoResponse toResponse() {
public void updateSessionInfo() {
try {
InetSocketAddress addressToPing = new InetSocketAddress(server.hostname(), server.port());
BedrockPong pong = serverManager.bedrockClient().ping(addressToPing, 1500, TimeUnit.MILLISECONDS).get();
BedrockPong pong = PingUtil.ping(addressToPing, 1500, TimeUnit.MILLISECONDS).get();

// Update the session information
sessionInfo.setHostName(pong.getMotd());
sessionInfo.setWorldName(pong.getSubMotd());
sessionInfo.setVersion(pong.getVersion());
sessionInfo.setProtocol(pong.getProtocolVersion());
sessionInfo.setPlayers(pong.getPlayerCount());
sessionInfo.setMaxPlayers(pong.getMaximumPlayerCount());
sessionInfo.setHostName(pong.motd());
sessionInfo.setWorldName(pong.subMotd());
sessionInfo.setVersion(pong.version());
sessionInfo.setProtocol(pong.protocolVersion());
sessionInfo.setPlayers(pong.playerCount());
sessionInfo.setMaxPlayers(pong.maximumPlayerCount());

// We only want to change this if the ping is successful so users can still join
sessionInfo.setIp(server.hostname());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.rtm516.mcxboxbroadcast.core.storage.FileStorageManager;
import org.cloudburstmc.protocol.bedrock.BedrockPong;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;

import java.io.File;
import java.io.FileOutputStream;
Expand All @@ -20,6 +21,7 @@
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.LogManager;

public class StandaloneMain {
private static StandaloneConfig config;
Expand All @@ -29,6 +31,10 @@ public class StandaloneMain {
public static SessionManager sessionManager;

public static void main(String[] args) throws Exception {
// Redirect all logging to SLF4J since ice4j uses java.util.logging
LogManager.getLogManager().reset();
SLF4JBridgeHandler.install();

logger = new StandaloneLoggerImpl(LoggerFactory.getLogger(StandaloneMain.class));

logger.info("Starting MCXboxBroadcast Standalone " + BuildData.VERSION);
Expand Down
12 changes: 10 additions & 2 deletions bootstrap/standalone/src/main/resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Configuration status="WARN">
<Appenders>
<TerminalConsole name="Console">
<PatternLayout pattern="[%d{HH:mm:ss} %style{%highlight{%level}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=cyan bright, DEBUG=green, TRACE=white}}] %style{%highlight{%msg}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=default, DEBUG=white dim, TRACE=white dim}}%n"/>
Expand All @@ -13,9 +13,17 @@
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Root level="DEBUG" >
<Root level="INFO" >
<AppenderRef ref="Console"/>
<AppenderRef ref="File"/>
</Root>

<!-- Disable logging for ice4j and jitsi -->
<Logger name="org.ice4j" level="OFF">
</Logger>
<Logger name="org.jitsi" level="OFF">
</Logger>
<Logger name="JitsiConfig" level="OFF">
</Logger>
</Loggers>
</Configuration>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id("com.rtm516.mcxboxbroadcast.java-conventions")
id("com.github.johnrengelman.shadow")
id("com.gradleup.shadow")
}

tasks {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.rtm516.mcxboxbroadcast.core.webrtc;

import com.rtm516.mcxboxbroadcast.core.Logger;
import com.rtm516.mcxboxbroadcast.core.SessionInfo;
import com.rtm516.mcxboxbroadcast.core.webrtc.bedrock.RedirectPacketHandler;
import com.rtm516.mcxboxbroadcast.core.webrtc.compression.CompressionHandler;
import com.rtm516.mcxboxbroadcast.core.webrtc.encryption.BedrockEncryptionEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import javax.crypto.SecretKey;
import org.bouncycastle.util.encoders.Hex;

import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
import org.cloudburstmc.protocol.bedrock.codec.BedrockCodecHelper;
import org.cloudburstmc.protocol.bedrock.data.PacketCompressionAlgorithm;
Expand All @@ -27,17 +28,19 @@ public class MinecraftDataHandler implements SCTPByteStreamListener {
private final BedrockCodec codec;
private final BedrockCodecHelper helper;
private final RedirectPacketHandler redirectPacketHandler;
private final Logger logger;

private CompressionHandler compressionHandler;
private BedrockEncryptionEncoder encryptionEncoder;

private ByteBuf concat;
private int expectedLength;

public MinecraftDataHandler(SCTPStream sctpStream, BedrockCodec codec, SessionInfo sessionInfo) {
public MinecraftDataHandler(SCTPStream sctpStream, BedrockCodec codec, SessionInfo sessionInfo, Logger logger) {
this.sctpStream = sctpStream;
this.codec = codec;
this.helper = codec.createHelper();
this.logger = logger.prefixed("MinecraftDataHandler");

this.redirectPacketHandler = new RedirectPacketHandler(this, sessionInfo);
}
Expand All @@ -54,7 +57,7 @@ public void onMessage(SCTPStream sctpStream, byte[] bytes) {
buf.writeBytes(bytes);

byte remainingSegments = buf.readByte();
System.out.println("first 100 bytes: " + Hex.toHexString(bytes, 0, Math.min(100, bytes.length)));
// System.out.println("first 100 bytes: " + Hex.toHexString(bytes, 0, Math.min(100, bytes.length)));

if (remainingSegments > 0) {
if (concat == null) {
Expand Down Expand Up @@ -88,27 +91,28 @@ public void onMessage(SCTPStream sctpStream, byte[] bytes) {
var packet = readPacket(buf);

if (!(packet instanceof LoginPacket)) {
System.out.println("C -> S: " + packet);
logger.debug("C -> S: " + packet);
} else {
// Don't log the contents of the login packet
logger.debug("C -> S: LoginPacket");
}

packet.handle(redirectPacketHandler);
} catch (Exception e) {
e.printStackTrace();
logger.error("Failed to handle packet from NetherNet", e);
}
}

@Override
public void onMessage(SCTPStream sctpStream, String s) {
System.out.println("string message (" + sctpStream.getLabel() + "): " + s);
}

@Override
public void close(SCTPStream sctpStream) {
System.out.println("stream closed: " + sctpStream.getLabel());
}

public void sendPacket(BedrockPacket packet) {
System.out.println("S -> C: " + packet);
logger.debug("S -> C: " + packet);
try {
ByteBuf dataBuf = Unpooled.buffer(128);
var shiftedBytes = 5; // leave enough room for data length
Expand All @@ -124,7 +128,7 @@ public void sendPacket(BedrockPacket packet) {

var lastPacketByte = dataBuf.writerIndex();
dataBuf.readerIndex(shiftedBytes);
System.out.println("packet: " + Hex.toHexString(encode(dataBuf)));
// System.out.println("packet: " + Hex.toHexString(encode(dataBuf)));

var packetLength = lastPacketByte - shiftedBytes;
// read from the first actual byte
Expand All @@ -139,14 +143,14 @@ public void sendPacket(BedrockPacket packet) {
}

var ri = dataBuf.readerIndex();
System.out.println("encoding: " + Hex.toHexString(encode(dataBuf)));
// System.out.println("encoding: " + Hex.toHexString(encode(dataBuf)));
dataBuf.readerIndex(ri);

if (encryptionEncoder != null) {
dataBuf = encryptionEncoder.encode(dataBuf);

ri = dataBuf.readerIndex();
System.out.println("encrypted: " + Hex.toHexString(encode(dataBuf)));
// System.out.println("encrypted: " + Hex.toHexString(encode(dataBuf)));
dataBuf.readerIndex(ri);
}

Expand All @@ -158,11 +162,11 @@ public void sendPacket(BedrockPacket packet) {
sendBuf.writeBytes(dataBuf, segmentLength);

var data = encode(sendBuf);
System.out.println("final: " + Hex.toHexString(data));
// System.out.println("final: " + Hex.toHexString(data));
sctpStream.send(data);
}
} catch (Exception e) {
e.printStackTrace();
logger.error("Failed to send packet to NetherNet", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,14 @@ public void receiveOffer(BigInteger from, String sessionId, String message) {
// Log.setLevel(Log.DEBUG);

// Log the remote public IP
component.getRemoteCandidates().forEach(remoteCandidate -> {
if (remoteCandidate.getType() == CandidateType.SERVER_REFLEXIVE_CANDIDATE) {
System.out.println("Remote public IP: " + remoteCandidate.getTransportAddress().getHostAddress());
}
});
// component.getRemoteCandidates().forEach(remoteCandidate -> {
// if (remoteCandidate.getType() == CandidateType.SERVER_REFLEXIVE_CANDIDATE) {
// System.out.println("Remote public IP: " + remoteCandidate.getTransportAddress().getHostAddress());
// }
// });

// TODO Pass some form of close handler to the association so we can clean up properly in the RtcWebsocketClient
new ThreadedAssociation(dtlsTransport, new SctpAssociationListener(rtcWebsocket.sessionInfo(), () -> {
new ThreadedAssociation(dtlsTransport, new SctpAssociationListener(rtcWebsocket.sessionInfo(), rtcWebsocket.logger(), () -> {
try {
dtlsTransport.close();
agent.free();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ private void handleCandidateAdd(String sessionId, String message) {
}

public void handleDisconnect(String sessionId) {
System.out.println("Disconnecting session: " + sessionId);
logger.debug("Disconnecting session: " + sessionId);
activeSessions.remove(sessionId);
}

Expand Down Expand Up @@ -175,4 +175,8 @@ public void onError(Exception ex) {
public SessionInfo sessionInfo() {
return sessionInfo;
}

public Logger logger() {
return logger;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.rtm516.mcxboxbroadcast.core.webrtc;

import com.rtm516.mcxboxbroadcast.core.Logger;
import com.rtm516.mcxboxbroadcast.core.SessionInfo;
import org.cloudburstmc.protocol.bedrock.codec.v712.Bedrock_v712;
import pe.pi.sctp4j.sctp.Association;
Expand All @@ -9,20 +10,22 @@
public class SctpAssociationListener implements AssociationListener {
private final SessionInfo sessionInfo;
private final Runnable onDisconnect;
private final Logger logger;

public SctpAssociationListener(SessionInfo sessionInfo, Runnable onDisconnect) {
public SctpAssociationListener(SessionInfo sessionInfo, Logger logger, Runnable onDisconnect) {
this.sessionInfo = sessionInfo;
this.logger = logger.prefixed("SctpAssociationListener");
this.onDisconnect = onDisconnect;
}

@Override
public void onAssociated(Association association) {
System.out.println("Association associated: " + association.toString());
// System.out.println("Association associated: " + association.toString());
}

@Override
public void onDisAssociated(Association association) {
System.out.println("Association disassociated: " + association.toString());
// System.out.println("Association disassociated: " + association.toString());
onDisconnect.run();
}

Expand All @@ -31,15 +34,15 @@ public void onDCEPStream(SCTPStream sctpStream, String label, int i) throws Exce
if (label == null) {
return;
}
System.out.println("Received DCEP SCTP stream: " + sctpStream.toString());
logger.debug("Received DCEP SCTP stream: " + sctpStream.toString());

if ("ReliableDataChannel".equals(label)) {
sctpStream.setSCTPStreamListener(new MinecraftDataHandler(sctpStream, Bedrock_v712.CODEC, sessionInfo));
sctpStream.setSCTPStreamListener(new MinecraftDataHandler(sctpStream, Bedrock_v712.CODEC, sessionInfo, logger));
}
}

@Override
public void onRawStream(SCTPStream sctpStream) {
System.out.println("Received raw SCTP stream: " + sctpStream.toString());
// System.out.println("Received raw SCTP stream: " + sctpStream.toString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public void sendStartGame() {

startGamePacket.setServerEngine("");
startGamePacket.setLevelId("");
startGamePacket.setLevelName("GlobalLinkServer");
startGamePacket.setLevelName("MCXboxBroadcast");
startGamePacket.setPremiumWorldTemplateId("");
startGamePacket.setWorldTemplateId(new UUID(0, 0));
startGamePacket.setCurrentTick(0);
Expand Down
Loading

0 comments on commit 67b4f05

Please sign in to comment.