From 0f56376dbcce96a2afd1c48030d81ad736fa1e9b Mon Sep 17 00:00:00 2001 From: BlueDemonTR <83763146+BlueDemonTR@users.noreply.github.com> Date: Wed, 22 Apr 2026 15:06:11 +0300 Subject: [PATCH 1/2] enable so_resureport Co-Authored-By: Ashtral <69469869+ashtr4l@users.noreply.github.com> --- .../java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java | 2 ++ .../sable/mixin/udp/ServerConnectionListenerMixin.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java index 80a8722b..ef0fb4c6 100644 --- a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java +++ b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java @@ -9,6 +9,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.epoll.Epoll; +import io.netty.channel.epoll.EpollChannelOption; import io.netty.channel.epoll.EpollDatagramChannel; import io.netty.channel.local.LocalChannel; import io.netty.channel.socket.nio.NioDatagramChannel; @@ -83,6 +84,7 @@ protected void initChannel(final Channel channel) { } }) .channel(channelClass) + .option(EpollChannelOption.SO_REUSEPORT, true) .connect(inetSocketAddress.getAddress(), inetSocketAddress.getPort()); channelFuture.syncUninterruptibly(); diff --git a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java index f3df9e77..77d358e1 100644 --- a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java +++ b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java @@ -9,6 +9,7 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.epoll.Epoll; +import io.netty.channel.epoll.EpollChannelOption; import io.netty.channel.epoll.EpollDatagramChannel; import io.netty.channel.local.LocalAddress; import io.netty.channel.local.LocalServerChannel; @@ -67,6 +68,7 @@ public class ServerConnectionListenerMixin implements ServerConnectionListenerEx this.channels.add(new Bootstrap() .channel(channelClass) .option(ChannelOption.SO_BROADCAST, true) + .option(EpollChannelOption.SO_REUSEPORT, true) .handler(new ChannelInitializer<>() { @Override protected void initChannel(final Channel channel) { @@ -93,6 +95,7 @@ protected void initChannel(final Channel channel) { this.channels.add(new Bootstrap() .channel(LocalServerChannel.class) .option(ChannelOption.SO_BROADCAST, true) + .option(EpollChannelOption.SO_REUSEPORT, true) .handler(new ChannelInitializer<>() { @Override protected void initChannel(final Channel channel) { From e6f2b647e70e3fdcd577848004749a921cb9de3a Mon Sep 17 00:00:00 2001 From: BlueDemonTR <83763146+BlueDemonTR@users.noreply.github.com> Date: Wed, 22 Apr 2026 20:59:49 +0300 Subject: [PATCH 2/2] add udp port control from config --- .../java/dev/ryanhcode/sable/SableConfig.java | 5 +++++ .../sable/mixin/udp/ConnectionMixin.java | 5 ++--- .../mixin/udp/ServerConnectionListenerMixin.java | 4 +--- .../tcp/ClientboundSableUDPActivationPacket.java | 6 +++++- .../udp/SableUDPClientboundKeepAlivePacket.java | 5 ++++- .../sable/network/udp/SableUDPServer.java | 15 +++++++++++++++ 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/dev/ryanhcode/sable/SableConfig.java b/common/src/main/java/dev/ryanhcode/sable/SableConfig.java index 27f47dbd..4c3ff887 100644 --- a/common/src/main/java/dev/ryanhcode/sable/SableConfig.java +++ b/common/src/main/java/dev/ryanhcode/sable/SableConfig.java @@ -17,6 +17,8 @@ public final class SableConfig { public static final ModConfigSpec.IntValue SUB_LEVEL_PUNCH_COOLDOWN_TICKS; public static final ModConfigSpec.BooleanValue DISABLE_UDP_PIPELINE; public static final ModConfigSpec.BooleanValue ATTEMPT_UDP_NETWORKING; + public static final ModConfigSpec.IntValue UDP_LISTEN_PORT; + static { final ModConfigSpec.Builder builder = new ModConfigSpec.Builder(); @@ -56,6 +58,9 @@ public final class SableConfig { ATTEMPT_UDP_NETWORKING = builder .comment("If Sable should attempt to authenticate with clients and send them sub-level data over UDP") .define("attempt_udp_networking", true); + UDP_LISTEN_PORT = builder + .comment("The port Sable will use when sending data over UDP (-1 = The Minecraft Server Instance Port)") + .defineInRange("udp_listen_port", -1, -1, 65535); SPEC = builder.build(); } diff --git a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java index ef0fb4c6..5d25ea16 100644 --- a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java +++ b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ConnectionMixin.java @@ -5,11 +5,11 @@ import dev.ryanhcode.sable.SableClient; import dev.ryanhcode.sable.mixinterface.udp.ConnectionExtension; import dev.ryanhcode.sable.network.udp.SableUDPPacket; +import dev.ryanhcode.sable.network.udp.SableUDPServer; import dev.ryanhcode.sable.network.udp.handler.SableUDPChannelHandlerClient; import io.netty.bootstrap.Bootstrap; import io.netty.channel.*; import io.netty.channel.epoll.Epoll; -import io.netty.channel.epoll.EpollChannelOption; import io.netty.channel.epoll.EpollDatagramChannel; import io.netty.channel.local.LocalChannel; import io.netty.channel.socket.nio.NioDatagramChannel; @@ -84,8 +84,7 @@ protected void initChannel(final Channel channel) { } }) .channel(channelClass) - .option(EpollChannelOption.SO_REUSEPORT, true) - .connect(inetSocketAddress.getAddress(), inetSocketAddress.getPort()); + .connect(inetSocketAddress.getAddress(), SableUDPServer.getUDPPort(inetSocketAddress.getPort())); channelFuture.syncUninterruptibly(); } diff --git a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java index 77d358e1..ab4e3733 100644 --- a/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java +++ b/common/src/main/java/dev/ryanhcode/sable/mixin/udp/ServerConnectionListenerMixin.java @@ -68,7 +68,6 @@ public class ServerConnectionListenerMixin implements ServerConnectionListenerEx this.channels.add(new Bootstrap() .channel(channelClass) .option(ChannelOption.SO_BROADCAST, true) - .option(EpollChannelOption.SO_REUSEPORT, true) .handler(new ChannelInitializer<>() { @Override protected void initChannel(final Channel channel) { @@ -77,7 +76,7 @@ protected void initChannel(final Channel channel) { } }) .group(eventLoopGroup) - .localAddress(inetAddress, port) + .localAddress(inetAddress, SableUDPServer.getUDPPort(port)) .bind() .syncUninterruptibly()); } @@ -95,7 +94,6 @@ protected void initChannel(final Channel channel) { this.channels.add(new Bootstrap() .channel(LocalServerChannel.class) .option(ChannelOption.SO_BROADCAST, true) - .option(EpollChannelOption.SO_REUSEPORT, true) .handler(new ChannelInitializer<>() { @Override protected void initChannel(final Channel channel) { diff --git a/common/src/main/java/dev/ryanhcode/sable/network/packets/tcp/ClientboundSableUDPActivationPacket.java b/common/src/main/java/dev/ryanhcode/sable/network/packets/tcp/ClientboundSableUDPActivationPacket.java index 14c05ac1..fc764f4b 100644 --- a/common/src/main/java/dev/ryanhcode/sable/network/packets/tcp/ClientboundSableUDPActivationPacket.java +++ b/common/src/main/java/dev/ryanhcode/sable/network/packets/tcp/ClientboundSableUDPActivationPacket.java @@ -5,6 +5,7 @@ import dev.ryanhcode.sable.network.packets.udp.SableUDPAuthenticationPacket; import dev.ryanhcode.sable.network.tcp.SableTCPPacket; import dev.ryanhcode.sable.network.udp.AddressedSableUDPPacket; +import dev.ryanhcode.sable.network.udp.SableUDPServer; import foundry.veil.api.network.handler.PacketContext; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -44,7 +45,10 @@ public void handle(final PacketContext context) { final Channel channel = connectionExtension.sable$getUDPChannel(); final InetSocketAddress baseAddress = ((InetSocketAddress) connection.getRemoteAddress()); - final InetSocketAddress remoteAddress = new InetSocketAddress(baseAddress.getAddress(), baseAddress.getPort()); + final InetSocketAddress remoteAddress = new InetSocketAddress( + baseAddress.getAddress(), + SableUDPServer.getUDPPort(baseAddress.getPort()) + ); Sable.LOGGER.info("Received authentication request, sending response over UDP to {}", remoteAddress); diff --git a/common/src/main/java/dev/ryanhcode/sable/network/packets/udp/SableUDPClientboundKeepAlivePacket.java b/common/src/main/java/dev/ryanhcode/sable/network/packets/udp/SableUDPClientboundKeepAlivePacket.java index c4990411..b1492671 100644 --- a/common/src/main/java/dev/ryanhcode/sable/network/packets/udp/SableUDPClientboundKeepAlivePacket.java +++ b/common/src/main/java/dev/ryanhcode/sable/network/packets/udp/SableUDPClientboundKeepAlivePacket.java @@ -4,6 +4,7 @@ import dev.ryanhcode.sable.network.udp.AddressedSableUDPPacket; import dev.ryanhcode.sable.network.udp.SableUDPPacket; import dev.ryanhcode.sable.network.udp.SableUDPPacketType; +import dev.ryanhcode.sable.network.udp.SableUDPServer; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; @@ -30,7 +31,9 @@ public void handleClient(final Level level) { final Channel channel = connectionExtension.sable$getUDPChannel(); final InetSocketAddress baseAddress = ((InetSocketAddress) connection.getRemoteAddress()); - final InetSocketAddress remoteAddress = new InetSocketAddress(baseAddress.getAddress(), baseAddress.getPort()); + final InetSocketAddress remoteAddress = new InetSocketAddress( + baseAddress.getAddress(), + SableUDPServer.getUDPPort(baseAddress.getPort())); channel.eventLoop().execute(() -> { final SableUDPServerboundAlivePacket packet = new SableUDPServerboundAlivePacket(); diff --git a/common/src/main/java/dev/ryanhcode/sable/network/udp/SableUDPServer.java b/common/src/main/java/dev/ryanhcode/sable/network/udp/SableUDPServer.java index d17dce80..933243f0 100644 --- a/common/src/main/java/dev/ryanhcode/sable/network/udp/SableUDPServer.java +++ b/common/src/main/java/dev/ryanhcode/sable/network/udp/SableUDPServer.java @@ -17,6 +17,7 @@ import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.common.ModConfigSpec; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -52,6 +53,20 @@ public static SableUDPServer getServer(final MinecraftServer server) { return (((ServerConnectionListenerExtension) server.getConnection())).sable$getServer(); } + /** + * Returns the port that will be used by the UDP server + * + * @param _default the socket that will be used in the case where the port in config is set to -1 + * @return the port that will be used by the UDP server + */ + public static Integer getUDPPort(final int _default) { + final int fromConfig = SableConfig.UDP_LISTEN_PORT.getAsInt(); + + if(fromConfig == -1) return _default; + + return fromConfig; + } + /*@Override public void flushUDP() { if (this.udpChannel.eventLoop().inEventLoop())