From 6d405b6c9b3d6a5ba27bd85be0f33bc52043cf85 Mon Sep 17 00:00:00 2001 From: Troy Frew Date: Tue, 15 Nov 2016 10:31:04 -0500 Subject: [PATCH] 1.7.x Protocol Patch diff --git a/protocol/src/main/java/io/github/waterfallmc/travertine/protocol/MultiVersionPacketV17.java b/protocol/src/main/java/io/github/waterfallmc/travertine/protocol/MultiVersionPacketV17.java new file mode 100644 index 00000000..90064112 --- /dev/null +++ b/protocol/src/main/java/io/github/waterfallmc/travertine/protocol/MultiVersionPacketV17.java @@ -0,0 +1,90 @@ +package io.github.waterfallmc.travertine.protocol; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; + +import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.ProtocolConstants; + +public abstract class MultiVersionPacketV17 extends DefinedPacket +{ + + protected void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + v17Read( buf ); + } + + @Override + public void read0(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + switch ( protocolVersion ) + { + case ProtocolConstants.MINECRAFT_1_7_2: + case ProtocolConstants.MINECRAFT_1_7_6: + v17Read(buf, direction, protocolVersion); + break; + default: + read(buf, direction, protocolVersion); + break; + } + } + + protected void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + v17Write( buf ); + } + + @Override + public void write0(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + switch ( protocolVersion ) + { + case ProtocolConstants.MINECRAFT_1_7_2: + case ProtocolConstants.MINECRAFT_1_7_6: + v17Write(buf, direction, protocolVersion); + break; + default: + write(buf, direction, protocolVersion); + break; + } + } + protected void v17Read(ByteBuf buf) + { + throw new UnsupportedOperationException( "Packet must implement read method" ); + } + + protected void v17Write(ByteBuf buf) + { + throw new UnsupportedOperationException( "Packet must implement write method" ); + } + + public static void v17writeArray(byte[] b, ByteBuf buf, boolean allowExtended) + { + // (Integer.MAX_VALUE & 0x1FFF9A ) = 2097050 - Forge's current upper limit + if ( allowExtended ) + { + Preconditions.checkArgument( b.length <= ( Integer.MAX_VALUE & 0x1FFF9A ), "Cannot send array longer than 2097050 (got %s bytes)", b.length ); + } else + { + Preconditions.checkArgument( b.length <= Short.MAX_VALUE, "Cannot send array longer than Short.MAX_VALUE (got %s bytes)", b.length ); + } + // Write a 2 or 3 byte number that represents the length of the packet. (3 byte "shorts" for Forge only) + // No vanilla packet should give a 3 byte packet, this method will still retain vanilla behaviour. + writeVarShort( buf, b.length ); + buf.writeBytes( b ); + } + + public static byte[] v17readArray(ByteBuf buf) + { + // Read in a 2 or 3 byte number that represents the length of the packet. (3 byte "shorts" for Forge only) + // No vanilla packet should give a 3 byte packet, this method will still retain vanilla behaviour. + int len = readVarShort( buf ); + + // (Integer.MAX_VALUE & 0x1FFF9A ) = 2097050 - Forge's current upper limit + Preconditions.checkArgument( len <= ( Integer.MAX_VALUE & 0x1FFF9A ), "Cannot receive array longer than 2097050 (got %s bytes)", len ); + + byte[] ret = new byte[ len ]; + buf.readBytes( ret ); + return ret; + } +} 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 9951c1f9..34f9c373 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 @@ -233,6 +233,11 @@ public abstract class DefinedPacket read( buf ); } + public void read0(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + read( buf, direction, protocolVersion ); + } + public void write(ByteBuf buf) { throw new UnsupportedOperationException( "Packet must implement write method" ); @@ -243,6 +248,11 @@ public abstract class DefinedPacket write( buf ); } + public void write0(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + write( buf, direction, protocolVersion ); + } + public abstract void handle(AbstractPacketHandler handler) throws Exception; @Override 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 71ddf022..e6f8d705 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 @@ -5,10 +5,11 @@ import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.MessageToMessageDecoder; -import java.util.List; import lombok.AllArgsConstructor; import lombok.Setter; +import java.util.List; + @AllArgsConstructor public class MinecraftDecoder extends MessageToMessageDecoder { @@ -49,7 +50,7 @@ public class MinecraftDecoder extends MessageToMessageDecoder if ( packet != null ) { packetTypeInfo = packet.getClass(); - packet.read( in, prot.getDirection(), protocolVersion ); + packet.read0( in, prot.getDirection(), protocolVersion ); if ( in.isReadable() ) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java index d4b03843..9aac7ca9 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/MinecraftEncoder.java @@ -21,6 +21,6 @@ public class MinecraftEncoder extends MessageToByteEncoder { Protocol.DirectionData prot = ( server ) ? protocol.TO_CLIENT : protocol.TO_SERVER; DefinedPacket.writeVarInt( prot.getId( msg.getClass(), protocolVersion ), out ); - msg.write( out, prot.getDirection(), protocolVersion ); + msg.write0( out, prot.getDirection(), protocolVersion ); } } 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 44dc34ff..a4ab8a0f 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 @@ -54,7 +54,7 @@ public enum Protocol TO_SERVER.registerPacket( Handshake.class, Handshake::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x00 ) // Travertine ); } }, @@ -66,7 +66,7 @@ public enum Protocol TO_CLIENT.registerPacket( KeepAlive.class, KeepAlive::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x00 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x00 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x1F ), map( ProtocolConstants.MINECRAFT_1_13, 0x21 ), map( ProtocolConstants.MINECRAFT_1_14, 0x20 ), @@ -75,7 +75,7 @@ public enum Protocol TO_CLIENT.registerPacket( Login.class, Login::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x01 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x23 ), map( ProtocolConstants.MINECRAFT_1_13, 0x25 ), map( ProtocolConstants.MINECRAFT_1_15, 0x26 ) @@ -83,7 +83,7 @@ public enum Protocol TO_CLIENT.registerPacket( Chat.class, Chat::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x02 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x02 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x0F ), map( ProtocolConstants.MINECRAFT_1_13, 0x0E ), map( ProtocolConstants.MINECRAFT_1_15, 0x0F ) @@ -91,7 +91,7 @@ public enum Protocol TO_CLIENT.registerPacket( Respawn.class, Respawn::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x07 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x07 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x33 ), map( ProtocolConstants.MINECRAFT_1_12, 0x34 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x35 ), @@ -109,7 +109,7 @@ public enum Protocol TO_CLIENT.registerPacket( EntityEffect.class, EntityEffect::new, // Waterfall - speed up packet construction - map(ProtocolConstants.MINECRAFT_1_8, 0x1D), + map(ProtocolConstants.MINECRAFT_1_7_2, 0x1D), // Travertine map(ProtocolConstants.MINECRAFT_1_9, 0x4C), map(ProtocolConstants.MINECRAFT_1_9_4, 0x4B), map(ProtocolConstants.MINECRAFT_1_12, 0x4E), @@ -121,7 +121,7 @@ public enum Protocol TO_CLIENT.registerPacket( EntityRemoveEffect.class, EntityRemoveEffect::new, // Waterfall - speed up packet construction - map(ProtocolConstants.MINECRAFT_1_8, 0x1E), + map(ProtocolConstants.MINECRAFT_1_7_2, 0x1E), // Travertine map(ProtocolConstants.MINECRAFT_1_9, 0x31), map(ProtocolConstants.MINECRAFT_1_12, 0x32), map(ProtocolConstants.MINECRAFT_1_12_1, 0x33), @@ -132,8 +132,7 @@ public enum Protocol // Waterfall end TO_CLIENT.registerPacket( PlayerListItem.class, // PlayerInfo - PlayerListItem::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x38 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x38 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x2D ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x2E ), map( ProtocolConstants.MINECRAFT_1_13, 0x30 ), @@ -143,7 +142,7 @@ public enum Protocol TO_CLIENT.registerPacket( TabCompleteResponse.class, TabCompleteResponse::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x3A ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x3A ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x0E ), map( ProtocolConstants.MINECRAFT_1_13, 0x10 ), map( ProtocolConstants.MINECRAFT_1_15, 0x11 ) @@ -151,7 +150,7 @@ public enum Protocol TO_CLIENT.registerPacket( ScoreboardObjective.class, ScoreboardObjective::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x3B ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x3B ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x3F ), map( ProtocolConstants.MINECRAFT_1_12, 0x41 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x42 ), @@ -162,7 +161,7 @@ public enum Protocol TO_CLIENT.registerPacket( ScoreboardScore.class, ScoreboardScore::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x3C ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x3C ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x42 ), map( ProtocolConstants.MINECRAFT_1_12, 0x44 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x45 ), @@ -173,7 +172,7 @@ public enum Protocol TO_CLIENT.registerPacket( ScoreboardDisplay.class, ScoreboardDisplay::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x3D ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x3D ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x38 ), map( ProtocolConstants.MINECRAFT_1_12, 0x3A ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x3B ), @@ -184,7 +183,7 @@ public enum Protocol TO_CLIENT.registerPacket( Team.class, Team::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x3E ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x3E ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x41 ), map( ProtocolConstants.MINECRAFT_1_12, 0x43 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x44 ), @@ -195,7 +194,7 @@ public enum Protocol TO_CLIENT.registerPacket( PluginMessage.class, PluginMessage::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x3F ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x3F ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x18 ), map( ProtocolConstants.MINECRAFT_1_13, 0x19 ), map( ProtocolConstants.MINECRAFT_1_14, 0x18 ), @@ -204,7 +203,7 @@ public enum Protocol TO_CLIENT.registerPacket( Kick.class, Kick::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x40 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x40 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x1A ), map( ProtocolConstants.MINECRAFT_1_13, 0x1B ), map( ProtocolConstants.MINECRAFT_1_14, 0x1A ), @@ -213,7 +212,7 @@ public enum Protocol TO_CLIENT.registerPacket( Title.class, Title::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x45 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x45 ), // Travertine map( ProtocolConstants.MINECRAFT_1_12, 0x47 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x48 ), map( ProtocolConstants.MINECRAFT_1_13, 0x4B ), @@ -223,7 +222,7 @@ public enum Protocol TO_CLIENT.registerPacket( PlayerListHeaderFooter.class, PlayerListHeaderFooter::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x47 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x47 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x48 ), map( ProtocolConstants.MINECRAFT_1_9_4, 0x47 ), map( ProtocolConstants.MINECRAFT_1_12, 0x49 ), @@ -235,7 +234,7 @@ public enum Protocol TO_CLIENT.registerPacket( EntityStatus.class, EntityStatus::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x1A ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x1A ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x1B ), map( ProtocolConstants.MINECRAFT_1_13, 0x1C ), map( ProtocolConstants.MINECRAFT_1_14, 0x1B ), @@ -257,7 +256,7 @@ public enum Protocol TO_SERVER.registerPacket( KeepAlive.class, KeepAlive::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x00 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x00 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x0B ), map( ProtocolConstants.MINECRAFT_1_12, 0x0C ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x0B ), @@ -267,7 +266,7 @@ public enum Protocol TO_SERVER.registerPacket( Chat.class, Chat::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x01 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x02 ), map( ProtocolConstants.MINECRAFT_1_12, 0x03 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x02 ), @@ -276,7 +275,7 @@ public enum Protocol TO_SERVER.registerPacket( TabCompleteRequest.class, TabCompleteRequest::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x14 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x14 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x01 ), map( ProtocolConstants.MINECRAFT_1_12, 0x02 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x01 ), @@ -286,7 +285,7 @@ public enum Protocol TO_SERVER.registerPacket( ClientSettings.class, ClientSettings::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x15 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x15 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x04 ), map( ProtocolConstants.MINECRAFT_1_12, 0x05 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x04 ), @@ -295,7 +294,7 @@ public enum Protocol TO_SERVER.registerPacket( PluginMessage.class, PluginMessage::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x17 ), + map( ProtocolConstants.MINECRAFT_1_7_2, 0x17 ), // Travertine map( ProtocolConstants.MINECRAFT_1_9, 0x09 ), map( ProtocolConstants.MINECRAFT_1_12, 0x0A ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x09 ), @@ -312,23 +311,23 @@ public enum Protocol TO_CLIENT.registerPacket( StatusResponse.class, StatusResponse::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x00 ) // Travertine ); TO_CLIENT.registerPacket( PingPacket.class, PingPacket::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x01 ) // Travertine ); TO_SERVER.registerPacket( StatusRequest.class, StatusRequest::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x00 ) // Travertine ); TO_SERVER.registerPacket( PingPacket.class, PingPacket::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x01 ) // Travertine ); } }, @@ -340,22 +339,22 @@ public enum Protocol TO_CLIENT.registerPacket( Kick.class, Kick::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x00 ) // Travertine ); TO_CLIENT.registerPacket( EncryptionRequest.class, EncryptionRequest::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x01 ) // Travertine ); TO_CLIENT.registerPacket( LoginSuccess.class, LoginSuccess::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x02 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x02 ) // Travertine ); TO_CLIENT.registerPacket( SetCompression.class, SetCompression::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x03 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x03 ) // Travertine ); TO_CLIENT.registerPacket( LoginPayloadRequest.class, @@ -366,12 +365,12 @@ public enum Protocol TO_SERVER.registerPacket( LoginRequest.class, LoginRequest::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x00 ) // Travertine ); TO_SERVER.registerPacket( EncryptionResponse.class, EncryptionResponse::new, // Waterfall - speed up packet construction - map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) + map( ProtocolConstants.MINECRAFT_1_7_2, 0x01 ) // Travertine ); TO_SERVER.registerPacket( LoginPayloadResponse.class, @@ -491,7 +490,11 @@ public enum Protocol } if ( !hasPacket(id, supportsForge) ) { - throw new BadPacketException( "Packet with id " + id + " outside of range " ); + if ( ProtocolConstants.isBeforeOrEq( version, ProtocolConstants.MINECRAFT_1_7_6 ) ) { + return null; + } else { + throw new BadPacketException( "Packet with id " + id + " outside of range " ); + } } java.util.function.Supplier constructor = protocolData.packetConstructors[id]; // Waterfall - speed up packet construction diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java b/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java index 20bbd5db..be966c44 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/ProtocolConstants.java @@ -6,6 +6,8 @@ import java.util.List; public class ProtocolConstants { + public static final int MINECRAFT_1_7_2 = 4; + public static final int MINECRAFT_1_7_6 = 5; public static final int MINECRAFT_1_8 = 47; public static final int MINECRAFT_1_9 = 107; public static final int MINECRAFT_1_9_1 = 108; @@ -28,6 +30,7 @@ public class ProtocolConstants public static final int MINECRAFT_1_15 = 573; public static final int MINECRAFT_1_15_1 = 575; public static final List SUPPORTED_VERSIONS = Arrays.asList( + "1.7.x", "1.8.x", "1.9.x", "1.10.x", @@ -38,6 +41,8 @@ public class ProtocolConstants "1.15.x" ); public static final List SUPPORTED_VERSION_IDS = Arrays.asList( + ProtocolConstants.MINECRAFT_1_7_2, + ProtocolConstants.MINECRAFT_1_7_6, ProtocolConstants.MINECRAFT_1_8, ProtocolConstants.MINECRAFT_1_9, ProtocolConstants.MINECRAFT_1_9_1, diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java index 743d65e4..37bf6b4b 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/Varint21FrameDecoder.java @@ -6,10 +6,12 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.CorruptedFrameException; import java.util.List; +import java.util.concurrent.atomic.AtomicLong; public class Varint21FrameDecoder extends ByteToMessageDecoder { + private AtomicLong lastEmptyPacket = new AtomicLong(0); // Travertine private static boolean DIRECT_WARNING; @Override @@ -34,7 +36,15 @@ public class Varint21FrameDecoder extends ByteToMessageDecoder // Waterfall end if ( false && length == 0) // Waterfall - ignore { - throw new CorruptedFrameException( "Empty Packet!" ); + // Travertine start - vanilla 1.7 client sometimes sends empty packets. + long currentTime = System.currentTimeMillis(); + long lastEmptyPacket = this.lastEmptyPacket.getAndSet(currentTime); + + if (currentTime - lastEmptyPacket < 50L) + { + throw new CorruptedFrameException( "Too many empty packets" ); + } + // Travertine end } if ( in.readableBytes() < length ) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java index 0ded6739..e82900c7 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Chat.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; @@ -13,7 +14,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class Chat extends DefinedPacket +public class Chat extends MultiVersionPacketV17 { private String message; @@ -24,6 +25,14 @@ public class Chat extends DefinedPacket this( message, (byte) 0 ); } + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + message = readString( buf ); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -39,6 +48,14 @@ public class Chat extends DefinedPacket } } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( message, buf ); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientSettings.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientSettings.java index 9daf7a73..b7640fcb 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientSettings.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientSettings.java @@ -1,5 +1,7 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; +import net.md_5.bungee.protocol.DefinedPacket; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; @@ -13,7 +15,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class ClientSettings extends DefinedPacket +public class ClientSettings extends MultiVersionPacketV17 { private String locale; @@ -24,6 +26,19 @@ public class ClientSettings extends DefinedPacket private byte skinParts; private int mainHand; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + locale = readString( buf ); + viewDistance = buf.readByte(); + chatFlags = buf.readUnsignedByte(); + chatColours = buf.readBoolean(); + skinParts = buf.readByte(); + difficulty = buf.readByte(); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -58,6 +73,19 @@ public class ClientSettings extends DefinedPacket } } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( locale, buf ); + buf.writeByte( viewDistance ); + buf.writeByte( chatFlags ); + buf.writeBoolean( chatColours ); + buf.writeByte( skinParts ); + buf.writeByte( difficulty ); + } + // Travertine end + @Override public void handle(AbstractPacketHandler handler) throws Exception { 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 index a29524ca..8d9f4ccb 100644 --- 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 @@ -1,25 +1,35 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; 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; import net.md_5.bungee.protocol.ProtocolConstants; @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class EncryptionRequest extends DefinedPacket +public class EncryptionRequest extends MultiVersionPacketV17 { private String serverId; private byte[] publicKey; private byte[] verifyToken; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + serverId = readString( buf ); + publicKey = v17readArray( buf ); + verifyToken = v17readArray( buf ); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -28,6 +38,16 @@ public class EncryptionRequest extends DefinedPacket verifyToken = readArray( buf ); } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( serverId, buf ); + v17writeArray( publicKey, buf, false ); + v17writeArray( verifyToken, buf, false ); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionResponse.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionResponse.java index 388f6cdb..7f124322 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionResponse.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EncryptionResponse.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; @@ -13,12 +14,21 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class EncryptionResponse extends DefinedPacket +public class EncryptionResponse extends MultiVersionPacketV17 { private byte[] sharedSecret; private byte[] verifyToken; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + sharedSecret = v17readArray( buf ); + verifyToken = v17readArray( buf ); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -26,6 +36,15 @@ public class EncryptionResponse extends DefinedPacket verifyToken = readArray( buf, 128 ); } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + v17writeArray( sharedSecret, buf, false ); + v17writeArray( verifyToken, buf, false ); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityEffect.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityEffect.java index d11a9ea9..07fc21b6 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityEffect.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityEffect.java @@ -1,18 +1,19 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; 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; +import net.md_5.bungee.protocol.ProtocolConstants; @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class EntityEffect extends DefinedPacket { +public class EntityEffect extends MultiVersionPacketV17 { private int entityId; private int effectId; @@ -20,6 +21,14 @@ public class EntityEffect extends DefinedPacket { private int duration; private boolean hideParticles; + @Override + protected void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { + this.entityId = buf.readInt(); + this.effectId = buf.readUnsignedByte(); + this.amplifier = buf.readUnsignedByte(); + this.duration = buf.readShort(); + } + @Override public void read(ByteBuf buf) { this.entityId = readVarInt(buf); @@ -29,6 +38,14 @@ public class EntityEffect extends DefinedPacket { this.hideParticles = buf.readBoolean(); } + @Override + protected void v17Write(ByteBuf buf) { + buf.writeInt(effectId); + buf.writeByte(effectId); + buf.writeByte(amplifier); + buf.writeShort(duration); + } + @Override public void write(ByteBuf buf) { writeVarInt(this.entityId, buf); diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityRemoveEffect.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityRemoveEffect.java index 7ed2dc3a..9f8d56fc 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityRemoveEffect.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/EntityRemoveEffect.java @@ -1,18 +1,18 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; 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 EntityRemoveEffect extends DefinedPacket { +public class EntityRemoveEffect extends MultiVersionPacketV17 { private int entityId; private int effectId; @@ -23,9 +23,15 @@ public class EntityRemoveEffect extends DefinedPacket { this.effectId = buf.readUnsignedByte(); } + @Override + protected void v17Read(ByteBuf buf) { + this.entityId = buf.readInt(); + this.effectId = buf.readUnsignedByte(); + } + @Override public void write(ByteBuf buf) { - writeVarInt(this.entityId, buf); + writeVarInt(entityId, buf); buf.writeByte(effectId); } @@ -33,4 +39,10 @@ public class EntityRemoveEffect extends DefinedPacket { public void handle(AbstractPacketHandler handler) throws Exception { handler.handle(this); } + + @Override + protected void v17Write(ByteBuf buf) { + buf.writeInt(entityId); + buf.writeByte(effectId); + } } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/KeepAlive.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/KeepAlive.java index b004bc41..0c2eb022 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/KeepAlive.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/KeepAlive.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; @@ -13,17 +14,33 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class KeepAlive extends DefinedPacket +public class KeepAlive extends MultiVersionPacketV17 { private long randomId; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + randomId = buf.readInt(); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { randomId = ( protocolVersion >= ProtocolConstants.MINECRAFT_1_12_2 ) ? buf.readLong() : readVarInt( buf ); } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + buf.writeInt((int) randomId); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java index 92bacc7c..c919f961 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItem.java @@ -1,5 +1,7 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; +import net.md_5.bungee.protocol.DefinedPacket; import io.netty.buffer.ByteBuf; import java.util.UUID; import lombok.Data; @@ -12,12 +14,24 @@ import net.md_5.bungee.protocol.ProtocolConstants; @Data @NoArgsConstructor @EqualsAndHashCode(callSuper = false) -public class PlayerListItem extends DefinedPacket +public class PlayerListItem extends MultiVersionPacketV17 { private Action action; private Item[] items; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + items = new Item[ 1 ]; + Item item = items[ 0 ] = new Item(); + item.displayName = item.username = readString( buf ); + action = !buf.readBoolean() ? Action.REMOVE_PLAYER : Action.ADD_PLAYER; + item.ping = buf.readShort(); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -72,6 +86,17 @@ public class PlayerListItem extends DefinedPacket } } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + Item item = items[0]; // Only one at a time + writeString( item.displayName, buf ); // TODO: Server unique only! + buf.writeBoolean( action != Action.REMOVE_PLAYER ); + buf.writeShort( item.ping ); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java index 17e12655..c49c5a56 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PluginMessage.java @@ -3,6 +3,8 @@ package net.md_5.bungee.protocol.packet; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; // Waterfall import java.io.ByteArrayInputStream; @@ -21,7 +23,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class PluginMessage extends DefinedPacket +public class PluginMessage extends MultiVersionPacketV17 { public static final Function MODERNISE = new Function() @@ -79,6 +81,15 @@ public class PluginMessage extends DefinedPacket */ private boolean allowExtendedPacket = false; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + tag = readString( buf ); + data = v17readArray( buf ); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -89,6 +100,15 @@ public class PluginMessage extends DefinedPacket buf.readBytes( data ); } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( tag, buf ); + v17writeArray( data, buf, allowExtendedPacket ); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java index 3c7905d5..fe290fa3 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardObjective.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; import io.netty.buffer.ByteBuf; import java.util.Locale; import lombok.AllArgsConstructor; @@ -14,7 +15,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class ScoreboardObjective extends DefinedPacket +public class ScoreboardObjective extends MultiVersionPacketV17 { private String name; @@ -25,6 +26,16 @@ public class ScoreboardObjective extends DefinedPacket */ private byte action; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + name = readString( buf ); + value = readString( buf ); + action = buf.readByte(); + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -43,6 +54,16 @@ public class ScoreboardObjective extends DefinedPacket } } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( name, buf ); + writeString( value, buf ); + buf.writeByte( action ); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardScore.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardScore.java index 0b27fc86..74066702 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardScore.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ScoreboardScore.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; @@ -13,7 +14,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class ScoreboardScore extends DefinedPacket +public class ScoreboardScore extends MultiVersionPacketV17 { private String itemName; @@ -24,6 +25,20 @@ public class ScoreboardScore extends DefinedPacket private String scoreName; private int value; + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + itemName = readString( buf ); + action = buf.readByte(); + if ( action != 1 ) + { + scoreName = readString( buf ); + value = buf.readInt(); + } + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -36,6 +51,20 @@ public class ScoreboardScore extends DefinedPacket } } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( itemName, buf ); + buf.writeByte( action ); + if ( action != 1 ) + { + writeString( scoreName, buf ); + buf.writeInt( value ); + } + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java index d6865ae2..01e38206 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/TabCompleteRequest.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; import io.netty.buffer.ByteBuf; import lombok.Data; import lombok.EqualsAndHashCode; @@ -11,7 +12,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; @Data @NoArgsConstructor @EqualsAndHashCode(callSuper = false) -public class TabCompleteRequest extends DefinedPacket +public class TabCompleteRequest extends MultiVersionPacketV17 { private int transactionId; @@ -33,6 +34,13 @@ public class TabCompleteRequest extends DefinedPacket this.hasPositon = hasPosition; this.position = position; } + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + cursor = readString( buf ); + } + // Travertine end @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) @@ -57,6 +65,14 @@ public class TabCompleteRequest extends DefinedPacket } } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( cursor, buf ); + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java index 85d386c0..7a80acac 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Team.java @@ -1,5 +1,6 @@ package net.md_5.bungee.protocol.packet; +import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; import io.netty.buffer.ByteBuf; import lombok.AllArgsConstructor; import lombok.Data; @@ -13,7 +14,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) -public class Team extends DefinedPacket +public class Team extends MultiVersionPacketV17 { private String name; @@ -39,6 +40,31 @@ public class Team extends DefinedPacket this.mode = 1; } + // Travertine start + @Override + public void v17Read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + name = readString( buf ); + mode = buf.readByte(); + if ( mode == 0 || mode == 2 ) + { + displayName = readString( buf ); + prefix = readString( buf ); + suffix = readString( buf ); + friendlyFire = buf.readByte(); + } + if ( mode == 0 || mode == 3 || mode == 4 ) + { + int len = buf.readShort(); + players = new String[ len ]; + for ( int i = 0; i < len; i++ ) + { + players[i] = readString( buf ); + } + } + } + // Travertine end + @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { @@ -76,6 +102,30 @@ public class Team extends DefinedPacket } } + // Travertine start + @Override + public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + writeString( name, buf ); + buf.writeByte( mode ); + if ( mode == 0 || mode == 2 ) + { + writeString( displayName, buf ); + writeString( prefix, buf ); + writeString( suffix, buf ); + buf.writeByte( friendlyFire ); + } + if ( mode == 0 || mode == 3 || mode == 4 ) + { + buf.writeShort( players.length ); + for ( String player : players ) + { + writeString( player, buf ); + } + } + } + // Travertine end + @Override public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { 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 0c90b978..a3ba3521 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -162,6 +162,14 @@ public class BungeeCord extends ProxyServer .registerTypeAdapter( SelectorComponent.class, new SelectorComponentSerializer() ) .registerTypeAdapter( ServerPing.PlayerInfo.class, new PlayerInfoSerializer() ) .registerTypeAdapter( Favicon.class, Favicon.getFaviconTypeAdapter() ).create(); + // Travertine start + public final Gson gsonLegacy = new GsonBuilder() + .registerTypeAdapter( BaseComponent.class, new ComponentSerializer() ) + .registerTypeAdapter( TextComponent.class, new TextComponentSerializer() ) + .registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ) + .registerTypeAdapter( ServerPing.PlayerInfo.class, new PlayerInfoSerializer( ProtocolConstants.MINECRAFT_1_7_2 ) ) + .registerTypeAdapter( Favicon.class, Favicon.getFaviconTypeAdapter() ).create(); + // Travertine end @Getter private ConnectionThrottle connectionThrottle; private final ModuleManager moduleManager = new ModuleManager(); diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java b/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java index 494213db..1d89acf5 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeTitle.java @@ -5,6 +5,7 @@ import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.chat.ComponentSerializer; import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.packet.Title.Action; public class BungeeTitle implements Title @@ -151,6 +152,7 @@ public class BungeeTitle implements Title @Override public Title send(ProxiedPlayer player) { + if ( ProtocolConstants.isBeforeOrEq( player.getPendingConnection().getVersion(), ProtocolConstants.MINECRAFT_1_7_6 ) ) return this; sendPacket( player, clear ); sendPacket( player, reset ); sendPacket( player, times ); diff --git a/proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java b/proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java index 491cf1a1..299a216c 100644 --- a/proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java +++ b/proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java @@ -10,17 +10,32 @@ import com.google.gson.JsonSerializer; import java.lang.reflect.Type; import java.util.UUID; import net.md_5.bungee.api.ServerPing; +import net.md_5.bungee.protocol.ProtocolConstants; public class PlayerInfoSerializer implements JsonSerializer, JsonDeserializer { + // Travertine start + private final int protocol; + + public PlayerInfoSerializer() + { + this.protocol = ProtocolConstants.MINECRAFT_1_7_6; + } + + public PlayerInfoSerializer(int protocol) + { + this.protocol = protocol; + } + // Travertine end + @Override public ServerPing.PlayerInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject js = json.getAsJsonObject(); ServerPing.PlayerInfo info = new ServerPing.PlayerInfo( js.get( "name" ).getAsString(), (UUID) null ); String id = js.get( "id" ).getAsString(); - if ( !id.contains( "-" ) ) + if ( ProtocolConstants.isBeforeOrEq( protocol, ProtocolConstants.MINECRAFT_1_7_2 ) || !id.contains( "-" ) ) // Travertine { info.setId( id ); } else @@ -35,7 +50,15 @@ public class PlayerInfoSerializer implements JsonSerializer= ProtocolConstants.MINECRAFT_1_13 ? "minecraft:brand" : "MC|Brand", brand, handshakeHandler.isServerForge() ) ); - brand.release(); + // Travertine start + String brandString = bungee.getName() + " (" + bungee.getVersion() + ")"; + + if ( ProtocolConstants.isBeforeOrEq( user.getPendingConnection().getVersion(), ProtocolConstants.MINECRAFT_1_7_6 ) ) + { + user.unsafe().sendPacket( new PluginMessage( "MC|Brand", brandString.getBytes( StandardCharsets.UTF_8 ), handshakeHandler.isServerForge() ) ); + } else + { + ByteBuf brand = ByteBufAllocator.DEFAULT.heapBuffer(); + DefinedPacket.writeString(brandString, brand); + user.unsafe().sendPacket( new PluginMessage( user.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ? "minecraft:brand" : "MC|Brand", brand, handshakeHandler.isServerForge() ) ); + brand.release(); + } + // Travertine end user.setDimension( login.getDimension() ); } else @@ -263,7 +274,7 @@ public class ServerConnector extends PacketHandler if ( !user.isDisableEntityMetadataRewrite() ) { // Waterfall for ( Objective objective : serverScoreboard.getObjectives() ) { - user.unsafe().sendPacket( new ScoreboardObjective( objective.getName(), objective.getValue(), ScoreboardObjective.HealthDisplay.fromString( objective.getType() ), (byte) 1 ) ); + user.unsafe().sendPacket( new ScoreboardObjective( objective.getName(), objective.getValue(), objective.getType() == null ? null : ScoreboardObjective.HealthDisplay.fromString(objective.getType()), (byte) 1 ) ); // Travertine - 1.7 } for ( Score score : serverScoreboard.getScores() ) { @@ -425,6 +436,14 @@ public class ServerConnector extends PacketHandler { this.handshakeHandler.handle( pluginMessage ); + // Travertine start + if ( user.getForgeClientHandler().checkUserOutdated() ) + { + ch.close(); + user.getPendingConnects().remove(target); + } + // Travertine end + // We send the message as part of the handler, so don't send it here. throw CancelSendSignal.INSTANCE; } 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 eeb7a51e..04f2af59 100644 --- a/proxy/src/main/java/net/md_5/bungee/UserConnection.java +++ b/proxy/src/main/java/net/md_5/bungee/UserConnection.java @@ -53,6 +53,7 @@ import net.md_5.bungee.protocol.MinecraftDecoder; import net.md_5.bungee.protocol.MinecraftEncoder; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.ProtocolConstants; // Travertine import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.ClientSettings; import net.md_5.bungee.protocol.packet.Kick; @@ -194,6 +195,7 @@ public final class UserConnection implements ProxiedPlayer public void setDisplayName(String name) { Preconditions.checkNotNull( name, "displayName" ); + Preconditions.checkArgument( name.length() <= 16, "Display name cannot be longer than 16 characters" ); // Travertine displayName = name; } @@ -476,7 +478,7 @@ public final class UserConnection implements ProxiedPlayer message = ChatComponentTransformer.getInstance().transform( this, message ); // Action bar doesn't display the new JSON formattings, legacy works - send it using this for now - if ( position == ChatMessageType.ACTION_BAR ) + if ( position == ChatMessageType.ACTION_BAR && getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_8 ) // Travertine { sendMessage( position, ComponentSerializer.toString( new TextComponent( BaseComponent.toLegacyText( message ) ) ) ); } else @@ -491,7 +493,7 @@ public final class UserConnection implements ProxiedPlayer message = ChatComponentTransformer.getInstance().transform( this, message )[0]; // Action bar doesn't display the new JSON formattings, legacy works - send it using this for now - if ( position == ChatMessageType.ACTION_BAR ) + if ( position == ChatMessageType.ACTION_BAR && getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_8 ) // Travertine { sendMessage( position, ComponentSerializer.toString( new TextComponent( BaseComponent.toLegacyText( message ) ) ) ); } else @@ -670,6 +672,7 @@ public final class UserConnection implements ProxiedPlayer @Override public void setTabHeader(BaseComponent header, BaseComponent footer) { + if ( ProtocolConstants.isBeforeOrEq( pendingConnection.getVersion(), ProtocolConstants.MINECRAFT_1_7_6 ) ) return; // Travertine header = ChatComponentTransformer.getInstance().transform( this, header )[0]; footer = ChatComponentTransformer.getInstance().transform( this, footer )[0]; @@ -682,6 +685,7 @@ public final class UserConnection implements ProxiedPlayer @Override public void setTabHeader(BaseComponent[] header, BaseComponent[] footer) { + if ( ProtocolConstants.isBeforeOrEq( pendingConnection.getVersion(), ProtocolConstants.MINECRAFT_1_7_6 ) ) return; // Travertine header = ChatComponentTransformer.getInstance().transform( this, header ); footer = ChatComponentTransformer.getInstance().transform( this, footer ); @@ -711,6 +715,7 @@ public final class UserConnection implements ProxiedPlayer public void setCompressionThreshold(int compressionThreshold) { + if ( ProtocolConstants.isBeforeOrEq( pendingConnection.getVersion(), ProtocolConstants.MINECRAFT_1_7_6 ) ) return; // Travertine if ( !ch.isClosing() && this.compressionThreshold == -1 && compressionThreshold >= 0 ) { this.compressionThreshold = compressionThreshold; 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 1f8a2439..8e1830e8 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 @@ -161,7 +161,7 @@ public class DownstreamBridge extends PacketHandler switch ( objective.getAction() ) { case 0: - serverScoreboard.addObjective( new Objective( objective.getName(), objective.getValue(), objective.getType().toString() ) ); + serverScoreboard.addObjective( new Objective( objective.getName(), objective.getValue(), objective.getType() != null ? objective.getType().toString() : null) ); // Travertine - 1.7 protocol support break; case 1: serverScoreboard.removeObjective( objective.getName() ); @@ -171,7 +171,7 @@ public class DownstreamBridge extends PacketHandler if ( oldObjective != null ) { oldObjective.setValue( objective.getValue() ); - oldObjective.setType( objective.getType().toString() ); + oldObjective.setType( objective.getType() != null ? objective.getType().toString() : null ); // Travertine - 1.7 protocol support } break; default: @@ -268,16 +268,28 @@ public class DownstreamBridge extends PacketHandler if ( pluginMessage.getTag().equals( con.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_13 ? "minecraft:brand" : "MC|Brand" ) ) { - ByteBuf brand = Unpooled.wrappedBuffer( pluginMessage.getData() ); - String serverBrand = DefinedPacket.readString( brand ); - brand.release(); - - Preconditions.checkState( !serverBrand.contains( bungee.getName() ), "Cannot connect proxy to itself!" ); - - brand = ByteBufAllocator.DEFAULT.heapBuffer(); - DefinedPacket.writeString( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand, brand ); - pluginMessage.setData( brand ); - brand.release(); + // Travertine start + if ( ProtocolConstants.isAfterOrEq( con.getPendingConnection().getVersion(), ProtocolConstants.MINECRAFT_1_8 ) ) + { + try + { + ByteBuf brand = Unpooled.wrappedBuffer(pluginMessage.getData()); + String serverBrand = DefinedPacket.readString(brand); + brand.release(); + brand = ByteBufAllocator.DEFAULT.heapBuffer(); + DefinedPacket.writeString(bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand, brand); + pluginMessage.setData(brand); + brand.release(); + } catch (Exception ProtocolHacksSuck) + { + return; + } + } else + { + String serverBrand = new String( pluginMessage.getData(), "UTF-8" ); + pluginMessage.setData( ( bungee.getName() + " (" + bungee.getVersion() + ")" + " <- " + serverBrand ).getBytes( "UTF-8" ) ); + } + // Travertine end // changes in the packet are ignored so we need to send it manually con.unsafe().sendPacket( pluginMessage ); throw CancelSendSignal.INSTANCE; 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 34f7f997..5ef8c7c8 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 @@ -11,6 +11,13 @@ import java.util.List; import java.util.UUID; import java.util.logging.Level; import javax.crypto.SecretKey; + +import com.google.common.base.Charsets; +import com.google.common.base.Preconditions; +import com.google.gson.Gson; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.md_5.bungee.BungeeCord; @@ -232,12 +239,28 @@ public class InitialHandler extends PacketHandler implements PendingConnection @Override public void done(ProxyPingEvent pingResult, Throwable error) { - Gson gson = BungeeCord.getInstance().gson; - unsafe.sendPacket( new StatusResponse( gson.toJson( pingResult.getResponse() ) ) ); + Gson gson = handshake.getProtocolVersion() == ProtocolConstants.MINECRAFT_1_7_2 ? BungeeCord.getInstance().gsonLegacy : BungeeCord.getInstance().gson; // Travertine if ( bungee.getConnectionThrottle() != null ) { bungee.getConnectionThrottle().unthrottle( getAddress().getAddress() ); } + // Travertine start + if ( ProtocolConstants.isBeforeOrEq( handshake.getProtocolVersion() , ProtocolConstants.MINECRAFT_1_8 ) ) + { + // Minecraft < 1.9 doesn't send string server descriptions as chat components. Older 1.7 + // clients even crash when encountering a chat component instead of a string. To be on the + // safe side, always send legacy descriptions for < 1.9 clients. + JsonElement element = gson.toJsonTree(pingResult.getResponse()); + Preconditions.checkArgument(element.isJsonObject(), "Response is not a JSON object"); + JsonObject object = element.getAsJsonObject(); + object.addProperty("description", pingResult.getResponse().getDescription()); + + unsafe.sendPacket(new StatusResponse(gson.toJson(element))); + } else + { + unsafe.sendPacket( new StatusResponse( gson.toJson( pingResult.getResponse() ) ) ); + } + // Travertine end } }; @@ -519,7 +542,15 @@ public class InitialHandler extends PacketHandler implements PendingConnection userCon.setCompressionThreshold( BungeeCord.getInstance().config.getCompressionThreshold() ); userCon.init(); - unsafe.sendPacket( new LoginSuccess( getUniqueId().toString(), getName() ) ); // With dashes in between + // Travertine start + if ( ProtocolConstants.isAfterOrEq( getVersion() , ProtocolConstants.MINECRAFT_1_7_6 ) ) + { + unsafe.sendPacket( new LoginSuccess( getUniqueId().toString(), getName() ) ); // With dashes in between + } else + { + unsafe.sendPacket( new LoginSuccess( getUUID(), getName() ) ); // Without dashes, for older clients. + } + // Travertine end ch.setProtocol( Protocol.GAME ); ch.getHandle().pipeline().get( HandlerBoss.class ).setHandler( new UpstreamBridge( bungee, userCon ) ); diff --git a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java index 6bc14d67..2b3bc361 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java @@ -15,6 +15,7 @@ import net.md_5.bungee.protocol.MinecraftDecoder; import net.md_5.bungee.protocol.MinecraftEncoder; import net.md_5.bungee.protocol.PacketWrapper; import net.md_5.bungee.protocol.Protocol; +import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.packet.Handshake; import net.md_5.bungee.protocol.packet.StatusRequest; import net.md_5.bungee.protocol.packet.StatusResponse; @@ -64,7 +65,7 @@ public class PingHandler extends PacketHandler @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") public void handle(StatusResponse statusResponse) throws Exception { - Gson gson = BungeeCord.getInstance().gson; + Gson gson = protocol == ProtocolConstants.MINECRAFT_1_7_2 ? BungeeCord.getInstance().gsonLegacy : BungeeCord.getInstance().gson; // Travertine callback.done( gson.fromJson( statusResponse.getResponse(), ServerPing.class ), null ); channel.close(); } 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 51d0c6cf..35b9530a 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 @@ -83,7 +83,12 @@ public class UpstreamBridge extends PacketHandler } ); for ( ProxiedPlayer player : con.getServer().getInfo().getPlayers() ) { - player.unsafe().sendPacket( packet ); + // Travertine start + if ( ProtocolConstants.isAfterOrEq( player.getPendingConnection().getVersion(), ProtocolConstants.MINECRAFT_1_8 ) ) + { + player.unsafe().sendPacket( packet ); + } + // Travertine end } con.getServer().disconnect( "Quitting" ); } diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java index 066135ad..08db1f17 100644 --- a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap.java @@ -35,6 +35,10 @@ public abstract class EntityMap // Waterfall end switch ( version ) { + case ProtocolConstants.MINECRAFT_1_7_2: + return EntityMap_1_7_2.INSTANCE; + case ProtocolConstants.MINECRAFT_1_7_6: + return EntityMap_1_7_6.INSTANCE; case ProtocolConstants.MINECRAFT_1_8: return EntityMap_1_8.INSTANCE; case ProtocolConstants.MINECRAFT_1_9: diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_7_2.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_7_2.java new file mode 100644 index 00000000..65c1a9ec --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_7_2.java @@ -0,0 +1,102 @@ +// Travertine start +package net.md_5.bungee.entitymap; + +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.protocol.DefinedPacket; +import net.md_5.bungee.protocol.ProtocolConstants; + +class EntityMap_1_7_2 extends EntityMap +{ + + static final EntityMap INSTANCE = new EntityMap_1_7_2(); + + EntityMap_1_7_2() + { + addRewrite( 0x04, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Equipment + addRewrite( 0x0A, ProtocolConstants.Direction.TO_CLIENT, false ); // Use bed + addRewrite( 0x0B, ProtocolConstants.Direction.TO_CLIENT, true ); // Animation + addRewrite( 0x0C, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Player + addRewrite( 0x0D, ProtocolConstants.Direction.TO_CLIENT, false ); // Collect Item + addRewrite( 0x0E, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Object + addRewrite( 0x0F, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Mob + addRewrite( 0x10, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Painting + addRewrite( 0x11, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Experience Orb + addRewrite( 0x12, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Velocity + addRewrite( 0x14, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity + addRewrite( 0x15, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Relative Move + addRewrite( 0x16, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Look + addRewrite( 0x17, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Look and Relative Move + addRewrite( 0x18, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Teleport + addRewrite( 0x19, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Head Look + addRewrite( 0x1A, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Status + addRewrite( 0x1B, ProtocolConstants.Direction.TO_CLIENT, false ); // Attach Entity + addRewrite( 0x1C, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Metadata + addRewrite( 0x1D, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Effect + addRewrite( 0x1E, ProtocolConstants.Direction.TO_CLIENT, false ); // Remove Entity Effect + addRewrite( 0x20, ProtocolConstants.Direction.TO_CLIENT, false ); // Entity Properties + addRewrite( 0x25, ProtocolConstants.Direction.TO_CLIENT, true ); // Block Break Animation + addRewrite( 0x2C, ProtocolConstants.Direction.TO_CLIENT, true ); // Spawn Global Entity + + addRewrite( 0x02, ProtocolConstants.Direction.TO_SERVER, false ); // Use Entity + addRewrite( 0x0A, ProtocolConstants.Direction.TO_SERVER, false ); // Animation + addRewrite( 0x0B, ProtocolConstants.Direction.TO_SERVER, false ); // Entity Action + } + + @Override + public void rewriteClientbound(ByteBuf packet, int oldId, int newId) + { + super.rewriteClientbound( packet, oldId, newId ); + + //Special cases + int readerIndex = packet.readerIndex(); + int packetId = DefinedPacket.readVarInt( packet ); + int packetIdLength = packet.readerIndex() - readerIndex; + if ( packetId == 0x0D /* Collect Item */ || packetId == 0x1B /* Attach Entity */ ) + { + rewriteInt( packet, oldId, newId, readerIndex + packetIdLength + 4 ); + } else if ( packetId == 0x13 /* Destroy Entities */ ) + { + int count = packet.getByte( packetIdLength ); + for ( int i = 0; i < count; i++ ) + { + rewriteInt( packet, oldId, newId, packetIdLength + 1 + i * 4 ); + } + } else if ( packetId == 0x0E /* Spawn Object */ ) + { + DefinedPacket.readVarInt( packet ); + int type = packet.readUnsignedByte(); + + if ( type == 60 || type == 90 ) + { + packet.skipBytes( 14 ); + int position = packet.readerIndex(); + int readId = packet.readInt(); + int changedId = -1; + if ( readId == oldId ) + { + packet.setInt( position, newId ); + changedId = newId; + } else if ( readId == newId ) + { + packet.setInt( position, oldId ); + changedId = oldId; + } + if ( changedId != -1 ) + { + if ( changedId == 0 && readId != 0 ) + { // Trim off the extra data + packet.readerIndex( readerIndex ); + packet.writerIndex( packet.readableBytes() - 6 ); + } else if ( changedId != 0 && readId == 0 ) + { // Add on the extra data + packet.readerIndex( readerIndex ); + packet.capacity( packet.readableBytes() + 6 ); + packet.writerIndex( packet.readableBytes() + 6 ); + } + } + } + } + packet.readerIndex( readerIndex ); + } +} +// Travertine end diff --git a/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_7_6.java b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_7_6.java new file mode 100644 index 00000000..6755fe84 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/entitymap/EntityMap_1_7_6.java @@ -0,0 +1,62 @@ +// Travertine start +package net.md_5.bungee.entitymap; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import io.netty.buffer.ByteBuf; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.UserConnection; +import net.md_5.bungee.connection.LoginResult; +import net.md_5.bungee.protocol.DefinedPacket; + +class EntityMap_1_7_6 extends EntityMap_1_7_2 +{ + + static final EntityMap_1_7_6 INSTANCE = new EntityMap_1_7_6(); + + @Override + @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE") + public void rewriteClientbound(ByteBuf packet, int oldId, int newId) + { + super.rewriteClientbound( packet, oldId, newId ); + + int readerIndex = packet.readerIndex(); + int packetId = DefinedPacket.readVarInt( packet ); + int packetIdLength = packet.readerIndex() - readerIndex; + if ( packetId == 0x0C /* Spawn Player */ ) + { + DefinedPacket.readVarInt( packet ); + int idLength = packet.readerIndex() - readerIndex - packetIdLength; + String uuid = DefinedPacket.readString( packet ); + String username = DefinedPacket.readString( packet ); + int props = DefinedPacket.readVarInt( packet ); + if ( props == 0 ) + { + UserConnection player = (UserConnection) BungeeCord.getInstance().getPlayer( username ); + if ( player != null ) + { + LoginResult profile = player.getPendingConnection().getLoginProfile(); + if ( profile != null && profile.getProperties() != null + && profile.getProperties().length >= 1 ) + { + ByteBuf rest = packet.copy(); + packet.readerIndex( readerIndex ); + packet.writerIndex( readerIndex + packetIdLength + idLength ); + DefinedPacket.writeString( player.getUniqueId().toString(), packet ); + DefinedPacket.writeString( username, packet ); + DefinedPacket.writeVarInt( profile.getProperties().length, packet ); + for ( LoginResult.Property property : profile.getProperties() ) + { + DefinedPacket.writeString( property.getName(), packet ); + DefinedPacket.writeString( property.getValue(), packet ); + DefinedPacket.writeString( property.getSignature(), packet ); + } + packet.writeBytes( rest ); + rest.release(); + } + } + } + } + packet.readerIndex( readerIndex ); + } +} +// Travertine end diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java index c1272da3..45af7ea4 100644 --- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandler.java @@ -8,6 +8,7 @@ import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.Setter; +import net.md_5.bungee.BungeeCord; import net.md_5.bungee.UserConnection; import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.packet.EntityRemoveEffect; @@ -23,6 +24,12 @@ public class ForgeClientHandler @NonNull private final UserConnection con; + // Travertine start + @Getter + @Setter(AccessLevel.PACKAGE) + private boolean forgeOutdated = false; + // Travertine end + /** * The users' mod list. */ @@ -173,4 +180,22 @@ public class ForgeClientHandler { return fmlTokenInHandshake || clientModList != null; } + + // Travertine start + /** + * Checks to see if a user is using an outdated FML build, and takes + * appropriate action on the User side. This should only be called during a + * server connection, by the ServerConnector + * + * @return true if the user's FML build is outdated, otherwise + * false + */ + public boolean checkUserOutdated() { + if (forgeOutdated) { + con.disconnect( BungeeCord.getInstance().getTranslation("connect_kick_outdated_forge") ); + } + return forgeOutdated; + } + // Travertine end + } diff --git a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandshakeState.java b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandshakeState.java index 5e02f8c8..e3c1b9b9 100644 --- a/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandshakeState.java +++ b/proxy/src/main/java/net/md_5/bungee/forge/ForgeClientHandshakeState.java @@ -3,6 +3,7 @@ package net.md_5.bungee.forge; import java.util.Map; import net.md_5.bungee.ServerConnector; import net.md_5.bungee.UserConnection; +import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.packet.PluginMessage; /** @@ -84,6 +85,22 @@ enum ForgeClientHandshakeState implements IForgeClientPacketHandler clientModList = ForgeUtils.readModList( message ); con.getForgeClientHandler().setClientModList( clientModList ); + // Travertine start + // If the user is below 1.8, we need to check the version of FML - it's not always an OK version. + if ( ProtocolConstants.isBeforeOrEq( con.getPendingConnection().getVersion(), ProtocolConstants.MINECRAFT_1_7_6 ) ) + { + // Get the version from the mod list. + int buildNumber = ForgeUtils.getFmlBuildNumber( clientModList ); + + // If we get 0, we're probably using a testing build, so let it though. Otherwise, check the build number. + if ( buildNumber < ForgeConstants.FML_MIN_BUILD_VERSION && buildNumber != 0 ) + { + // Mark the user as an old Forge user. This will then cause any Forge ServerConnectors to cancel any + // connections to it. + con.getForgeClientHandler().setForgeOutdated( true ); + } + } + // Travertine end } return WAITINGSERVERDATA; diff --git a/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java b/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java index daf12f74..e33861ab 100644 --- a/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java +++ b/proxy/src/main/java/net/md_5/bungee/tab/ServerUnique.java @@ -4,12 +4,14 @@ import java.util.Collection; import java.util.HashSet; import java.util.UUID; import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.protocol.ProtocolConstants; import net.md_5.bungee.protocol.packet.PlayerListItem; public class ServerUnique extends TabList { private final Collection uuids = new HashSet<>(); + private final Collection usernames = new HashSet<>(); // Travertine - Support for <=1.7.9 public ServerUnique(ProxiedPlayer player) { @@ -23,10 +25,26 @@ public class ServerUnique extends TabList { if ( playerListItem.getAction() == PlayerListItem.Action.ADD_PLAYER ) { - uuids.add( item.getUuid() ); + // Travertine start + if ( item.getUuid() != null ) + { + uuids.add( item.getUuid() ); + } else + { + usernames.add( item.getUsername() ); + } + // Travertine end } else if ( playerListItem.getAction() == PlayerListItem.Action.REMOVE_PLAYER ) { - uuids.remove( item.getUuid() ); + // Travertine start + if ( item.getUuid() != null ) + { + uuids.remove( item.getUuid() ); + } else + { + usernames.remove( item.getUsername() ); + } + // Travertine end } } player.unsafe().sendPacket( playerListItem ); @@ -43,16 +61,44 @@ public class ServerUnique extends TabList { PlayerListItem packet = new PlayerListItem(); packet.setAction( PlayerListItem.Action.REMOVE_PLAYER ); - PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() ]; + PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() + usernames.size() ]; // Travertine int i = 0; for ( UUID uuid : uuids ) { PlayerListItem.Item item = items[i++] = new PlayerListItem.Item(); item.setUuid( uuid ); } + // Travertine start + for ( String username : usernames ) + { + PlayerListItem.Item item = items[i++] = new PlayerListItem.Item(); + item.setUsername( username ); + item.setDisplayName( username ); + } + // Travertine end packet.setItems( items ); - player.unsafe().sendPacket( packet ); + // Travertine start + if ( ProtocolConstants.isAfterOrEq( player.getPendingConnection().getVersion(), ProtocolConstants.MINECRAFT_1_8 ) ) + { + player.unsafe().sendPacket( packet ); + } else + { + // Split up the packet + for ( PlayerListItem.Item item : packet.getItems() ) + { + PlayerListItem p2 = new PlayerListItem(); + p2.setAction( packet.getAction() ); + + p2.setItems( new PlayerListItem.Item[] + { + item + } ); + player.unsafe().sendPacket( p2 ); + } + } + // Travertine end uuids.clear(); + usernames.clear(); // Travertine } @Override -- 2.24.1