From a3502173ac3d9da1cfe11f5a28c4bb796d22b55d 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..3f8c783 --- /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 read(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 write(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/Protocol.java b/protocol/src/main/java/net/md_5/bungee/protocol/Protocol.java 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 @@ -273,6 +273,8 @@ public enum Protocol private final TIntObjectMap> linkedProtocols = new TIntObjectHashMap<>(); { linkedProtocols.put( ProtocolConstants.MINECRAFT_1_8, Arrays.asList( + ProtocolConstants.MINECRAFT_1_7_2, + ProtocolConstants.MINECRAFT_1_7_6, ProtocolConstants.MINECRAFT_1_9 ) ); linkedProtocols.put( ProtocolConstants.MINECRAFT_1_9, Arrays.asList( @@ -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 " ); + } } 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/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 8ff6e3c..ad7e85f 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -154,6 +154,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 (Apple Git-66)