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 37f0cba9..08b12630 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 @@ -17,6 +17,7 @@ import net.md_5.bungee.protocol.packet.Kick; import net.md_5.bungee.protocol.packet.Respawn; import net.md_5.bungee.protocol.packet.Handshake; import net.md_5.bungee.protocol.packet.EncryptionResponse; +import net.md_5.bungee.protocol.packet.LegacyPing; import net.md_5.bungee.protocol.packet.LoginRequest; import net.md_5.bungee.protocol.packet.LoginSuccess; import net.md_5.bungee.protocol.packet.PingPacket; @@ -27,6 +28,10 @@ import net.md_5.bungee.protocol.packet.TabCompleteResponse; public abstract class AbstractPacketHandler { + public void handle(LegacyPing ping) throws Exception + { + } + public void handle(TabCompleteResponse tabResponse) throws Exception { } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java b/protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java new file mode 100644 index 00000000..eda9571e --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/KickStringWriter.java @@ -0,0 +1,20 @@ +package net.md_5.bungee.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; + +public class KickStringWriter extends MessageToByteEncoder +{ + + @Override + protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out) throws Exception + { + out.writeByte( 0xFF ); + out.writeShort( msg.length() ); + for ( char c : msg.toCharArray() ) + { + out.writeChar( c ); + } + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java new file mode 100644 index 00000000..7cc06d9b --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/LegacyDecoder.java @@ -0,0 +1,31 @@ +package net.md_5.bungee.protocol; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import java.util.List; +import net.md_5.bungee.protocol.packet.LegacyPing; + +public class LegacyDecoder extends ByteToMessageDecoder +{ + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception + { + if ( in.readableBytes() < 3 ) + { + return; + } + int i = in.readerIndex(); + short b1 = in.getUnsignedByte( i++ ); + short b2 = in.getUnsignedByte( i++ ); + short b3 = in.getUnsignedByte( i++ ); + + if ( b1 == 0xFE && b2 == 0x01 && b3 == 0xFA ) + { + out.add( new PacketWrapper( new LegacyPing(), Unpooled.EMPTY_BUFFER ) ); + } + ctx.pipeline().remove( this ); + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java index 1c6476fe..7a222d66 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftDecoder.java @@ -31,8 +31,7 @@ public class MinecraftDecoder extends ByteToMessageDecoder packet.read( in ); if ( in.readableBytes() != 0 ) { - System.out.println( in.toString( Charsets.UTF_8 ) ); - // throw new BadPacketException( "Did not read all bytes from packet " + packet.getClass() + " " + packetId + " Protocol " + protocol + " Direction " + prot ); + throw new BadPacketException( "Did not read all bytes from packet " + packet.getClass() + " " + packetId + " Protocol " + protocol + " Direction " + prot ); } } else { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/LegacyPing.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/LegacyPing.java new file mode 100644 index 00000000..2ead20af --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/LegacyPing.java @@ -0,0 +1,46 @@ +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.protocol.AbstractPacketHandler; +import net.md_5.bungee.protocol.DefinedPacket; + +public class LegacyPing extends DefinedPacket +{ + + @Override + public void read(ByteBuf buf) + { + throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void write(ByteBuf buf) + { + throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public void handle(AbstractPacketHandler handler) throws Exception + { + handler.handle( this ); + } + + @Override + public boolean equals(Object obj) + { + throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public int hashCode() + { + throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public String toString() + { + throw new UnsupportedOperationException( "Not supported yet." ); //To change body of generated methods, choose Tools | Templates. + } + +} 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 a22e3b29..1a0a2db8 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 @@ -1,6 +1,8 @@ package net.md_5.bungee.connection; import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import java.math.BigInteger; import java.net.InetSocketAddress; import java.net.URLEncoder; @@ -44,8 +46,8 @@ 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.PacketWrapper; import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.packet.LegacyPing; import net.md_5.bungee.protocol.packet.LoginRequest; import net.md_5.bungee.protocol.packet.LoginSuccess; import net.md_5.bungee.protocol.packet.PingPacket; @@ -119,6 +121,20 @@ public class InitialHandler extends PacketHandler implements PendingConnection } } + @Override + public void handle(LegacyPing ping) throws Exception + { + String kickMessage = ChatColor.DARK_BLUE + + "\00" + bungee.getProtocolVersion() + + "\00" + bungee.getGameVersion() + + "\00" + listener.getMotd() + + "\00" + bungee.getOnlineCount() + + "\00" + listener.getMaxPlayers(); + + ch.getHandle().writeAndFlush( kickMessage ); + ch.close(); + } + @Override public void handle(StatusRequest statusRequest) throws Exception { @@ -231,7 +247,6 @@ public class InitialHandler extends PacketHandler implements PendingConnection // TODO: Nuuuu Mojang why u do this // unsafe().sendPacket( PacketConstants.I_AM_BUNGEE ); // unsafe().sendPacket( PacketConstants.FORGE_MOD_REQUEST ); - unsafe().sendPacket( request = EncryptionUtil.encryptRequest( this.onlineMode ) ); thisState = State.ENCRYPT; } 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 24a24581..fd22e5c0 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 @@ -14,6 +14,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.KickStringWriter; +import net.md_5.bungee.protocol.LegacyDecoder; import net.md_5.bungee.protocol.MinecraftDecoder; import net.md_5.bungee.protocol.MinecraftEncoder; import net.md_5.bungee.protocol.Protocol; @@ -39,8 +41,10 @@ public class PipelineUtils } BASE.initChannel( ch ); + ch.pipeline().addBefore( FRAME_DECODER, LEGACY_DECODER, new LegacyDecoder() ); ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true ) ); ch.pipeline().addAfter( FRAME_PREPENDER, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true ) ); + ch.pipeline().addBefore( FRAME_PREPENDER, LEGACY_KICKER, new KickStringWriter() ); ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( ProxyServer.getInstance(), ch.attr( LISTENER ).get() ) ); } }; @@ -54,6 +58,8 @@ public class PipelineUtils public static String DECRYPT_HANDLER = "decrypt"; public static String FRAME_DECODER = "frame-decoder"; public static String FRAME_PREPENDER = "frame-prepender"; + public static String LEGACY_DECODER = "legacy-decoder"; + public static String LEGACY_KICKER = "legacy-kick"; public final static class Base extends ChannelInitializer {