From 8ed5f195a6e2f3ee85e0f196850eda78187eec9a Mon Sep 17 00:00:00 2001 From: Tux Date: Wed, 4 Jan 2017 20:04:39 -0500 Subject: [PATCH] Revert "Corrected patches" This reverts commit c6cd0525452d0112c17385b359f09fbcbeba5fd7. --- .../0001-POM-Changes.patch | 8 +- .../0004-Fixup-ProtocolConstants.patch | 12 +- .../0005-1.7.x-Protocol-Patch.patch | 1743 ++++++++++++++++- 3 files changed, 1747 insertions(+), 16 deletions(-) diff --git a/Waterfall-Proxy-Patches/0001-POM-Changes.patch b/Waterfall-Proxy-Patches/0001-POM-Changes.patch index 04ca861..9fb3408 100644 --- a/Waterfall-Proxy-Patches/0001-POM-Changes.patch +++ b/Waterfall-Proxy-Patches/0001-POM-Changes.patch @@ -1,4 +1,4 @@ -From 71be2c37afc455ff3deb042af7fb70e4dff7b50f Mon Sep 17 00:00:00 2001 +From 5a8caa35c270d39bab6cddba4a7bffa3255f628f Mon Sep 17 00:00:00 2001 From: Troy Frew Date: Tue, 15 Nov 2016 08:56:43 -0500 Subject: [PATCH] POM Changes @@ -499,7 +499,7 @@ index 3421be0..c79809c 100644 compile diff --git a/proxy/pom.xml b/proxy/pom.xml -index 180b78d..7fc7658 100644 +index 1220a41..b38e7bf 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -5,17 +5,17 @@ @@ -523,7 +523,7 @@ index 180b78d..7fc7658 100644 Proxy component of the Elastic Portal Suite -@@ -54,31 +54,31 @@ +@@ -40,31 +40,31 @@ io.github.waterfallmc @@ -597,5 +597,5 @@ index 349d5cc..a49d315 100644 compile -- -2.7.4 +2.7.4 (Apple Git-66) diff --git a/Waterfall-Proxy-Patches/0004-Fixup-ProtocolConstants.patch b/Waterfall-Proxy-Patches/0004-Fixup-ProtocolConstants.patch index 1fe45b8..125d467 100644 --- a/Waterfall-Proxy-Patches/0004-Fixup-ProtocolConstants.patch +++ b/Waterfall-Proxy-Patches/0004-Fixup-ProtocolConstants.patch @@ -1,14 +1,14 @@ -From 40e9be14af583bb8b5224c4b8753460ad9735673 Mon Sep 17 00:00:00 2001 +From d623e55c58449f3483f57b28681b1a831a5fe8b7 Mon Sep 17 00:00:00 2001 From: Troy Frew Date: Tue, 15 Nov 2016 09:07:51 -0500 Subject: [PATCH] Fixup ProtocolConstants 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 9929ef4..af80c95 100644 +index f3c13bf..637262d 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 -@@ -20,7 +20,8 @@ public class ProtocolConstants +@@ -19,7 +19,8 @@ public class ProtocolConstants "1.10.x", "1.11.x" ); @@ -18,8 +18,8 @@ index 9929ef4..af80c95 100644 ProtocolConstants.MINECRAFT_1_9, ProtocolConstants.MINECRAFT_1_9_1, ProtocolConstants.MINECRAFT_1_9_2, -@@ -30,6 +31,16 @@ public class ProtocolConstants - ProtocolConstants.MINECRAFT_1_11_1 +@@ -28,6 +29,16 @@ public class ProtocolConstants + ProtocolConstants.MINECRAFT_1_11 ); + public static final boolean isBeforeOrEq(int before, int other) @@ -36,5 +36,5 @@ index 9929ef4..af80c95 100644 { -- -2.7.4 +2.7.4 (Apple Git-66) diff --git a/Waterfall-Proxy-Patches/0005-1.7.x-Protocol-Patch.patch b/Waterfall-Proxy-Patches/0005-1.7.x-Protocol-Patch.patch index fefe3ed..fae1c19 100644 --- a/Waterfall-Proxy-Patches/0005-1.7.x-Protocol-Patch.patch +++ b/Waterfall-Proxy-Patches/0005-1.7.x-Protocol-Patch.patch @@ -1,14 +1,177 @@ -From b7a9aef9f7b615eb356879eb367e42baf9426a20 Mon Sep 17 00:00:00 2001 +From 8fdb71b40367d2cc2d40672ba113cd2b1300753d 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 0000000..60bf2e0 +--- /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; ++ } ++} +\ No newline at end of file +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 10e16d7..04a3403 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 +@@ -193,6 +193,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" ); +@@ -203,6 +208,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 17d8444..172e387 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 + { +@@ -43,7 +44,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 d4b0384..9aac7ca 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 2aa6885..2ff8a6a 100644 +index 741166d..4eebd12 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 -@@ -274,6 +274,8 @@ public enum Protocol +@@ -273,6 +273,8 @@ public enum Protocol private final TIntObjectMap> linkedProtocols = new TIntObjectHashMap<>(); { linkedProtocols.put( ProtocolConstants.MINECRAFT_1_8, Arrays.asList( @@ -17,16 +180,1584 @@ index 2aa6885..2ff8a6a 100644 ProtocolConstants.MINECRAFT_1_9 ) ); linkedProtocols.put( ProtocolConstants.MINECRAFT_1_9, Arrays.asList( -@@ -312,6 +314,9 @@ public enum Protocol +@@ -310,7 +312,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 " ); + } - throw new BadPacketException( "Packet with id " + id + " outside of range " ); } + Constructor constructor = protocolData.packetConstructors.get( id ); +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 637262d..e41c9fa 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; +@@ -14,12 +16,15 @@ public class ProtocolConstants + public static final int MINECRAFT_1_10 = 210; + public static final int MINECRAFT_1_11 = 315; + public static final List SUPPORTED_VERSIONS = Arrays.asList( ++ "1.7.x", + "1.8.x", + "1.9.x", + "1.10.x", + "1.11.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 6da27fc..65506c2 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 +@@ -7,10 +7,12 @@ 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 +@@ -33,7 +35,15 @@ public class Varint21FrameDecoder extends ByteToMessageDecoder + int length = DefinedPacket.readVarInt( Unpooled.wrappedBuffer( buf ) ); + if ( length == 0 ) + { +- 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 95ad39b..1f78125 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,6 +1,6 @@ + package net.md_5.bungee.protocol.packet; + +-import net.md_5.bungee.protocol.DefinedPacket; ++import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; + import io.netty.buffer.ByteBuf; + import lombok.AllArgsConstructor; + import lombok.Data; +@@ -13,7 +13,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 +24,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) + { +@@ -34,6 +42,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 5c79727..431b2eb 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,6 @@ + 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; +@@ -13,7 +14,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 +25,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 +72,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 a29524c..8d9f4cc 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 06676e4..19a8549 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,6 +1,6 @@ + package net.md_5.bungee.protocol.packet; + +-import net.md_5.bungee.protocol.DefinedPacket; ++import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; + import io.netty.buffer.ByteBuf; + import lombok.AllArgsConstructor; + import lombok.Data; +@@ -13,12 +13,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 +35,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 d11a9ea..07fc21b 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; +@@ -21,6 +22,14 @@ public class EntityEffect extends DefinedPacket { + 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); + this.effectId = buf.readUnsignedByte(); +@@ -30,6 +39,14 @@ public class EntityEffect extends DefinedPacket { + } + + @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); + buf.writeByte(this.effectId); +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 7ed2dc3..776cc14 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; +@@ -24,8 +24,20 @@ public class EntityRemoveEffect extends DefinedPacket { + } + + @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); ++ } ++ ++ @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 0960b7d..253a3ec 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,6 +1,6 @@ + package net.md_5.bungee.protocol.packet; + +-import net.md_5.bungee.protocol.DefinedPacket; ++import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; + import io.netty.buffer.ByteBuf; + import lombok.AllArgsConstructor; + import lombok.Data; +@@ -13,17 +13,33 @@ import net.md_5.bungee.protocol.ProtocolConstants; + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(callSuper = false) +-public class KeepAlive extends DefinedPacket ++public class KeepAlive extends MultiVersionPacketV17 + { + + private int 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 = readVarInt( buf ); + } + ++ // Travertine start ++ @Override ++ public void v17Write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) ++ { ++ buf.writeInt( 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 9983ef2..ae5dad5 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,6 @@ + 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.Data; +@@ -13,12 +14,24 @@ import java.util.UUID; + @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) + { +@@ -73,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 e67773d..97cef3c 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 +@@ -2,8 +2,8 @@ package net.md_5.bungee.protocol.packet; + + 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 net.md_5.bungee.protocol.DefinedPacket; + import io.netty.buffer.ByteBuf; + import java.io.ByteArrayInputStream; + import java.io.DataInput; +@@ -19,7 +19,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 Predicate SHOULD_RELAY = new Predicate() +@@ -52,6 +52,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) + { +@@ -62,6 +71,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 ef9b8cf..43af318 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,6 +1,6 @@ + package net.md_5.bungee.protocol.packet; + +-import net.md_5.bungee.protocol.DefinedPacket; ++import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; + import io.netty.buffer.ByteBuf; + import lombok.AllArgsConstructor; + import lombok.Data; +@@ -13,7 +13,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; +@@ -24,6 +24,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) + { +@@ -36,6 +46,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 6f0de53..b967f89 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,6 +1,6 @@ + package net.md_5.bungee.protocol.packet; + +-import net.md_5.bungee.protocol.DefinedPacket; ++import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; + import io.netty.buffer.ByteBuf; + import lombok.AllArgsConstructor; + import lombok.Data; +@@ -13,7 +13,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 +24,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 +50,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 e3bcbc3..7634ebf 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,6 +1,6 @@ + package net.md_5.bungee.protocol.packet; + +-import net.md_5.bungee.protocol.DefinedPacket; ++import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; + import io.netty.buffer.ByteBuf; + import lombok.AllArgsConstructor; + import lombok.Data; +@@ -13,7 +13,7 @@ import net.md_5.bungee.protocol.ProtocolConstants; + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(callSuper = false) +-public class TabCompleteRequest extends DefinedPacket ++public class TabCompleteRequest extends MultiVersionPacketV17 + { + + private String cursor; +@@ -21,6 +21,14 @@ public class TabCompleteRequest extends DefinedPacket + private boolean hasPositon; + private long 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) + { +@@ -36,6 +44,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 b470579..da1066c 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,6 +1,6 @@ + package net.md_5.bungee.protocol.packet; + +-import net.md_5.bungee.protocol.DefinedPacket; ++import io.github.waterfallmc.travertine.protocol.MultiVersionPacketV17; + import io.netty.buffer.ByteBuf; + import lombok.AllArgsConstructor; + import lombok.Data; +@@ -13,7 +13,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 +39,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) + { +@@ -68,6 +93,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 014ea5f..d4d0212 100644 +--- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java ++++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +@@ -153,6 +153,14 @@ public class BungeeCord extends ProxyServer + .registerTypeAdapter( TranslatableComponent.class, new TranslatableComponentSerializer() ) + .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 494213d..1d89acf 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 491cf1a..299a216 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= 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 +\ No newline at end of file +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 17e250d..bcc6a4f 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 +@@ -7,6 +7,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; +@@ -22,6 +23,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. + */ +@@ -171,4 +178,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 5242926..6d7747b 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/Global.java b/proxy/src/main/java/net/md_5/bungee/tab/Global.java +index 0cf1d21..958bb06 100644 +--- a/proxy/src/main/java/net/md_5/bungee/tab/Global.java ++++ b/proxy/src/main/java/net/md_5/bungee/tab/Global.java +@@ -6,6 +6,7 @@ import net.md_5.bungee.api.chat.TextComponent; + import net.md_5.bungee.api.connection.ProxiedPlayer; + import net.md_5.bungee.chat.ComponentSerializer; + import net.md_5.bungee.connection.LoginResult; ++import net.md_5.bungee.protocol.ProtocolConstants; + import net.md_5.bungee.protocol.packet.PlayerListItem; + + import java.util.Collection; +@@ -89,7 +90,26 @@ public class Global extends TabList + item.setGamemode( ( (UserConnection) p ).getGamemode() ); + item.setPing( p.getPing() ); + } +- player.unsafe().sendPacket( playerListItem ); ++ // Travertine start ++ if ( ProtocolConstants.isAfterOrEq( player.getPendingConnection().getVersion(), ProtocolConstants.MINECRAFT_1_8 ) ) ++ { ++ player.unsafe().sendPacket( playerListItem ); ++ } else ++ { ++ // Split up the packet ++ for ( PlayerListItem.Item item : playerListItem.getItems() ) ++ { ++ PlayerListItem packet = new PlayerListItem(); ++ packet.setAction( playerListItem.getAction() ); ++ ++ packet.setItems( new PlayerListItem.Item[] ++ { ++ item ++ } ); ++ player.unsafe().sendPacket( packet ); ++ } ++ } ++ // Travertine end + PlayerListItem packet = new PlayerListItem(); + packet.setAction( PlayerListItem.Action.ADD_PLAYER ); + PlayerListItem.Item item = new PlayerListItem.Item(); +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 daf12f7..e33861a 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.7.4 +2.7.4 (Apple Git-66)