From 1b41682e37db79efc31f7c817d9ed97dc3b47eee Mon Sep 17 00:00:00 2001 From: md_5 Date: Sat, 12 Oct 2013 11:36:53 +1100 Subject: [PATCH] Checkpoint --- .../md_5/bungee/protocol/MinecraftCodec.java | 10 +- .../md_5/bungee/protocol/PacketWrapper.java | 1 - .../net/md_5/bungee/protocol/Protocol.java | 13 ++- .../bungee/protocol/packet/LoginSuccess.java | 9 +- .../java/net/md_5/bungee/ServerConnector.java | 98 +++++-------------- .../java/net/md_5/bungee/UserConnection.java | 5 + .../bungee/connection/DownstreamBridge.java | 2 +- .../bungee/connection/InitialHandler.java | 7 +- .../bungee/connection/UpstreamBridge.java | 2 +- .../net/md_5/bungee/netty/PipelineUtils.java | 15 +-- 10 files changed, 66 insertions(+), 96 deletions(-) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftCodec.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftCodec.java index 65961ab94..a8909e6a7 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftCodec.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftCodec.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol; +import com.google.common.base.Charsets; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageCodec; @@ -23,7 +24,7 @@ public class MinecraftCodec extends MessageToMessageCodec out) throws Exception { Protocol.ProtocolDirection prot = ( server ) ? protocol.TO_SERVER : protocol.TO_CLIENT; + ByteBuf copy = msg.copy(); int packetId = DefinedPacket.readVarInt( msg ); - ByteBuf copy = msg.copy(); DefinedPacket packet = null; if ( prot.hasPacket( packetId ) ) { packet = prot.createPacket( packetId ); packet.read( msg ); + if ( msg.readableBytes() != 0 ) + { + System.out.println( msg.toString( Charsets.UTF_8 ) ); + throw new BadPacketException( "Did not read all bytes from packet " + packetId + " Protocol " + protocol + " Direction " + prot ); + } } out.add( new PacketWrapper( packet, copy ) ); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java b/protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java index 44610630d..8eba797b5 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java @@ -3,7 +3,6 @@ package net.md_5.bungee.protocol; import io.netty.buffer.ByteBuf; import lombok.RequiredArgsConstructor; import lombok.Setter; -import net.md_5.bungee.protocol.DefinedPacket; @RequiredArgsConstructor public class PacketWrapper diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java index 5cb03a8d9..10ddb6025 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TObjectIntHashMap; import java.lang.reflect.Constructor; +import lombok.RequiredArgsConstructor; import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.ClientSettings; import net.md_5.bungee.protocol.packet.EncryptionRequest; @@ -92,12 +93,14 @@ public enum Protocol public static final int PROTOCOL_VERSION = 0x00; public static final String MINECRAFT_VERSION = "13w41a"; /*========================================================================*/ - public final ProtocolDirection TO_SERVER = new ProtocolDirection(); - public final ProtocolDirection TO_CLIENT = new ProtocolDirection(); + public final ProtocolDirection TO_SERVER = new ProtocolDirection( "TO_SERVER" ); + public final ProtocolDirection TO_CLIENT = new ProtocolDirection( "TO_CLIENT" ); + @RequiredArgsConstructor public class ProtocolDirection { + private final String name; private final TObjectIntMap> packetMap = new TObjectIntHashMap<>( MAX_PACKET_ID ); private final Class[] packetClasses = new Class[ MAX_PACKET_ID ]; private final Constructor[] packetConstructors = new Constructor[ MAX_PACKET_ID ]; @@ -107,6 +110,12 @@ public enum Protocol return id < MAX_PACKET_ID && packetConstructors[id] != null; } + @Override + public String toString() + { + return name; + } + public final DefinedPacket createPacket(int id) { if ( id > MAX_PACKET_ID ) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginSuccess.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginSuccess.java index ed9e5b57c..09c718b51 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginSuccess.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginSuccess.java @@ -15,18 +15,21 @@ import net.md_5.bungee.protocol.AbstractPacketHandler; public class LoginSuccess extends DefinedPacket { - private String data; + private String uuid; + private String username; @Override public void read(ByteBuf buf) { - data = readString( buf ); + uuid = readString( buf ); + username = readString( buf ); } @Override public void write(ByteBuf buf) { - writeString( data, buf ); + writeString( uuid, buf ); + writeString( username, buf ); } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java index b4a51d8c7..4ca384ad0 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -3,11 +3,8 @@ package net.md_5.bungee; import com.google.common.base.Preconditions; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; -import java.io.DataInput; import java.util.Objects; import java.util.Queue; -import javax.crypto.Cipher; -import javax.crypto.SecretKey; import lombok.RequiredArgsConstructor; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ProxyServer; @@ -22,17 +19,17 @@ import net.md_5.bungee.connection.CancelSendSignal; import net.md_5.bungee.connection.DownstreamBridge; import net.md_5.bungee.netty.HandlerBoss; import net.md_5.bungee.netty.ChannelWrapper; -import net.md_5.bungee.netty.CipherDecoder; import net.md_5.bungee.netty.PacketHandler; -import net.md_5.bungee.netty.PipelineUtils; import net.md_5.bungee.protocol.MinecraftOutput; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.PacketWrapper; +import net.md_5.bungee.protocol.Protocol; import net.md_5.bungee.protocol.packet.Login; import net.md_5.bungee.protocol.packet.Respawn; import net.md_5.bungee.protocol.packet.ScoreboardObjective; import net.md_5.bungee.protocol.packet.PluginMessage; -import net.md_5.bungee.protocol.packet.EncryptionResponse; import net.md_5.bungee.protocol.packet.Kick; +import net.md_5.bungee.protocol.packet.LoginSuccess; @RequiredArgsConstructor public class ServerConnector extends PacketHandler @@ -42,14 +39,12 @@ public class ServerConnector extends PacketHandler private ChannelWrapper ch; private final UserConnection user; private final BungeeServerInfo target; - private State thisState = State.ENCRYPT_REQUEST; - private SecretKey secretkey; - private boolean sentMessages; + private State thisState = State.LOGIN_SUCCESS; private enum State { - ENCRYPT_REQUEST, ENCRYPT_RESPONSE, LOGIN, FINISHED; + LOGIN_SUCCESS, ENCRYPT_RESPONSE, LOGIN, FINISHED; } @Override @@ -74,15 +69,12 @@ public class ServerConnector extends PacketHandler out.writeUTF( "Login" ); out.writeUTF( user.getAddress().getHostString() ); out.writeInt( user.getAddress().getPort() ); - channel.write( new PluginMessage( "BungeeCord", out.toByteArray() ) ); + // channel.write( new PluginMessage( "BungeeCord", out.toByteArray() ) ); MOJANG - // channel.write( user.getPendingConnection().getHandshake() ); FIX + channel.write( user.getPendingConnection().getHandshake() ); - // Skip encryption if we are not using Forge - if ( user.getPendingConnection().getForgeLogin() == null ) - { - channel.write( PacketConstants.CLIENT_LOGIN ); - } + channel.setProtocol( Protocol.LOGIN ); + channel.write( user.getPendingConnection().getLoginRequest() ); } @Override @@ -91,6 +83,24 @@ public class ServerConnector extends PacketHandler user.getPendingConnects().remove( target ); } + @Override + public void handle(PacketWrapper packet) throws Exception + { + int packetID = DefinedPacket.readVarInt( packet.buf ); + System.out.println( packetID + " : " + packet.packet ); + super.handle( packet ); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void handle(LoginSuccess loginSuccess) throws Exception + { + Preconditions.checkState( thisState == State.LOGIN_SUCCESS, "Not exepcting LOGIN_SUCCESS" ); + ch.setProtocol( Protocol.GAME ); + thisState = State.LOGIN; + + throw new CancelSendSignal(); + } + @Override public void handle(Login login) throws Exception { @@ -114,13 +124,6 @@ public class ServerConnector extends PacketHandler { ch.write( message ); } - if ( !sentMessages ) - { - for ( PluginMessage message : user.getPendingConnection().getLoginMessages() ) - { - ch.write( message ); - } - } if ( user.getSettings() != null ) { @@ -194,20 +197,6 @@ public class ServerConnector extends PacketHandler throw new CancelSendSignal(); } - @Override - public void handle(EncryptionResponse encryptResponse) throws Exception - { - Preconditions.checkState( thisState == State.ENCRYPT_RESPONSE, "Not expecting ENCRYPT_RESPONSE" ); - - Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, secretkey ); - ch.addBefore( PipelineUtils.FRAME_DECODER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) ); - - ch.write( user.getPendingConnection().getForgeLogin() ); - - ch.write( PacketConstants.CLIENT_LOGIN ); - thisState = State.LOGIN; - } - @Override public void handle(Kick kick) throws Exception { @@ -233,39 +222,6 @@ public class ServerConnector extends PacketHandler } } - @Override - public void handle(PluginMessage pluginMessage) throws Exception - { - if ( pluginMessage.equals( PacketConstants.I_AM_BUNGEE ) ) - { - throw new IllegalStateException( "May not connect to another BungeCord!" ); - } - - DataInput in = pluginMessage.getStream(); - if ( pluginMessage.getTag().equals( "FML" ) && in.readUnsignedByte() == 0 ) - { - int count = in.readInt(); - for ( int i = 0; i < count; i++ ) - { - in.readUTF(); - } - if ( in.readByte() != 0 ) - { - // TODO: Using forge flag - } - } - - user.unsafe().sendPacket( pluginMessage ); // We have to forward these to the user, especially with Forge as stuff might break - if ( !sentMessages && user.getPendingConnection().getForgeLogin() != null ) - { - for ( PluginMessage message : user.getPendingConnection().getLoginMessages() ) - { - ch.write( message ); - } - sentMessages = true; - } - } - @Override public String toString() { diff --git a/proxy/src/main/java/net/md_5/bungee/UserConnection.java b/proxy/src/main/java/net/md_5/bungee/UserConnection.java index 6b0771f3f..e6efb4193 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -32,7 +32,11 @@ import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.HandlerBoss; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.netty.PipelineUtils; +import static net.md_5.bungee.netty.PipelineUtils.FRAME_DECODER; +import static net.md_5.bungee.netty.PipelineUtils.PACKET_CODEC; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.MinecraftCodec; +import net.md_5.bungee.protocol.Protocol; import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.ClientSettings; import net.md_5.bungee.protocol.packet.PluginMessage; @@ -200,6 +204,7 @@ public final class UserConnection implements ProxiedPlayer protected void initChannel(Channel ch) throws Exception { PipelineUtils.BASE.initChannel( ch ); + ch.pipeline().addAfter( FRAME_DECODER, PACKET_CODEC, new MinecraftCodec( Protocol.HANDSHAKE, false ) ); ch.pipeline().get( HandlerBoss.class ).setHandler( new ServerConnector( bungee, UserConnection.this, target ) ); } }; diff --git a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java index 25f73c303..d39410c9b 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/DownstreamBridge.java @@ -74,7 +74,7 @@ public class DownstreamBridge extends PacketHandler { if ( !server.isObsolete() ) { - EntityMap.rewrite( packet.buf, con.getServerEntityId(), con.getClientEntityId() ); + // EntityMap.rewrite( packet.buf, con.getServerEntityId(), con.getClientEntityId() ); con.sendPacket( packet ); } } diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index 8487bf6fa..057c5e153 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -104,7 +104,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection { int len = DefinedPacket.readVarInt( packet.buf ); int id = DefinedPacket.readVarInt( packet.buf ); - throw new UnsupportedOperationException( "Cannot handle unknown packet at login!" ); + // throw new UnsupportedOperationException( "Cannot handle unknown packet at login!" ); } @Override @@ -343,7 +343,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection { UUID = java.util.UUID.randomUUID().toString(); } - unsafe.sendPacket( new LoginSuccess( BungeeCord.getInstance().gson.toJson( new LoginResult( UUID ) ) ) ); + System.out.println( ch.getHandle().pipeline() ); + unsafe.sendPacket( new LoginSuccess( UUID, getName() ) ); ch.setProtocol( Protocol.GAME ); UserConnection userCon = new UserConnection( bungee, ch, getName(), InitialHandler.this ); @@ -361,7 +362,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection { server = AbstractReconnectHandler.getForcedHost( InitialHandler.this ); } - userCon.connect( server, true ); + // userCon.connect( server, true ); thisState = State.FINISHED; } diff --git a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java index 6fb545b48..06a6bd283 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/UpstreamBridge.java @@ -59,7 +59,7 @@ public class UpstreamBridge extends PacketHandler @Override public void handle(PacketWrapper packet) throws Exception { - EntityMap.rewrite( packet.buf, con.getClientEntityId(), con.getServerEntityId() ); + // EntityMap.rewrite( packet.buf, con.getClientEntityId(), con.getServerEntityId() ); if ( con.getServer() != null ) { con.getServer().getCh().write( packet ); diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java index 52ae773ad..2295b5d49 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java @@ -10,7 +10,6 @@ import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.BungeeServerInfo; -import net.md_5.bungee.ServerConnector; import net.md_5.bungee.UserConnection; import net.md_5.bungee.connection.InitialHandler; import net.md_5.bungee.api.ProxyServer; @@ -40,19 +39,10 @@ public class PipelineUtils BASE.initChannel( ch ); ch.pipeline().addAfter( FRAME_DECODER, PACKET_CODEC, new MinecraftCodec( Protocol.HANDSHAKE, true ) ); + System.out.println( ch.pipeline() ); ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( ProxyServer.getInstance(), ch.attr( LISTENER ).get() ) ); } }; - public static final ChannelInitializer CLIENT = new ChannelInitializer() - { - @Override - protected void initChannel(Channel ch) throws Exception - { - BASE.initChannel( ch ); - ch.pipeline().addAfter( FRAME_DECODER, PACKET_CODEC, new MinecraftCodec( Protocol.LOGIN, false) ); - ch.pipeline().get( HandlerBoss.class ).setHandler( new ServerConnector( ProxyServer.getInstance(), ch.attr( USER ).get(), ch.attr( TARGET ).get() ) ); - } - }; public static final Base BASE = new Base(); private static final Varint21LengthFieldPrepender framePrepender = new Varint21LengthFieldPrepender(); public static String TIMEOUT_HANDLER = "timeout"; @@ -76,9 +66,10 @@ public class PipelineUtils { // IP_TOS is not supported (Windows XP / Windows Server 2003) } - ch.pipeline().addLast( FRAME_PREPENDER, framePrepender ); + ch.pipeline().addLast( TIMEOUT_HANDLER, new ReadTimeoutHandler( BungeeCord.getInstance().config.getTimeout(), TimeUnit.MILLISECONDS ) ); ch.pipeline().addLast( FRAME_DECODER, new Varint21FrameDecoder() ); + ch.pipeline().addLast( FRAME_PREPENDER, framePrepender ); ch.pipeline().addLast( BOSS_HANDLER, new HandlerBoss() ); }