Skip to content

Commit 2ca9a55

Browse files
committed
Fix motd broadcast and use native netty transports
1 parent c0b8d45 commit 2ca9a55

File tree

3 files changed

+36
-29
lines changed

3 files changed

+36
-29
lines changed

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ fastutil-short-sets = { group = "org.cloudburstmc.fastutil.sets", name = "short-
5656
fastutil-short-object-maps = { group = "org.cloudburstmc.fastutil.maps", name = "short-object-maps", version.ref = "fastutil" }
5757

5858
bedrock-connection = { group = "org.cloudburstmc.protocol", name = "bedrock-connection", version = "3.0.0.Beta12-20260209.180455-4" }
59+
netty-transport-native-epoll = { group = "io.netty", name = "netty-transport-native-epoll", version = "4.1.101.Final" }
60+
netty-transport-native-kqueue = { group = "io.netty", name = "netty-transport-native-kqueue", version = "4.1.101.Final" }
5961
block-state-updater = { group = "org.cloudburstmc", name = "block-state-updater", version = "1.21.110-SNAPSHOT" }
6062
jopt-simple = { group = "net.sf.jopt-simple", name = "jopt-simple", version = "5.0.4" }
6163
leveldb-mcpe-jni = { group = "net.daporkchop", name = "leveldb-mcpe-jni", version = "0.0.10-SNAPSHOT" }

server/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ dependencies {
1515
api(libs.bedrock.connection) {
1616
exclude("com.nukkitx.fastutil")
1717
}
18+
compileOnly(libs.netty.transport.native.epoll)
19+
compileOnly(libs.netty.transport.native.kqueue)
20+
runtimeOnly(libs.netty.transport.native.epoll) { artifact { classifier = "linux-x86_64" } }
21+
runtimeOnly(libs.netty.transport.native.kqueue) { artifact { classifier = "osx-x86_64" } }
1822
api(libs.block.state.updater)
1923
api(libs.bundles.fastutil)
2024
api(libs.leveldb.mcpe.jni)

server/src/main/java/org/cloudburstmc/server/network/BedrockInterface.java

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44
import io.netty.buffer.ByteBuf;
55
import io.netty.channel.Channel;
66
import io.netty.channel.EventLoopGroup;
7+
import io.netty.channel.epoll.Epoll;
8+
import io.netty.channel.epoll.EpollDatagramChannel;
9+
import io.netty.channel.epoll.EpollEventLoopGroup;
10+
import io.netty.channel.kqueue.KQueue;
11+
import io.netty.channel.kqueue.KQueueDatagramChannel;
12+
import io.netty.channel.kqueue.KQueueEventLoopGroup;
713
import io.netty.channel.nio.NioEventLoopGroup;
14+
import io.netty.channel.socket.DatagramChannel;
815
import io.netty.channel.socket.nio.NioDatagramChannel;
916
import lombok.extern.log4j.Log4j2;
1017
import org.cloudburstmc.api.event.server.QueryRegenerateEvent;
@@ -29,17 +36,30 @@
2936
public class BedrockInterface implements AdvancedSourceInterface {
3037

3138
private final CloudServer server;
32-
3339
private final EventLoopGroup eventLoopGroup;
3440
private final List<Channel> channels = new ArrayList<>();
3541
private final BedrockPong advertisement = new BedrockPong();
3642

37-
public BedrockInterface(CloudServer server) throws Exception {
43+
public BedrockInterface(CloudServer server) {
3844
this.server = server;
3945

40-
this.eventLoopGroup = new NioEventLoopGroup();
46+
Class<? extends DatagramChannel> datagramChannelClass;
47+
if (Epoll.isAvailable()) {
48+
this.eventLoopGroup = new EpollEventLoopGroup();
49+
datagramChannelClass = EpollDatagramChannel.class;
50+
log.debug("Using Epoll transport");
51+
} else if (KQueue.isAvailable()) {
52+
this.eventLoopGroup = new KQueueEventLoopGroup();
53+
datagramChannelClass = KQueueDatagramChannel.class;
54+
log.debug("Using KQueue transport");
55+
} else {
56+
this.eventLoopGroup = new NioEventLoopGroup();
57+
datagramChannelClass = NioDatagramChannel.class;
58+
log.debug("Using NIO transport");
59+
}
60+
4161
ServerBootstrap bootstrap = new ServerBootstrap()
42-
.channelFactory(RakChannelFactory.server(NioDatagramChannel.class)) // TODO: Epoll, KQueue and IO Uring support
62+
.channelFactory(RakChannelFactory.server(datagramChannelClass))
4363
.group(this.eventLoopGroup)
4464
.childHandler(new BedrockServerInitializer() {
4565
@Override
@@ -79,7 +99,7 @@ public void sendRawPacket(InetSocketAddress socketAddress, ByteBuf payload) {
7999
@Override
80100
public void setName(String name) {
81101
QueryRegenerateEvent info = this.server.getQueryInformation();
82-
String[] names = name.split("!@#"); //Split double names within the program
102+
String[] names = name.split("!@#"); // Split double names within the program
83103
String motd = Utils.rtrim(names[0].replace(";", "\\;"), '\\');
84104
String subMotd = names.length > 1 ? Utils.rtrim(names[1].replace(";", "\\;"), '\\') : "";
85105
String gm = this.server.getDefaultGamemode().getName();
@@ -89,10 +109,12 @@ public void setName(String name) {
89109
.subMotd(subMotd.trim().isEmpty() ? "Cloudburst" : subMotd)
90110
.playerCount(info.getPlayerCount())
91111
.maximumPlayerCount(info.getMaxPlayerCount())
92-
.version("1")
93-
.protocolVersion(0)
112+
.version(ProtocolInfo.getDefaultMinecraftVersion())
113+
.protocolVersion(ProtocolInfo.getDefaultProtocolVersion())
94114
.gameType(gm.substring(0, 1).toUpperCase() + gm.substring(1))
95-
.nintendoLimited(false);
115+
.nintendoLimited(false)
116+
.ipv4Port(this.server.getPort())
117+
.serverId(this.server.getServerUniqueId().getMostSignificantBits());
96118

97119
for (Channel channel : this.channels) {
98120
channel.config().setOption(RakChannelOption.RAK_ADVERTISEMENT, this.advertisement.toByteBuf());
@@ -101,10 +123,6 @@ public void setName(String name) {
101123

102124
@Override
103125
public boolean process() {
104-
// NukkitSessionListener listener;
105-
// while ((listener = disconnectQueue.poll()) != null) {
106-
// listener.player.close(listener.player.getLeaveMessage(), listener.disconnectReason, false);
107-
// }
108126
return true;
109127
}
110128

@@ -120,21 +138,4 @@ public void shutdown() {
120138
public void emergencyShutdown() {
121139
this.shutdown();
122140
}
123-
//
124-
// @RequiredArgsConstructor
125-
// private class NukkitSessionListener implements Consumer<DisconnectReason> {
126-
// private final CloudPlayer player;
127-
// private String disconnectReason = null;
128-
//
129-
// @Override
130-
// public void accept(DisconnectReason disconnectReason) {
131-
// if (disconnectReason == DisconnectReason.TIMED_OUT) {
132-
// this.disconnectReason = "Timed out";
133-
// } else {
134-
// this.disconnectReason = "Disconnected from Server";
135-
// }
136-
// // Queue for disconnect on main thread.
137-
// BedrockInterface.this.disconnectQueue.add(this);
138-
// }
139-
// }
140141
}

0 commit comments

Comments
 (0)