Skip to content

Commit 1044b97

Browse files
committed
Refactored bedrock status ping handling
1 parent 25ae33c commit 1044b97

File tree

5 files changed

+69
-49
lines changed

5 files changed

+69
-49
lines changed

src/main/java/net/raphimc/viaproxy/protocoltranslator/providers/ViaProxyNettyPipelineProvider.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import io.netty.channel.Channel;
2323
import net.raphimc.netminecraft.constants.MCPipeline;
2424
import net.raphimc.viabedrock.api.io.compression.ProtocolCompression;
25-
import net.raphimc.viabedrock.netty.AesEncryptionCodec;
2625
import net.raphimc.viabedrock.netty.CompressionCodec;
26+
import net.raphimc.viabedrock.netty.raknet.AesEncryptionCodec;
2727
import net.raphimc.viabedrock.protocol.provider.NettyPipelineProvider;
2828
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
2929

@@ -57,7 +57,7 @@ public void enableEncryption(UserConnection user, SecretKey key) {
5757
}
5858

5959
try {
60-
channel.pipeline().addAfter(VLPipeline.VIABEDROCK_FRAME_ENCAPSULATION_HANDLER_NAME, MCPipeline.ENCRYPTION_HANDLER_NAME, new AesEncryptionCodec(key));
60+
channel.pipeline().addAfter(VLPipeline.VIABEDROCK_RAKNET_MESSAGE_CODEC_NAME, MCPipeline.ENCRYPTION_HANDLER_NAME, new AesEncryptionCodec(key));
6161
} catch (Throwable e) {
6262
throw new RuntimeException(e);
6363
}

src/main/java/net/raphimc/viaproxy/proxy/client2proxy/Client2ProxyHandler.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,15 @@
4343
import net.raphimc.viaproxy.proxy.packethandler.*;
4444
import net.raphimc.viaproxy.proxy.proxy2server.Proxy2ServerChannelInitializer;
4545
import net.raphimc.viaproxy.proxy.proxy2server.Proxy2ServerHandler;
46-
import net.raphimc.viaproxy.proxy.session.BedrockProxyConnection;
47-
import net.raphimc.viaproxy.proxy.session.DummyProxyConnection;
48-
import net.raphimc.viaproxy.proxy.session.ProxyConnection;
49-
import net.raphimc.viaproxy.proxy.session.UserOptions;
46+
import net.raphimc.viaproxy.proxy.session.*;
5047
import net.raphimc.viaproxy.proxy.util.*;
5148
import net.raphimc.viaproxy.saves.impl.accounts.ClassicAccount;
5249
import net.raphimc.viaproxy.util.*;
5350
import net.raphimc.viaproxy.util.logging.Logger;
5451

