From d900417d95b4cb76c0cff23200930d3297cb0ee9 Mon Sep 17 00:00:00 2001 From: md_5 Date: Fri, 11 Oct 2013 20:00:54 +1100 Subject: [PATCH] It compiles --- .../java/net/md_5/bungee/api/ProxyServer.java | 2 +- .../api/connection/PendingConnection.java | 2 +- .../api/event/PlayerHandshakeEvent.java | 5 +- protocol/pom.xml | 2 +- .../protocol/AbstractPacketHandler.java | 5 ++ .../md_5/bungee/protocol/DefinedPacket.java | 12 +-- .../md_5/bungee/protocol/MinecraftCodec.java | 38 +++++++++ .../md_5/bungee/protocol}/PacketWrapper.java | 2 +- .../net/md_5/bungee/protocol/Protocol.java | 11 ++- .../protocol/packet/EncryptionRequest.java | 43 ++++++++++ .../bungee/protocol/packet/Handshake.java | 12 +-- .../main/java/net/md_5/bungee/BungeeCord.java | 8 +- .../java/net/md_5/bungee/EncryptionUtil.java | 10 +-- .../java/net/md_5/bungee/ServerConnector.java | 53 ++---------- .../java/net/md_5/bungee/UserConnection.java | 2 +- .../bungee/connection/DownstreamBridge.java | 5 +- .../bungee/connection/InitialHandler.java | 81 +++++++++---------- .../bungee/connection/UpstreamBridge.java | 2 +- .../net/md_5/bungee/netty/ChannelWrapper.java | 1 + .../bungee/netty/DefinedPacketEncoder.java | 19 ----- .../net/md_5/bungee/netty/HandlerBoss.java | 1 + .../net/md_5/bungee/netty/PacketDecoder.java | 50 ------------ .../net/md_5/bungee/netty/PacketHandler.java | 2 + .../net/md_5/bungee/netty/PipelineUtils.java | 17 ++-- 24 files changed, 186 insertions(+), 199 deletions(-) create mode 100644 protocol/src/main/java/net/md_5/bungee/protocol/MinecraftCodec.java rename {proxy/src/main/java/net/md_5/bungee/netty => protocol/src/main/java/net/md_5/bungee/protocol}/PacketWrapper.java (93%) create mode 100644 protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionRequest.java delete mode 100644 proxy/src/main/java/net/md_5/bungee/netty/DefinedPacketEncoder.java delete mode 100644 proxy/src/main/java/net/md_5/bungee/netty/PacketDecoder.java diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java index 474391e1..b4894ab4 100644 --- a/api/src/main/java/net/md_5/bungee/api/ProxyServer.java +++ b/api/src/main/java/net/md_5/bungee/api/ProxyServer.java @@ -180,7 +180,7 @@ public abstract class ProxyServer * * @return the Minecraft protocol version */ - public abstract byte getProtocolVersion(); + public abstract int getProtocolVersion(); /** * Factory method to construct an implementation specific server info diff --git a/api/src/main/java/net/md_5/bungee/api/connection/PendingConnection.java b/api/src/main/java/net/md_5/bungee/api/connection/PendingConnection.java index f0cb572a..8513e8e3 100644 --- a/api/src/main/java/net/md_5/bungee/api/connection/PendingConnection.java +++ b/api/src/main/java/net/md_5/bungee/api/connection/PendingConnection.java @@ -21,7 +21,7 @@ public interface PendingConnection extends Connection * * @return the protocol version of the remote client */ - byte getVersion(); + int getVersion(); /** * Get the requested virtual host that the client tried to connect to. diff --git a/api/src/main/java/net/md_5/bungee/api/event/PlayerHandshakeEvent.java b/api/src/main/java/net/md_5/bungee/api/event/PlayerHandshakeEvent.java index de927325..06db41e1 100644 --- a/api/src/main/java/net/md_5/bungee/api/event/PlayerHandshakeEvent.java +++ b/api/src/main/java/net/md_5/bungee/api/event/PlayerHandshakeEvent.java @@ -6,6 +6,7 @@ import lombok.ToString; import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.protocol.packet.Packet2Handshake; import net.md_5.bungee.api.plugin.Event; +import net.md_5.bungee.protocol.packet.Handshake; /** * Event called to represent a player first making their presence and username @@ -24,9 +25,9 @@ public class PlayerHandshakeEvent extends Event /** * The handshake. */ - private final Packet2Handshake handshake; + private final Handshake handshake; - public PlayerHandshakeEvent(PendingConnection connection, Packet2Handshake handshake) + public PlayerHandshakeEvent(PendingConnection connection, Handshake handshake) { this.connection = connection; this.handshake = handshake; diff --git a/protocol/pom.xml b/protocol/pom.xml index e13e8062..c25d094d 100644 --- a/protocol/pom.xml +++ b/protocol/pom.xml @@ -21,7 +21,7 @@ io.netty - netty-buffer + netty-codec ${netty.version} compile diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java b/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java index 5ee2fd17..6101c314 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java @@ -5,6 +5,7 @@ import net.md_5.bungee.protocol.packet.ClientSettings; import net.md_5.bungee.protocol.packet.ClientStatus; import net.md_5.bungee.protocol.packet.Login; import net.md_5.bungee.protocol.packet.Chat; +import net.md_5.bungee.protocol.packet.EncryptionRequest; import net.md_5.bungee.protocol.packet.PlayerListItem; import net.md_5.bungee.protocol.packet.TabComplete; import net.md_5.bungee.protocol.packet.ScoreboardObjective; @@ -70,6 +71,10 @@ public abstract class AbstractPacketHandler { } + public void handle(EncryptionRequest encryptionRequest) throws Exception + { + } + public void handle(ScoreboardDisplay displayScoreboard) throws Exception { } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java b/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java index c3a034bc..be342952 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java @@ -8,7 +8,7 @@ import lombok.RequiredArgsConstructor; public abstract class DefinedPacket { - public void writeString(String s, ByteBuf buf) + public static void writeString(String s, ByteBuf buf) { // TODO: Check len - use Guava? byte[] b = s.getBytes( Charsets.UTF_8 ); @@ -16,7 +16,7 @@ public abstract class DefinedPacket buf.writeBytes( b ); } - public String readString(ByteBuf buf) + public static String readString(ByteBuf buf) { int len = readVarInt( buf ); byte[] b = new byte[ len ]; @@ -25,14 +25,14 @@ public abstract class DefinedPacket return new String( b, Charsets.UTF_8 ); } - public void writeArray(byte[] b, ByteBuf buf) + public static void writeArray(byte[] b, ByteBuf buf) { // TODO: Check len - use Guava? buf.writeShort( b.length ); buf.writeBytes( b ); } - public byte[] readArray(ByteBuf buf) + public static byte[] readArray(ByteBuf buf) { // TODO: Check len - use Guava? short len = buf.readShort(); @@ -41,7 +41,7 @@ public abstract class DefinedPacket return ret; } - public int readVarInt(ByteBuf input) + public static int readVarInt(ByteBuf input) { int out = 0; int bytes = 0; @@ -66,7 +66,7 @@ public abstract class DefinedPacket return out; } - public void writeVarInt(int value, ByteBuf output) + public static void writeVarInt(int value, ByteBuf output) { int part; while ( true ) 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 new file mode 100644 index 00000000..530253ea --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftCodec.java @@ -0,0 +1,38 @@ +package net.md_5.bungee.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageCodec; +import java.util.List; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class MinecraftCodec extends MessageToMessageCodec +{ + + private Protocol protocol; + + @Override + protected void encode(ChannelHandlerContext ctx, DefinedPacket msg, List out) throws Exception + { + ByteBuf buf = ctx.alloc().buffer(); + DefinedPacket.writeVarInt( protocol.getId( msg.getClass() ), buf ); + msg.write( buf ); + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception + { + int packetId = DefinedPacket.readVarInt( msg ); + + ByteBuf copy = msg.copy(); + DefinedPacket packet = null; + if ( protocol.hasPacket( packetId ) ) + { + packet = protocol.createPacket( packetId ); + packet.read( msg ); + } + + out.add( new PacketWrapper( packet, copy ) ); + } +} diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PacketWrapper.java b/protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java similarity index 93% rename from proxy/src/main/java/net/md_5/bungee/netty/PacketWrapper.java rename to protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java index 2d0f66fc..44610630 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PacketWrapper.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/PacketWrapper.java @@ -1,4 +1,4 @@ -package net.md_5.bungee.netty; +package net.md_5.bungee.protocol; import io.netty.buffer.ByteBuf; import lombok.RequiredArgsConstructor; 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 d9f28385..fdcce8b7 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 @@ -5,6 +5,7 @@ import gnu.trove.map.hash.TObjectIntHashMap; import java.lang.reflect.Constructor; import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.ClientSettings; +import net.md_5.bungee.protocol.packet.EncryptionRequest; import net.md_5.bungee.protocol.packet.EncryptionResponse; import net.md_5.bungee.protocol.packet.Handshake; import net.md_5.bungee.protocol.packet.KeepAlive; @@ -82,7 +83,7 @@ public enum Protocol { registerPacket( 0x00, Kick.class ); - registerPacket( 0x01, EncryptionResponse.class ); + registerPacket( 0x01, EncryptionRequest.class ); registerPacket( 0x02, LoginSuccess.class ); } }, @@ -92,15 +93,23 @@ public enum Protocol { registerPacket( 0x00, LoginRequest.class ); + registerPacket( 0x01, EncryptionResponse.class ); } }; /*========================================================================*/ public static final int MAX_PACKET_ID = 0xFF; + public static final int PROTOCOL_VERSION = 0x00; + public static final String MINECRAFT_VERSION = "13w41a"; /*========================================================================*/ 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 ]; + public boolean hasPacket(int id) + { + return id < MAX_PACKET_ID && packetConstructors[id] != null; + } + public final DefinedPacket createPacket(int id) { if ( id > MAX_PACKET_ID ) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionRequest.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionRequest.java new file mode 100644 index 00000000..4521f6c3 --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionRequest.java @@ -0,0 +1,43 @@ +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import net.md_5.bungee.protocol.AbstractPacketHandler; +import net.md_5.bungee.protocol.DefinedPacket; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class EncryptionRequest extends DefinedPacket +{ + + private String serverId; + private byte[] publicKey; + private byte[] verifyToken; + + @Override + public void read(ByteBuf buf) + { + serverId = readString( buf ); + publicKey = readArray( buf ); + verifyToken = readArray( buf ); + } + + @Override + public void write(ByteBuf buf) + { + writeString( serverId, buf ); + writeArray( publicKey, buf ); + writeArray( verifyToken, buf ); + } + + @Override + public void handle(AbstractPacketHandler handler) throws Exception + { + handler.handle( this ); + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Handshake.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Handshake.java index 47d12299..ed55d472 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Handshake.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Handshake.java @@ -16,16 +16,16 @@ public class Handshake extends DefinedPacket { private int protocolVersion; - private String serverAddress; - private int serverPort; + private String host; + private int port; private int requestedProtocol; @Override public void read(ByteBuf buf) { protocolVersion = readVarInt( buf ); - serverAddress = readString( buf ); - serverPort = readVarInt( buf ); + host = readString( buf ); + port = readVarInt( buf ); requestedProtocol = readVarInt( buf ); } @@ -33,8 +33,8 @@ public class Handshake extends DefinedPacket public void write(ByteBuf buf) { writeVarInt( protocolVersion, buf ); - writeString( serverAddress, buf ); - writeVarInt( serverPort, buf ); + writeString( host, buf ); + writeVarInt( port, buf ); writeVarInt( requestedProtocol, buf ); } diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index d04db1a2..751d2e21 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -58,9 +58,9 @@ import net.md_5.bungee.config.YamlConfig; import net.md_5.bungee.log.LoggingOutputStream; import net.md_5.bungee.netty.PipelineUtils; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.Protocol; import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.PluginMessage; -import net.md_5.bungee.protocol.Vanilla; import net.md_5.bungee.query.RemoteQuery; import net.md_5.bungee.tab.Custom; import net.md_5.bungee.util.CaseInsensitiveMap; @@ -453,15 +453,15 @@ public class BungeeCord extends ProxyServer } @Override - public byte getProtocolVersion() + public int getProtocolVersion() { - return Vanilla.PROTOCOL_VERSION; + return Protocol.PROTOCOL_VERSION; } @Override public String getGameVersion() { - return Vanilla.GAME_VERSION; + return Protocol.MINECRAFT_VERSION; } @Override diff --git a/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java b/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java index 15a87766..9cc2140d 100644 --- a/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java +++ b/proxy/src/main/java/net/md_5/bungee/EncryptionUtil.java @@ -16,7 +16,7 @@ import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import lombok.Getter; import net.md_5.bungee.protocol.packet.EncryptionResponse; -import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest; +import net.md_5.bungee.protocol.packet.EncryptionRequest; /** * Class containing all encryption related methods for the proxy. @@ -40,16 +40,16 @@ public class EncryptionUtil } } - public static PacketFDEncryptionRequest encryptRequest(boolean onlinemode) + public static EncryptionRequest encryptRequest(boolean onlinemode) { String hash = ( onlinemode ) ? Long.toString( random.nextLong(), 16 ) : "-"; byte[] pubKey = keys.getPublic().getEncoded(); byte[] verify = new byte[ 4 ]; random.nextBytes( verify ); - return new PacketFDEncryptionRequest( hash, pubKey, verify ); + return new EncryptionRequest( hash, pubKey, verify ); } - public static SecretKey getSecret(EncryptionResponse resp, PacketFDEncryptionRequest request) throws GeneralSecurityException + public static SecretKey getSecret(EncryptionResponse resp, EncryptionRequest request) throws GeneralSecurityException { Cipher cipher = Cipher.getInstance( "RSA" ); cipher.init( Cipher.DECRYPT_MODE, keys.getPrivate() ); @@ -71,7 +71,7 @@ public class EncryptionUtil return cip; } - public static PublicKey getPubkey(PacketFDEncryptionRequest request) throws GeneralSecurityException + public static PublicKey getPubkey(EncryptionRequest request) throws GeneralSecurityException { return KeyFactory.getInstance( "RSA" ).generatePublic( new X509EncodedKeySpec( request.getPublicKey() ) ); } 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 42c1e83e..b4a51d8c 100644 --- a/proxy/src/main/java/net/md_5/bungee/ServerConnector.java +++ b/proxy/src/main/java/net/md_5/bungee/ServerConnector.java @@ -4,7 +4,6 @@ import com.google.common.base.Preconditions; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import java.io.DataInput; -import java.security.PublicKey; import java.util.Objects; import java.util.Queue; import javax.crypto.Cipher; @@ -24,22 +23,16 @@ 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.CipherEncoder; -import net.md_5.bungee.netty.PacketDecoder; import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.netty.PipelineUtils; -import net.md_5.bungee.protocol.Forge; import net.md_5.bungee.protocol.MinecraftOutput; import net.md_5.bungee.protocol.DefinedPacket; 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.Team; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.EncryptionResponse; -import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest; import net.md_5.bungee.protocol.packet.Kick; -import net.md_5.bungee.protocol.packet.forge.Forge1Login; @RequiredArgsConstructor public class ServerConnector extends PacketHandler @@ -83,7 +76,7 @@ public class ServerConnector extends PacketHandler out.writeInt( user.getAddress().getPort() ); channel.write( new PluginMessage( "BungeeCord", out.toByteArray() ) ); - channel.write( user.getPendingConnection().getHandshake() ); + // channel.write( user.getPendingConnection().getHandshake() ); FIX // Skip encryption if we are not using Forge if ( user.getPendingConnection().getForgeLogin() == null ) @@ -143,16 +136,9 @@ public class ServerConnector extends PacketHandler user.setServerEntityId( login.getEntityId() ); // Set tab list size, this sucks balls, TODO: what shall we do about packet mutability - Login modLogin; - if ( ch.getHandle().pipeline().get( PacketDecoder.class ).getProtocol() == Forge.getInstance() ) - { - modLogin = new Forge1Login( login.getEntityId(), login.getLevelType(), login.getGameMode(), login.getDimension(), login.getDifficulty(), login.getUnused(), - (byte) user.getPendingConnection().getListener().getTabListSize() ); - } else - { - modLogin = new Login( login.getEntityId(), login.getLevelType(), login.getGameMode(), (byte) login.getDimension(), login.getDifficulty(), login.getUnused(), - (byte) user.getPendingConnection().getListener().getTabListSize() ); - } + Login modLogin = new Login( login.getEntityId(), login.getLevelType(), login.getGameMode(), (byte) login.getDimension(), login.getDifficulty(), login.getUnused(), + (byte) user.getPendingConnection().getListener().getTabListSize() ); + user.unsafe().sendPacket( modLogin ); MinecraftOutput out = new MinecraftOutput(); @@ -169,7 +155,7 @@ public class ServerConnector extends PacketHandler } for ( Team team : serverScoreboard.getTeams() ) { - user.unsafe().sendPacket( new Team( team.getName() ) ); + user.unsafe().sendPacket( new net.md_5.bungee.protocol.packet.Team( team.getName() ) ); } serverScoreboard.clear(); @@ -208,39 +194,13 @@ public class ServerConnector extends PacketHandler throw new CancelSendSignal(); } - @Override - public void handle(PacketFDEncryptionRequest encryptRequest) throws Exception - { - Preconditions.checkState( thisState == State.ENCRYPT_REQUEST, "Not expecting ENCRYPT_REQUEST" ); - - // Only need to handle this if we want to use encryption - if ( user.getPendingConnection().getForgeLogin() != null ) - { - PublicKey publickey = EncryptionUtil.getPubkey( encryptRequest ); - this.secretkey = EncryptionUtil.getSecret(); - - byte[] shared = EncryptionUtil.encrypt( publickey, secretkey.getEncoded() ); - byte[] token = EncryptionUtil.encrypt( publickey, encryptRequest.getVerifyToken() ); - - ch.write( new EncryptionResponse( shared, token ) ); - - Cipher encrypt = EncryptionUtil.getCipher( Cipher.ENCRYPT_MODE, secretkey ); - ch.addBefore( PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.ENCRYPT_HANDLER, new CipherEncoder( encrypt ) ); - - thisState = State.ENCRYPT_RESPONSE; - } else - { - thisState = State.LOGIN; - } - } - @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.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) ); + ch.addBefore( PipelineUtils.FRAME_DECODER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) ); ch.write( user.getPendingConnection().getForgeLogin() ); @@ -292,7 +252,6 @@ public class ServerConnector extends PacketHandler if ( in.readByte() != 0 ) { // TODO: Using forge flag - ch.getHandle().pipeline().get( PacketDecoder.class ).setProtocol( Forge.getInstance() ); } } 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 117f86c1..6b0771f3 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -30,7 +30,7 @@ import net.md_5.bungee.api.tab.TabListHandler; import net.md_5.bungee.connection.InitialHandler; import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.HandlerBoss; -import net.md_5.bungee.netty.PacketWrapper; +import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.netty.PipelineUtils; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.packet.Chat; 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 e6da72e3..25f73c30 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 @@ -21,13 +21,12 @@ import net.md_5.bungee.api.score.Scoreboard; import net.md_5.bungee.api.score.Team; import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.PacketHandler; -import net.md_5.bungee.netty.PacketWrapper; +import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.packet.KeepAlive; import net.md_5.bungee.protocol.packet.PlayerListItem; import net.md_5.bungee.protocol.packet.ScoreboardObjective; import net.md_5.bungee.protocol.packet.ScoreboardScore; import net.md_5.bungee.protocol.packet.ScoreboardDisplay; -import net.md_5.bungee.protocol.packet.Team; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.Kick; @@ -138,7 +137,7 @@ public class DownstreamBridge extends PacketHandler } @Override - public void handle(Team team) throws Exception + public void handle(net.md_5.bungee.protocol.packet.Team team) throws Exception { Scoreboard serverScoreboard = con.getServerSentScoreboard(); // Remove team and move on 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 c150b090..475d7695 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 @@ -4,14 +4,11 @@ import com.google.common.base.Preconditions; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.netty.util.concurrent.ScheduledFuture; -import java.math.BigInteger; import java.net.InetSocketAddress; import java.net.URLEncoder; import java.security.GeneralSecurityException; -import java.security.MessageDigest; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; import javax.crypto.Cipher; import javax.crypto.SecretKey; @@ -38,23 +35,20 @@ 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.CipherEncoder; -import net.md_5.bungee.netty.PacketDecoder; import net.md_5.bungee.netty.PacketHandler; import net.md_5.bungee.netty.PipelineUtils; -import net.md_5.bungee.protocol.Forge; import net.md_5.bungee.protocol.MinecraftInput; -import net.md_5.bungee.protocol.Vanilla; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.packet.Login; -import net.md_5.bungee.protocol.packet.Packet2Handshake; +import net.md_5.bungee.protocol.packet.Handshake; import net.md_5.bungee.protocol.packet.ClientStatus; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.EncryptionResponse; -import net.md_5.bungee.protocol.packet.PacketFDEncryptionRequest; -import net.md_5.bungee.protocol.packet.PacketFEPing; +import net.md_5.bungee.protocol.packet.EncryptionRequest; import net.md_5.bungee.protocol.packet.Kick; import net.md_5.bungee.api.AbstractReconnectHandler; import net.md_5.bungee.api.event.PlayerHandshakeEvent; +import net.md_5.bungee.protocol.packet.LoginRequest; @RequiredArgsConstructor public class InitialHandler extends PacketHandler implements PendingConnection @@ -67,8 +61,10 @@ public class InitialHandler extends PacketHandler implements PendingConnection @Getter private Login forgeLogin; @Getter - private Packet2Handshake handshake; - private PacketFDEncryptionRequest request; + private Handshake handshake; + @Getter + private LoginRequest loginRequest; + private EncryptionRequest request; @Getter private List loginMessages = new ArrayList<>(); @Getter @@ -170,35 +166,25 @@ public class InitialHandler extends PacketHandler implements PendingConnection forced.ping( pingBack ); } else { - pingBack.done( new ServerPing( bungee.getProtocolVersion(), bungee.getGameVersion(), motd, bungee.getOnlineCount(), listener.getMaxPlayers() ), null ); + // pingBack.done( new ServerPing( bungee.getProtocolVersion(), bungee.getGameVersion(), motd, bungee.getOnlineCount(), listener.getMaxPlayers() ), null ); } } + /* + @Override + public void handle(PacketFEPing ping) throws Exception + { + pingFuture = ch.getHandle().eventLoop().schedule( new Runnable() + { + @Override + public void run() + { + respondToPing(); + } + }, 200, TimeUnit.MILLISECONDS ); + }*/ @Override - public void handle(PacketFEPing ping) throws Exception - { - pingFuture = ch.getHandle().eventLoop().schedule( new Runnable() - { - @Override - public void run() - { - respondToPing(); - } - }, 200, TimeUnit.MILLISECONDS ); - } - - @Override - public void handle(Login login) throws Exception - { - Preconditions.checkState( thisState == State.LOGIN, "Not expecting FORGE LOGIN" ); - Preconditions.checkState( forgeLogin == null, "Already received FORGE LOGIN" ); - forgeLogin = login; - - ch.getHandle().pipeline().get( PacketDecoder.class ).setProtocol( Forge.getInstance() ); - } - - @Override - public void handle(Packet2Handshake handshake) throws Exception + public void handle(Handshake handshake) throws Exception { Preconditions.checkState( thisState == State.HANDSHAKE, "Not expecting HANDSHAKE" ); this.handshake = handshake; @@ -207,15 +193,22 @@ public class InitialHandler extends PacketHandler implements PendingConnection bungee.getPluginManager().callEvent( new PlayerHandshakeEvent( InitialHandler.this, handshake ) ); - if ( handshake.getProtocolVersion() > Vanilla.PROTOCOL_VERSION ) + if ( handshake.getProtocolVersion() > bungee.getProtocolVersion() ) { disconnect( bungee.getTranslation( "outdated_server" ) ); - } else if ( handshake.getProtocolVersion() < Vanilla.PROTOCOL_VERSION ) + } else if ( handshake.getProtocolVersion() < bungee.getProtocolVersion() ) { disconnect( bungee.getTranslation( "outdated_client" ) ); } - if ( handshake.getUsername().length() > 16 ) + } + + @Override + public void handle(LoginRequest loginRequest) throws Exception + { + this.loginRequest = loginRequest; + + if ( getName().length() > 16 ) { disconnect( "Cannot have username longer than 16 characters" ); return; @@ -229,7 +222,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection } // If offline mode and they are already on, don't allow connect - if ( !isOnlineMode() && bungee.getPlayer( handshake.getUsername() ) != null ) + if ( !isOnlineMode() && bungee.getPlayer( getName() ) != null ) { disconnect( bungee.getTranslation( "already_connected" ) ); return; @@ -249,7 +242,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection sharedKey = EncryptionUtil.getSecret( encryptResponse, request ); Cipher decrypt = EncryptionUtil.getCipher( Cipher.DECRYPT_MODE, sharedKey ); - ch.addBefore( PipelineUtils.PACKET_DECODE_HANDLER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) ); + ch.addBefore( PipelineUtils.FRAME_DECODER, PipelineUtils.DECRYPT_HANDLER, new CipherDecoder( decrypt ) ); if ( this.onlineMode ) { @@ -295,7 +288,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection private void finish() { // Check for multiple connections - ProxiedPlayer old = bungee.getPlayer( handshake.getUsername() ); + ProxiedPlayer old = bungee.getPlayer( getName() ); if ( old != null ) { old.disconnect( bungee.getTranslation( "already_connected" ) ); @@ -381,11 +374,11 @@ public class InitialHandler extends PacketHandler implements PendingConnection @Override public String getName() { - return ( handshake == null ) ? null : handshake.getUsername(); + return ( loginRequest == null ) ? null : loginRequest.getData(); } @Override - public byte getVersion() + public int getVersion() { return ( handshake == null ) ? version : handshake.getProtocolVersion(); } 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 eae12258..6fb545b4 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 @@ -10,7 +10,7 @@ import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.event.PluginMessageEvent; import net.md_5.bungee.netty.ChannelWrapper; import net.md_5.bungee.netty.PacketHandler; -import net.md_5.bungee.netty.PacketWrapper; +import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.packet.KeepAlive; import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.TabComplete; diff --git a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java index e16ae233..b4e9fc1d 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/ChannelWrapper.java @@ -1,5 +1,6 @@ package net.md_5.bungee.netty; +import net.md_5.bungee.protocol.PacketWrapper; import com.google.common.base.Preconditions; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; diff --git a/proxy/src/main/java/net/md_5/bungee/netty/DefinedPacketEncoder.java b/proxy/src/main/java/net/md_5/bungee/netty/DefinedPacketEncoder.java deleted file mode 100644 index c5e8b8ff..00000000 --- a/proxy/src/main/java/net/md_5/bungee/netty/DefinedPacketEncoder.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.md_5.bungee.netty; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.MessageToByteEncoder; -import net.md_5.bungee.protocol.DefinedPacket; - -@ChannelHandler.Sharable -public class DefinedPacketEncoder extends MessageToByteEncoder -{ - - @Override - protected void encode(ChannelHandlerContext ctx, DefinedPacket msg, ByteBuf out) throws Exception - { - out.writeByte( msg.getId() ); - msg.write( out ); - } -} diff --git a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java index d3a59eef..fc80d169 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/HandlerBoss.java @@ -1,5 +1,6 @@ package net.md_5.bungee.netty; +import net.md_5.bungee.protocol.PacketWrapper; import com.google.common.base.Preconditions; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PacketDecoder.java b/proxy/src/main/java/net/md_5/bungee/netty/PacketDecoder.java deleted file mode 100644 index 99e959aa..00000000 --- a/proxy/src/main/java/net/md_5/bungee/netty/PacketDecoder.java +++ /dev/null @@ -1,50 +0,0 @@ -package net.md_5.bungee.netty; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.ReplayingDecoder; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; -import net.md_5.bungee.protocol.Protocol; -import net.md_5.bungee.protocol.DefinedPacket; -import net.md_5.bungee.protocol.skip.PacketReader; - -/** - * This class will attempt to read a packet from {@link PacketReader}, with the - * specified {@link #protocol} before returning a new {@link ByteBuf} with the - * copied contents of all bytes read in this frame. - *

- * It is based on {@link ReplayingDecoder} so that packets will only be returned - * when all needed data is present. - */ -@AllArgsConstructor -public class PacketDecoder extends ReplayingDecoder -{ - - @Getter - @Setter - private Protocol protocol; - - @Override - protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception - { - // While we have enough data - while ( true ) - { - // Store our start index - int startIndex = in.readerIndex(); - // Run packet through framer - DefinedPacket packet = protocol.read( in.readUnsignedByte(), in ); - // If we got this far, it means we have formed a packet, so lets grab the end index - int endIndex = in.readerIndex(); - // Allocate a buffer big enough for all bytes we have read - ByteBuf buf = in.copy( startIndex, endIndex - startIndex ); - // Checkpoint our state incase we don't have enough data for another packet - checkpoint(); - // Store our decoded message - out.add( new PacketWrapper( packet, buf ) ); - } - } -} diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java b/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java index e5634c92..08ab8152 100644 --- a/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/netty/PacketHandler.java @@ -1,5 +1,7 @@ package net.md_5.bungee.netty; +import net.md_5.bungee.protocol.PacketWrapper; + public abstract class PacketHandler extends net.md_5.bungee.protocol.AbstractPacketHandler { 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 f37d9951..3c001a89 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 @@ -4,6 +4,7 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelException; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; +import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.util.AttributeKey; import java.net.InetSocketAddress; @@ -15,7 +16,8 @@ import net.md_5.bungee.UserConnection; import net.md_5.bungee.connection.InitialHandler; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ListenerInfo; -import net.md_5.bungee.protocol.Vanilla; +import net.md_5.bungee.protocol.MinecraftCodec; +import net.md_5.bungee.protocol.Protocol; public class PipelineUtils { @@ -49,13 +51,15 @@ public class PipelineUtils } }; public static final Base BASE = new Base(); - private static final DefinedPacketEncoder packetEncoder = new DefinedPacketEncoder(); + private static final ProtobufVarint32FrameDecoder frameDecoder = new ProtobufVarint32FrameDecoder(); + private static final ProtobufVarint32FrameDecoder framePrepender = new ProtobufVarint32FrameDecoder(); public static String TIMEOUT_HANDLER = "timeout"; - public static String PACKET_DECODE_HANDLER = "packet-decoder"; - public static String PACKET_ENCODE_HANDLER = "packet-encoder"; + public static String PACKET_CODEC = "packet-codec"; public static String BOSS_HANDLER = "inbound-boss"; public static String ENCRYPT_HANDLER = "encrypt"; public static String DECRYPT_HANDLER = "decrypt"; + public static String FRAME_DECODER = "frame-decoder"; + public static String FRAME_PREPENDER = "frame-prepender"; public final static class Base extends ChannelInitializer { @@ -72,8 +76,9 @@ public class PipelineUtils } ch.pipeline().addLast( TIMEOUT_HANDLER, new ReadTimeoutHandler( BungeeCord.getInstance().config.getTimeout(), TimeUnit.MILLISECONDS ) ); - ch.pipeline().addLast( PACKET_DECODE_HANDLER, new PacketDecoder( Vanilla.getInstance() ) ); - ch.pipeline().addLast( PACKET_ENCODE_HANDLER, packetEncoder ); + ch.pipeline().addLast( FRAME_DECODER, frameDecoder ); + ch.pipeline().addLast( PACKET_CODEC, new MinecraftCodec( Protocol.SERVER_HANDSHAKE ) ); + ch.pipeline().addLast( FRAME_PREPENDER, framePrepender ); ch.pipeline().addLast( BOSS_HANDLER, new HandlerBoss() ); } };