Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 31 additions & 77 deletions src/main/java/gg/playit/minecraft/PlayitTcpTunnel.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.util.AttributeKey;
import org.bukkit.Server;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.logging.Logger;

public class PlayitTcpTunnel {
Expand Down Expand Up @@ -180,6 +181,11 @@ private boolean addChannelToMinecraftServer() {
ReflectionHelper reflect = new ReflectionHelper();
log.info("Reflect: " + reflect);

if (!reflect.setRemoteAddress(tunnelChannel, trueIp)) {
log.warning("failed to set remote address to " + trueIp);
return false;
}

Object minecraftServer = reflect.getMinecraftServer(server);
if (minecraftServer == null) {
log.info("failed to get Minecraft server from Bukkit.getServer()");
Expand All @@ -192,97 +198,45 @@ private boolean addChannelToMinecraftServer() {
return false;
}

Object legacyPingHandler = reflect.newLegacyPingHandler(serverConnection);
if (legacyPingHandler == null) {
log.info("legacyPingHandler is null");
return false;
}

Object packetSplitter = reflect.newPacketSplitter();
if (packetSplitter == null) {
log.info("packetSplitter is null");
ServerChannel serverChannel = reflect.findServerChannel(serverConnection);
if (serverChannel == null) {
log.info("serverChannel is null");
return false;
}

Object packetDecoder = reflect.newServerBoundPacketDecoder();
if (packetDecoder == null) {
log.info("packetDecoder is null");
ChannelHandler serverHandler = reflect.findServerHandler(serverChannel);
if (serverHandler == null) {
log.info("serverHandler is null");
return false;
}

Object packetPrepender = reflect.newPacketPrepender();
if (packetPrepender == null) {
log.info("packetPrepender is null");
ChannelHandler handler = reflect.findChildHandler(serverHandler);
if (handler == null) {
log.info("handler is null");
return false;
}

Object packetEncoder = reflect.newClientBoundPacketEncoder();
if (packetEncoder == null) {
log.info("packetEncoder is null");
return false;
}

Integer rateLimitNullable = reflect.getRateLimitFromMCServer(minecraftServer);
if (rateLimitNullable == null) {
rateLimitNullable = 0;
}

int rateLimit = rateLimitNullable;

Object networkManager;
if (rateLimit > 0) {
networkManager = reflect.newNetworkManagerServer(rateLimit);
} else {
networkManager = reflect.newServerNetworkManager();
}

if (networkManager == null) {
log.info("networkManager is null");
return false;
}

Object handshakeListener = reflect.newHandshakeListener(minecraftServer, networkManager);
if (handshakeListener == null) {
log.info("handshakeListener is null");
return false;
}

if (!reflect.networkManagerSetListener(networkManager, handshakeListener)) {
log.info("failed to set handshake listener on network manager");
return false;
Map.Entry<ChannelOption<Object>, Object>[] options = reflect.findChildOptions(serverHandler);
if (options != null) {
for (Map.Entry<ChannelOption<Object>, Object> option : options) {
tunnelChannel.config().setOption(option.getKey(), option.getValue());
}
}

if (!reflect.setRemoteAddress(tunnelChannel, trueIp)) {
log.warning("failed to set remote address to " + trueIp);
Map.Entry<AttributeKey<Object>, Object>[] attrs = reflect.findChildAttrs(serverHandler);
if (attrs != null) {
for (Map.Entry<AttributeKey<Object>, Object> attr : attrs) {
tunnelChannel.attr(attr.getKey()).set(attr.getValue());
}
}

var channel = tunnelChannel.pipeline().removeLast();
tunnelChannel.pipeline()
.addLast("timeout", new ReadTimeoutHandler(connectionTimeoutSeconds))
.addLast("legacy_query", (ChannelHandler) legacyPingHandler)
.addLast("splitter", (ChannelHandler) packetSplitter)
.addLast("decoder", (ChannelHandler) packetDecoder)
.addLast("prepender", (ChannelHandler) packetPrepender)
.addLast("encoder", (ChannelHandler) packetEncoder)
.addLast("packet_handler", (ChannelHandler) networkManager);

if (!reflect.addToServerConnections(serverConnection, networkManager)) {
log.info("failed to add to server connections");

tunnelChannel.pipeline().remove("timeout");
tunnelChannel.pipeline().remove("legacy_query");
tunnelChannel.pipeline().remove("splitter");
tunnelChannel.pipeline().remove("decoder");
tunnelChannel.pipeline().remove("prepender");
tunnelChannel.pipeline().remove("encoder");
tunnelChannel.pipeline().remove("packet_handler");

tunnelChannel.pipeline().addLast(channel);
ChannelPipeline pipeline = tunnelChannel.pipeline();

return false;
}
pipeline.remove(this);
pipeline.addLast(handler);

tunnelChannel.pipeline().fireChannelActive();
pipeline.fireChannelRegistered();
pipeline.fireChannelActive();
return true;
}
}
Expand Down
Loading