From e01290d381f1df95dc5142b592d8ef588ff9585c Mon Sep 17 00:00:00 2001 From: Andrew Steinborn Date: Wed, 25 Jul 2018 00:12:39 -0400 Subject: [PATCH] Handle disconnects more gracefully. --- .../protocol/netty/MinecraftDecoder.java | 2 +- .../protocol/netty/MinecraftEncoder.java | 2 +- .../velocity/proxy/ConnectedPlayer.java | 4 ++++ .../proxy/InboundMinecraftConnection.java | 10 +++++++-- .../velocity/proxy/ServerConnection.java | 22 +++++++++++++++++++ .../proxy/handler/PlaySessionHandler.java | 12 +++++++++- 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftDecoder.java b/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftDecoder.java index 07f9e40a8..f62e4645c 100644 --- a/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftDecoder.java +++ b/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftDecoder.java @@ -31,7 +31,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder { int packetId = ProtocolUtils.readVarInt(msg); StateRegistry.ProtocolMappings mappings = direction == ProtocolConstants.Direction.TO_CLIENT ? state.TO_CLIENT : state.TO_SERVER; MinecraftPacket packet = mappings.createPacket(packetId); - System.out.println(direction + " <- " + ByteBufUtil.hexDump(slice)); + //System.out.println(direction + " <- " + ByteBufUtil.hexDump(slice)); if (packet == null) { msg.skipBytes(msg.readableBytes()); out.add(new PacketWrapper(null, slice)); diff --git a/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftEncoder.java b/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftEncoder.java index b87cad3a9..f56fe47aa 100644 --- a/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftEncoder.java +++ b/src/main/java/io/minimum/minecraft/velocity/protocol/netty/MinecraftEncoder.java @@ -24,7 +24,7 @@ public class MinecraftEncoder extends MessageToByteEncoder { ProtocolUtils.writeVarInt(out, packetId); msg.encode(out, direction, protocolVersion); - System.out.println(direction + " -> " + ByteBufUtil.hexDump(out)); + //System.out.println(direction + " -> " + ByteBufUtil.hexDump(out)); } public int getProtocolVersion() { diff --git a/src/main/java/io/minimum/minecraft/velocity/proxy/ConnectedPlayer.java b/src/main/java/io/minimum/minecraft/velocity/proxy/ConnectedPlayer.java index 5e4e14c94..ef13ed19d 100644 --- a/src/main/java/io/minimum/minecraft/velocity/proxy/ConnectedPlayer.java +++ b/src/main/java/io/minimum/minecraft/velocity/proxy/ConnectedPlayer.java @@ -50,4 +50,8 @@ public class ConnectedPlayer { // TODO } } + + public void setConnectedServer(ServerConnection serverConnection) { + this.connectedServer = serverConnection; + } } diff --git a/src/main/java/io/minimum/minecraft/velocity/proxy/InboundMinecraftConnection.java b/src/main/java/io/minimum/minecraft/velocity/proxy/InboundMinecraftConnection.java index 2a784ff58..71339b00d 100644 --- a/src/main/java/io/minimum/minecraft/velocity/proxy/InboundMinecraftConnection.java +++ b/src/main/java/io/minimum/minecraft/velocity/proxy/InboundMinecraftConnection.java @@ -10,11 +10,13 @@ import io.minimum.minecraft.velocity.protocol.packets.Handshake; import io.minimum.minecraft.velocity.protocol.packets.ServerLoginSuccess; import io.minimum.minecraft.velocity.proxy.handler.HandshakeSessionHandler; import io.minimum.minecraft.velocity.proxy.handler.LoginSessionHandler; +import io.minimum.minecraft.velocity.proxy.handler.PlaySessionHandler; import io.minimum.minecraft.velocity.proxy.handler.StatusSessionHandler; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.util.AttributeKey; +import net.kyori.text.TextComponent; import java.net.InetSocketAddress; import java.util.Optional; @@ -43,7 +45,7 @@ public class InboundMinecraftConnection { public void closeWith(Object msg) { ensureOpen(); - closed = true; + teardown(); channel.writeAndFlush(msg).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { @@ -54,8 +56,8 @@ public class InboundMinecraftConnection { public void close() { ensureOpen(); + teardown(); channel.close(); - closed = true; } public MinecraftSessionHandler getSessionHandler() { @@ -95,6 +97,9 @@ public class InboundMinecraftConnection { public void teardown() { closed = true; + if (connectedPlayer != null && connectedPlayer.getConnectedServer() != null) { + connectedPlayer.getConnectedServer().disconnect(); + } } public boolean isClosed() { @@ -114,6 +119,7 @@ public class InboundMinecraftConnection { ConnectedPlayer player = new ConnectedPlayer(success.getUsername(), success.getUuid(), this); ServerInfo info = new ServerInfo("test", new InetSocketAddress("127.0.0.1", 25565)); ServerConnection connection = new ServerConnection(info, player, VelocityServer.getServer()); + sessionHandler = new PlaySessionHandler(player, connection); connection.connect(); } } diff --git a/src/main/java/io/minimum/minecraft/velocity/proxy/ServerConnection.java b/src/main/java/io/minimum/minecraft/velocity/proxy/ServerConnection.java index cec4900ce..523aeaf38 100644 --- a/src/main/java/io/minimum/minecraft/velocity/proxy/ServerConnection.java +++ b/src/main/java/io/minimum/minecraft/velocity/proxy/ServerConnection.java @@ -11,7 +11,9 @@ import io.minimum.minecraft.velocity.protocol.packets.Disconnect; import io.minimum.minecraft.velocity.protocol.packets.Handshake; import io.minimum.minecraft.velocity.protocol.packets.ServerLogin; import io.minimum.minecraft.velocity.protocol.packets.ServerLoginSuccess; +import io.netty.buffer.ByteBuf; import io.netty.channel.*; +import net.kyori.text.TextComponent; public class ServerConnection { private Channel channel; @@ -45,6 +47,18 @@ public class ServerConnection { }); } + public void disconnect() { + channel.close(); + channel = null; + } + + public void forward(ByteBuf buf) { + if (registry != StateRegistry.PLAY) { + throw new IllegalStateException("Not accepting player information until PLAY state"); + } + channel.writeAndFlush(buf.retain()); + } + private class StateBasedInterceptor extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { @@ -66,6 +80,13 @@ public class ServerConnection { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (proxyPlayer.getConnection().isClosed()) { + // The upstream connection is closed, but we didn't forward that on for some reason. Close the connection + // here. + ctx.close(); + return; + } + if (msg instanceof PacketWrapper) { PacketWrapper pw = (PacketWrapper) msg; try { @@ -102,6 +123,7 @@ public class ServerConnection { // the player has been logged on. System.out.println("Player connected to remote server"); setRegistry(StateRegistry.PLAY); + proxyPlayer.setConnectedServer(ServerConnection.this); } } } diff --git a/src/main/java/io/minimum/minecraft/velocity/proxy/handler/PlaySessionHandler.java b/src/main/java/io/minimum/minecraft/velocity/proxy/handler/PlaySessionHandler.java index ca71a76e6..1e6a7d0f8 100644 --- a/src/main/java/io/minimum/minecraft/velocity/proxy/handler/PlaySessionHandler.java +++ b/src/main/java/io/minimum/minecraft/velocity/proxy/handler/PlaySessionHandler.java @@ -1,10 +1,20 @@ package io.minimum.minecraft.velocity.proxy.handler; import io.minimum.minecraft.velocity.protocol.MinecraftPacket; +import io.minimum.minecraft.velocity.proxy.ConnectedPlayer; import io.minimum.minecraft.velocity.proxy.MinecraftSessionHandler; +import io.minimum.minecraft.velocity.proxy.ServerConnection; import io.netty.buffer.ByteBuf; public class PlaySessionHandler implements MinecraftSessionHandler { + private final ConnectedPlayer player; + private final ServerConnection connection; + + public PlaySessionHandler(ConnectedPlayer player, ServerConnection connection) { + this.player = player; + this.connection = connection; + } + @Override public void handle(MinecraftPacket packet) { @@ -12,6 +22,6 @@ public class PlaySessionHandler implements MinecraftSessionHandler { @Override public void handleUnknown(ByteBuf buf) { - + connection.forward(buf); } }