5552
import java.net.ConnectException;
5653
import java.net.InetSocketAddress;
54+
import java.net.PortUnreachableException;
5755
import java.net.SocketAddress;
5856
import java.nio.channels.UnresolvedAddressException;
5957
import java.util.List;
@@ -206,7 +204,7 @@ private void handleHandshake(final C2SHandshakingClientIntentionPacket packet) {
206204
final ProtocolVersion detectedVersion = ProtocolVersionDetector.get(finalServerAddress, clientVersion);
207205
this.connect(finalServerAddress, detectedVersion, clientVersion, packet.intendedState, finalClientHandshakeAddress, userOptions, handshakeParts);
208206
}).exceptionally(t -> {
209-
if (t instanceof ConnectException || t instanceof UnresolvedAddressException) {
207+
if (t instanceof ConnectException || t instanceof UnresolvedAddressException || t instanceof PortUnreachableException) {
210208
this.proxyConnection.kickClient("§cCould not connect to the backend server!");
211209
} else {
212210
this.proxyConnection.kickClient("§cAutomatic protocol detection failed!\n§c" + t.getMessage());
@@ -222,7 +220,11 @@ private void connect(final SocketAddress serverAddress, final ProtocolVersion se
222220
final Supplier<ChannelHandler> handlerSupplier = () -> ViaProxy.EVENT_MANAGER.call(new Proxy2ServerHandlerCreationEvent(new Proxy2ServerHandler(), false)).getHandler();
223221
final ProxyConnection proxyConnection;
224222
if (serverVersion.equals(BedrockProtocolVersion.bedrockLatest)) {
225-
proxyConnection = new BedrockProxyConnection(new Proxy2ServerChannelInitializer(handlerSupplier), this.proxyConnection.getC2P());
223+
if (intendedState != IntendedState.STATUS) {
224+
proxyConnection = new BedrockProxyConnection(new Proxy2ServerChannelInitializer(handlerSupplier), this.proxyConnection.getC2P());
225+
} else {
226+
proxyConnection = new BedrockStatusProxyConnection(new Proxy2ServerChannelInitializer(handlerSupplier), this.proxyConnection.getC2P());
227+
}
226228
} else {
227229
proxyConnection = new ProxyConnection(new Proxy2ServerChannelInitializer(handlerSupplier), this.proxyConnection.getC2P());
228230
}
@@ -302,7 +304,7 @@ private void connect(final SocketAddress serverAddress, final ProtocolVersion se
302304
}
303305
}, (ThrowingChannelFutureListener) f -> {
304306
if (!f.isSuccess()) {
305-
if (f.cause() instanceof ConnectException || f.cause() instanceof UnresolvedAddressException) {
307+
if (f.cause() instanceof ConnectException || f.cause() instanceof UnresolvedAddressException || f.cause() instanceof PortUnreachableException) {
306308
this.proxyConnection.kickClient("§cCould not connect to the backend server!");
307309
} else {
308310
Logger.LOGGER.error("Error while connecting to the backend server", f.cause());

src/main/java/net/raphimc/viaproxy/proxy/proxy2server/Proxy2ServerChannelInitializer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@
2424
import io.netty.channel.Channel;
2525
import io.netty.channel.ChannelHandler;
2626
import io.netty.handler.codec.haproxy.HAProxyMessageEncoder;
27+
import net.raphimc.netminecraft.constants.ConnectionState;
2728
import net.raphimc.netminecraft.constants.MCPipeline;
2829
import net.raphimc.netminecraft.netty.codec.NoReadFlowControlHandler;
2930
import net.raphimc.netminecraft.netty.connection.MinecraftChannelInitializer;
3031
import net.raphimc.netminecraft.packet.registry.DefaultPacketRegistry;
3132
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
33+
import net.raphimc.viabedrock.netty.util.DatagramCodec;
34+
import net.raphimc.viabedrock.protocol.RakNetStatusProtocol;
3235
import net.raphimc.viaproxy.ViaProxy;
3336
import net.raphimc.viaproxy.plugins.events.Proxy2ServerChannelInitializeEvent;
3437
import net.raphimc.viaproxy.plugins.events.types.ITyped;
@@ -73,6 +76,13 @@ protected void initChannel(Channel channel) {
7376
if (proxyConnection.getServerVersion().equals(BedrockProtocolVersion.bedrockLatest)) {
7477
channel.pipeline().remove(MCPipeline.COMPRESSION_HANDLER_NAME);
7578
channel.pipeline().remove(MCPipeline.ENCRYPTION_HANDLER_NAME);
79+
80+
if (proxyConnection.getC2pConnectionState() == ConnectionState.STATUS) {
81+
channel.pipeline().remove(MCPipeline.SIZER_HANDLER_NAME);
82+
channel.pipeline().remove(VLPipeline.VIABEDROCK_PACKET_CODEC_NAME);
83+
channel.pipeline().replace(VLPipeline.VIABEDROCK_RAKNET_MESSAGE_CODEC_NAME, "viabedrock-datagram-codec", new DatagramCodec());
84+
user.getProtocolInfo().getPipeline().add(RakNetStatusProtocol.INSTANCE);
85+
}
7686
}
7787

7888
if (ViaProxy.EVENT_MANAGER.call(new Proxy2ServerChannelInitializeEvent(ITyped.Type.POST, channel, false)).isCancelled()) {

src/main/java/net/raphimc/viaproxy/proxy/session/BedrockProxyConnection.java

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,23 @@
1717
*/
1818
package net.raphimc.viaproxy.proxy.session;
1919

20-
import com.viaversion.vialoader.netty.VLPipeline;
21-
import com.viaversion.vialoader.netty.viabedrock.RakNetPingEncapsulationCodec;
22-
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
2320
import io.netty.bootstrap.Bootstrap;
2421
import io.netty.channel.Channel;
25-
import io.netty.channel.ChannelFuture;
2622
import io.netty.channel.ChannelInitializer;
2723
import io.netty.channel.ChannelOption;
2824
import io.netty.channel.socket.DatagramChannel;
29-
import net.lenni0451.reflect.stream.RStream;
30-
import net.raphimc.netminecraft.constants.ConnectionState;
31-
import net.raphimc.netminecraft.constants.MCPipeline;
3225
import net.raphimc.netminecraft.util.EventLoops;
3326
import net.raphimc.netminecraft.util.TransportType;
3427
import net.raphimc.viabedrock.protocol.data.ProtocolConstants;
3528
import net.raphimc.viaproxy.ViaProxy;
3629
import org.cloudburstmc.netty.channel.raknet.RakChannelFactory;
3730
import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption;
3831

39-
import java.net.InetSocketAddress;
40-
import java.net.SocketAddress;
4132
import java.util.concurrent.ThreadLocalRandom;
4233

4334
public class BedrockProxyConnection extends ProxyConnection {
4435

45-
public BedrockProxyConnection(final ChannelInitializer<Channel> channelInitializer, Channel c2p) {
36+
public BedrockProxyConnection(final ChannelInitializer<Channel> channelInitializer, final Channel c2p) {
4637
super(channelInitializer, c2p);
4738
}
4839

@@ -51,12 +42,13 @@ public void initialize(TransportType transportType, final Bootstrap bootstrap) {
5142
if (!DatagramChannel.class.isAssignableFrom(transportType.udpClientChannelClass())) {
5243
throw new IllegalArgumentException("Channel type must be a DatagramChannel");
5344
}
54-
if (transportType == TransportType.KQUEUE) transportType = TransportType.NIO; // KQueue doesn't work for Bedrock for some reason
55-
final Class<? extends DatagramChannel> channelClass = (Class<? extends DatagramChannel>) transportType.udpClientChannelClass();
45+
if (transportType == TransportType.KQUEUE) {
46+
transportType = TransportType.NIO; // KQueue doesn't work for some reason
47+
}
5648

5749
bootstrap
5850
.group(EventLoops.getClientEventLoop(transportType))
59-
.channelFactory(RakChannelFactory.client(channelClass))
51+
.channelFactory(RakChannelFactory.client((Class<? extends DatagramChannel>) transportType.udpClientChannelClass()))
6052
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ViaProxy.getConfig().getConnectTimeout())
6153
.option(RakChannelOption.RAK_PROTOCOL_VERSION, ProtocolConstants.BEDROCK_RAKNET_PROTOCOL_VERSION)
6254
.option(RakChannelOption.RAK_COMPATIBILITY_MODE, true)
@@ -75,31 +67,4 @@ public void initialize(TransportType transportType, final Bootstrap bootstrap) {
7567
}*/
7668
}
7769

78-
@Override
79-
public ChannelFuture connectToServer(final SocketAddress serverAddress, final ProtocolVersion targetVersion) {
80-
if (!(serverAddress instanceof InetSocketAddress)) {
81-
throw new IllegalArgumentException("Server address must be an InetSocketAddress");
82-
}
83-
84-
if (this.getC2pConnectionState() == ConnectionState.STATUS) {
85-
RStream.of(this).withSuper().fields().by("serverAddress").set(serverAddress);
86-
RStream.of(this).withSuper().fields().by("serverVersion").set(targetVersion);
87-
return this.ping(serverAddress);
88-
} else {
89-
return super.connectToServer(serverAddress, targetVersion);
90-
}
91-
}
92-
93-
private ChannelFuture ping(final SocketAddress address) {
94-
if (this.channelFuture == null) this.initialize(TransportType.getBest(address), new Bootstrap());
95-
96-
this.channelFuture.channel().eventLoop().submit(() -> {
97-
this.getChannel().pipeline().replace(VLPipeline.VIABEDROCK_FRAME_ENCAPSULATION_HANDLER_NAME, "ping_encapsulation", new RakNetPingEncapsulationCodec(((InetSocketAddress) address)));
98-
this.getChannel().pipeline().remove(VLPipeline.VIABEDROCK_PACKET_ENCAPSULATION_HANDLER_NAME);
99-
this.getChannel().pipeline().remove(MCPipeline.SIZER_HANDLER_NAME);
100-
});
101-
102-
return this.getChannel().bind(new InetSocketAddress(0));
103-
}
104-
10570
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This file is part of ViaProxy - https://github.com/RaphiMC/ViaProxy
3+
* Copyright (C) 2021-2025 RK_01/RaphiMC and contributors
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
package net.raphimc.viaproxy.proxy.session;
19+
20+
import io.netty.bootstrap.Bootstrap;
21+
import io.netty.channel.Channel;
22+
import io.netty.channel.ChannelInitializer;
23+
import net.raphimc.netminecraft.util.EventLoops;
24+
import net.raphimc.netminecraft.util.TransportType;
25+
26+
public class BedrockStatusProxyConnection extends ProxyConnection {
27+
28+
public BedrockStatusProxyConnection(final ChannelInitializer<Channel> channelInitializer, final Channel c2p) {
29+
super(channelInitializer, c2p);
30+
}
31+
32+
@Override
33+
public void initialize(final TransportType transportType, final Bootstrap bootstrap) {
34+
bootstrap
35+
.group(EventLoops.getClientEventLoop(transportType))
36+
.channel(transportType.udpClientChannelClass())
37+
.attr(ProxyConnection.PROXY_CONNECTION_ATTRIBUTE_KEY, this)
38+
.handler(this.channelInitializer);
39+
40+
this.channelFuture = bootstrap.register().syncUninterruptibly();
41+
}
42+
43+
}

0 commit comments

Comments
 (0)