From 5467e3a8424fdc4b72a26fc35d9a0432333fa4b2 Mon Sep 17 00:00:00 2001 From: md_5 Date: Thu, 8 Dec 2022 03:00:00 +1100 Subject: [PATCH] Minecraft 1.19.3 support --- chat/pom.xml | 2 +- config/pom.xml | 2 +- pom.xml | 2 +- .../protocol/AbstractPacketHandler.java | 10 ++ .../md_5/bungee/protocol/DefinedPacket.java | 50 +++++++ .../net/md_5/bungee/protocol/Protocol.java | 90 ++++++++---- .../bungee/protocol/ProtocolConstants.java | 4 +- .../md_5/bungee/protocol/SeenMessages.java | 39 +++++ .../bungee/protocol/packet/ClientChat.java | 48 ++++++- .../bungee/protocol/packet/ClientCommand.java | 44 +++++- .../md_5/bungee/protocol/packet/Commands.java | 127 ++++++++++++++++- .../protocol/packet/EncryptionResponse.java | 4 +- .../bungee/protocol/packet/LoginRequest.java | 4 +- .../protocol/packet/PlayerListItem.java | 19 ++- .../protocol/packet/PlayerListItemRemove.java | 45 ++++++ .../protocol/packet/PlayerListItemUpdate.java | 133 ++++++++++++++++++ .../bungee/protocol/packet/ServerData.java | 10 +- .../bungee/connection/DownstreamBridge.java | 16 +++ .../bungee/connection/InitialHandler.java | 4 +- .../bungee/connection/UpstreamBridge.java | 23 ++- .../net/md_5/bungee/entitymap/EntityMap.java | 1 + .../net/md_5/bungee/tab/ServerUnique.java | 56 ++++++-- .../java/net/md_5/bungee/tab/TabList.java | 69 +++++++-- 23 files changed, 712 insertions(+), 90 deletions(-) create mode 100644 protocol/src/main/java/net/md_5/bungee/protocol/SeenMessages.java create mode 100644 protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemRemove.java create mode 100644 protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java diff --git a/chat/pom.xml b/chat/pom.xml index 4efc70d2..f695c462 100644 --- a/chat/pom.xml +++ b/chat/pom.xml @@ -22,7 +22,7 @@ com.google.code.gson gson - 2.8.9 + 2.10 compile diff --git a/config/pom.xml b/config/pom.xml index a51b1038..807223ec 100644 --- a/config/pom.xml +++ b/config/pom.xml @@ -22,7 +22,7 @@ com.google.code.gson gson - 2.8.9 + 2.10 compile true diff --git a/pom.xml b/pom.xml index 4c3b8e55..7005df5d 100644 --- a/pom.xml +++ b/pom.xml @@ -89,7 +89,7 @@ com.google.guava guava - 31.0.1-jre + 31.1-jre compile diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java b/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java index 608769eb..88865b85 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/AbstractPacketHandler.java @@ -25,6 +25,8 @@ import net.md_5.bungee.protocol.packet.LoginSuccess; import net.md_5.bungee.protocol.packet.PingPacket; import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; import net.md_5.bungee.protocol.packet.PlayerListItem; +import net.md_5.bungee.protocol.packet.PlayerListItemRemove; +import net.md_5.bungee.protocol.packet.PlayerListItemUpdate; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.Respawn; import net.md_5.bungee.protocol.packet.ScoreboardDisplay; @@ -114,6 +116,14 @@ public abstract class AbstractPacketHandler { } + public void handle(PlayerListItemRemove playerListItem) throws Exception + { + } + + public void handle(PlayerListItemUpdate playerListItem) throws Exception + { + } + public void handle(PlayerListHeaderFooter playerListHeaderFooter) throws Exception { } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java b/protocol/src/main/java/net/md_5/bungee/protocol/DefinedPacket.java index 5fe55dcc..111802f7 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 @@ -9,6 +9,9 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; +import java.util.BitSet; +import java.util.EnumSet; import java.util.List; import java.util.UUID; import lombok.RequiredArgsConstructor; @@ -308,6 +311,53 @@ public abstract class DefinedPacket } } + public static > void writeEnumSet(EnumSet enumset, Class oclass, ByteBuf buf) + { + E[] enums = oclass.getEnumConstants(); + BitSet bits = new BitSet( enums.length ); + + for ( int i = 0; i < enums.length; ++i ) + { + bits.set( i, enumset.contains( enums[i] ) ); + } + + writeFixedBitSet( bits, enums.length, buf ); + } + + public static > EnumSet readEnumSet(Class oclass, ByteBuf buf) + { + E[] enums = oclass.getEnumConstants(); + BitSet bits = readFixedBitSet( enums.length, buf ); + EnumSet set = EnumSet.noneOf( oclass ); + + for ( int i = 0; i < enums.length; ++i ) + { + if ( bits.get( i ) ) + { + set.add( enums[i] ); + } + } + + return set; + } + + public static BitSet readFixedBitSet(int i, ByteBuf buf) + { + byte[] bits = new byte[ ( i + 8 ) >> 3 ]; + buf.readBytes( bits ); + + return BitSet.valueOf( bits ); + } + + public static void writeFixedBitSet(BitSet bits, int size, ByteBuf buf) + { + if ( bits.length() > size ) + { + throw new OverflowPacketException( "BitSet too large (expected " + size + " got " + bits.size() + ")" ); + } + buf.writeBytes( Arrays.copyOf( bits.toByteArray(), ( size + 8 ) >> 3 ) ); + } + public void read(ByteBuf buf) { throw new UnsupportedOperationException( "Packet must implement read method" ); 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 aa22f134..f746c4ff 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 @@ -31,6 +31,8 @@ import net.md_5.bungee.protocol.packet.LoginSuccess; import net.md_5.bungee.protocol.packet.PingPacket; import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter; import net.md_5.bungee.protocol.packet.PlayerListItem; +import net.md_5.bungee.protocol.packet.PlayerListItemRemove; +import net.md_5.bungee.protocol.packet.PlayerListItemUpdate; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.Respawn; import net.md_5.bungee.protocol.packet.ScoreboardDisplay; @@ -81,7 +83,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x1F ), map( ProtocolConstants.MINECRAFT_1_17, 0x21 ), map( ProtocolConstants.MINECRAFT_1_19, 0x1E ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x20 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x20 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x1F ) ); TO_CLIENT.registerPacket( Login.class, @@ -94,7 +97,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x24 ), map( ProtocolConstants.MINECRAFT_1_17, 0x26 ), map( ProtocolConstants.MINECRAFT_1_19, 0x23 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x25 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x25 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x24 ) ); TO_CLIENT.registerPacket( Chat.class, Chat::new, @@ -120,7 +124,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x39 ), map( ProtocolConstants.MINECRAFT_1_17, 0x3D ), map( ProtocolConstants.MINECRAFT_1_19, 0x3B ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x3E ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x3E ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x3D ) ); TO_CLIENT.registerPacket( BossBar.class, @@ -144,7 +149,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x32 ), map( ProtocolConstants.MINECRAFT_1_17, 0x36 ), map( ProtocolConstants.MINECRAFT_1_19, 0x34 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x37 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x37 ), + map( ProtocolConstants.MINECRAFT_1_19_3, -1 ) ); TO_CLIENT.registerPacket( TabCompleteResponse.class, @@ -156,7 +162,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16, 0x10 ), map( ProtocolConstants.MINECRAFT_1_16_2, 0x0F ), map( ProtocolConstants.MINECRAFT_1_17, 0x11 ), - map( ProtocolConstants.MINECRAFT_1_19, 0x0E ) + map( ProtocolConstants.MINECRAFT_1_19, 0x0E ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x0D ) ); TO_CLIENT.registerPacket( ScoreboardObjective.class, @@ -169,7 +176,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_14, 0x49 ), map( ProtocolConstants.MINECRAFT_1_15, 0x4A ), map( ProtocolConstants.MINECRAFT_1_17, 0x53 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x56 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x56 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x54 ) ); TO_CLIENT.registerPacket( ScoreboardScore.class, @@ -182,7 +190,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_14, 0x4C ), map( ProtocolConstants.MINECRAFT_1_15, 0x4D ), map( ProtocolConstants.MINECRAFT_1_17, 0x56 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x59 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x59 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x57 ) ); TO_CLIENT.registerPacket( ScoreboardDisplay.class, @@ -195,7 +204,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_14, 0x42 ), map( ProtocolConstants.MINECRAFT_1_15, 0x43 ), map( ProtocolConstants.MINECRAFT_1_17, 0x4C ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x4F ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x4F ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x4D ) ); TO_CLIENT.registerPacket( Team.class, @@ -208,7 +218,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_14, 0x4B ), map( ProtocolConstants.MINECRAFT_1_15, 0x4C ), map( ProtocolConstants.MINECRAFT_1_17, 0x55 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x58 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x58 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x56 ) ); TO_CLIENT.registerPacket( PluginMessage.class, @@ -222,7 +233,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x17 ), map( ProtocolConstants.MINECRAFT_1_17, 0x18 ), map( ProtocolConstants.MINECRAFT_1_19, 0x15 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x16 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x16 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x15 ) ); TO_CLIENT.registerPacket( Kick.class, @@ -236,7 +248,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x19 ), map( ProtocolConstants.MINECRAFT_1_17, 0x1A ), map( ProtocolConstants.MINECRAFT_1_19, 0x17 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x19 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x19 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x17 ) ); TO_CLIENT.registerPacket( Title.class, @@ -250,33 +263,38 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16, 0x4F ), map( ProtocolConstants.MINECRAFT_1_17, 0x59 ), map( ProtocolConstants.MINECRAFT_1_18, 0x5A ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x5D ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x5D ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x5B ) ); TO_CLIENT.registerPacket( ClearTitles.class, ClearTitles::new, map( ProtocolConstants.MINECRAFT_1_17, 0x10 ), - map( ProtocolConstants.MINECRAFT_1_19, 0x0D ) + map( ProtocolConstants.MINECRAFT_1_19, 0x0D ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ) ); TO_CLIENT.registerPacket( Subtitle.class, Subtitle::new, map( ProtocolConstants.MINECRAFT_1_17, 0x57 ), map( ProtocolConstants.MINECRAFT_1_18, 0x58 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x5B ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x59 ) ); TO_CLIENT.registerPacket( TitleTimes.class, TitleTimes::new, map( ProtocolConstants.MINECRAFT_1_17, 0x5A ), map( ProtocolConstants.MINECRAFT_1_18, 0x5B ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x5E ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x5C ) ); TO_CLIENT.registerPacket( SystemChat.class, SystemChat::new, map( ProtocolConstants.MINECRAFT_1_19, 0x5F ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x62 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x62 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x60 ) ); TO_CLIENT.registerPacket( PlayerListHeaderFooter.class, @@ -293,7 +311,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_17, 0x5E ), map( ProtocolConstants.MINECRAFT_1_18, 0x5F ), map( ProtocolConstants.MINECRAFT_1_19, 0x60 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x63 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x63 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x61 ) ); TO_CLIENT.registerPacket( EntityStatus.class, @@ -307,7 +326,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x1A ), map( ProtocolConstants.MINECRAFT_1_17, 0x1B ), map( ProtocolConstants.MINECRAFT_1_19, 0x18 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x1A ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x1A ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x19 ) ); TO_CLIENT.registerPacket( Commands.class, @@ -317,7 +337,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16, 0x11 ), map( ProtocolConstants.MINECRAFT_1_16_2, 0x10 ), map( ProtocolConstants.MINECRAFT_1_17, 0x12 ), - map( ProtocolConstants.MINECRAFT_1_19, 0x0F ) + map( ProtocolConstants.MINECRAFT_1_19, 0x0F ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x0E ) ); TO_CLIENT.registerPacket( GameState.class, @@ -327,7 +348,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16_2, 0x1D ), map( ProtocolConstants.MINECRAFT_1_17, 0x1E ), map( ProtocolConstants.MINECRAFT_1_19, 0x1B ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x1D ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x1D ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x1C ) ); TO_CLIENT.registerPacket( ViewDistance.class, @@ -337,13 +359,25 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16, 0x41 ), map( ProtocolConstants.MINECRAFT_1_17, 0x4A ), map( ProtocolConstants.MINECRAFT_1_19, 0x49 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x4C ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x4C ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x4B ) ); TO_CLIENT.registerPacket( ServerData.class, ServerData::new, map( ProtocolConstants.MINECRAFT_1_19, 0x3F ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x42 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x42 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x41 ) + ); + TO_CLIENT.registerPacket( + PlayerListItemRemove.class, + PlayerListItemRemove::new, + map( ProtocolConstants.MINECRAFT_1_19_3, 0x35 ) + ); + TO_CLIENT.registerPacket( + PlayerListItemUpdate.class, + PlayerListItemUpdate::new, + map( ProtocolConstants.MINECRAFT_1_19_3, 0x36 ) ); TO_SERVER.registerPacket( @@ -358,7 +392,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16, 0x10 ), map( ProtocolConstants.MINECRAFT_1_17, 0x0F ), map( ProtocolConstants.MINECRAFT_1_19, 0x11 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x12 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x12 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x11 ) ); TO_SERVER.registerPacket( Chat.class, Chat::new, @@ -391,7 +426,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_13, 0x05 ), map( ProtocolConstants.MINECRAFT_1_14, 0x06 ), map( ProtocolConstants.MINECRAFT_1_19, 0x08 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x09 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x09 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x08 ) ); TO_SERVER.registerPacket( ClientSettings.class, @@ -402,7 +438,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_12_1, 0x04 ), map( ProtocolConstants.MINECRAFT_1_14, 0x05 ), map( ProtocolConstants.MINECRAFT_1_19, 0x07 ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x08 ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x08 ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x07 ) ); TO_SERVER.registerPacket( PluginMessage.class, @@ -415,7 +452,8 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_14, 0x0B ), map( ProtocolConstants.MINECRAFT_1_17, 0x0A ), map( ProtocolConstants.MINECRAFT_1_19, 0x0C ), - map( ProtocolConstants.MINECRAFT_1_19_1, 0x0D ) + map( ProtocolConstants.MINECRAFT_1_19_1, 0x0D ), + map( ProtocolConstants.MINECRAFT_1_19_3, 0x0C ) ); } }, 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 0471b9a5..17d741d8 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 @@ -40,6 +40,7 @@ public class ProtocolConstants public static final int MINECRAFT_1_18_2 = 758; public static final int MINECRAFT_1_19 = 759; public static final int MINECRAFT_1_19_1 = 760; + public static final int MINECRAFT_1_19_3 = 761; public static final List SUPPORTED_VERSIONS; public static final List SUPPORTED_VERSION_IDS; @@ -92,7 +93,8 @@ public class ProtocolConstants ProtocolConstants.MINECRAFT_1_18, ProtocolConstants.MINECRAFT_1_18_2, ProtocolConstants.MINECRAFT_1_19, - ProtocolConstants.MINECRAFT_1_19_1 + ProtocolConstants.MINECRAFT_1_19_1, + ProtocolConstants.MINECRAFT_1_19_3 ); if ( SNAPSHOT_SUPPORT ) diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/SeenMessages.java b/protocol/src/main/java/net/md_5/bungee/protocol/SeenMessages.java new file mode 100644 index 00000000..9f0b452a --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/SeenMessages.java @@ -0,0 +1,39 @@ +package net.md_5.bungee.protocol; + +import io.netty.buffer.ByteBuf; +import java.util.BitSet; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class SeenMessages extends DefinedPacket +{ + + private int offset; + private BitSet acknowledged; + + @Override + public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + offset = DefinedPacket.readVarInt( buf ); + acknowledged = DefinedPacket.readFixedBitSet( 20, buf ); + } + + @Override + public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + DefinedPacket.writeVarInt( offset, buf ); + DefinedPacket.writeFixedBitSet( acknowledged, 20, buf ); + } + + @Override + public void handle(AbstractPacketHandler handler) throws Exception + { + throw new UnsupportedOperationException( "Not supported." ); + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientChat.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientChat.java index 59e4daf1..105c8276 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientChat.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientChat.java @@ -9,6 +9,7 @@ import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.ChatChain; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.ProtocolConstants; +import net.md_5.bungee.protocol.SeenMessages; @Data @NoArgsConstructor @@ -23,6 +24,7 @@ public class ClientChat extends DefinedPacket private byte[] signature; private boolean signedPreview; private ChatChain chain; + private SeenMessages seenMessages; @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) @@ -30,9 +32,27 @@ public class ClientChat extends DefinedPacket message = readString( buf, 256 ); timestamp = buf.readLong(); salt = buf.readLong(); - signature = readArray( buf ); - signedPreview = buf.readBoolean(); - if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) + + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + if ( buf.readBoolean() ) + { + signature = new byte[ 256 ]; + buf.readBytes( signature ); + } + } else + { + signature = readArray( buf ); + } + if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) + { + signedPreview = buf.readBoolean(); + } + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + seenMessages = new SeenMessages(); + seenMessages.read( buf, direction, protocolVersion ); + } else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) { chain = new ChatChain(); chain.read( buf, direction, protocolVersion ); @@ -45,9 +65,25 @@ public class ClientChat extends DefinedPacket writeString( message, buf ); buf.writeLong( timestamp ); buf.writeLong( salt ); - writeArray( signature, buf ); - buf.writeBoolean( signedPreview ); - if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + buf.writeBoolean( signature != null ); + if ( signature != null ) + { + buf.writeBytes( signature ); + } + } else + { + writeArray( signature, buf ); + } + if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) + { + buf.writeBoolean( signedPreview ); + } + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + seenMessages.write( buf, direction, protocolVersion ); + } else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) { chain.write( buf, direction, protocolVersion ); } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientCommand.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientCommand.java index 72b09985..9b7435fb 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientCommand.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ClientCommand.java @@ -12,6 +12,7 @@ import net.md_5.bungee.protocol.AbstractPacketHandler; import net.md_5.bungee.protocol.ChatChain; import net.md_5.bungee.protocol.DefinedPacket; import net.md_5.bungee.protocol.ProtocolConstants; +import net.md_5.bungee.protocol.SeenMessages; @Data @NoArgsConstructor @@ -26,6 +27,7 @@ public class ClientCommand extends DefinedPacket private Map signatures; private boolean signedPreview; private ChatChain chain; + private SeenMessages seenMessages; @Override public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) @@ -39,11 +41,29 @@ public class ClientCommand extends DefinedPacket signatures = new HashMap<>( cnt ); for ( int i = 0; i < cnt; i++ ) { - signatures.put( readString( buf, 16 ), readArray( buf ) ); + String name = readString( buf, 16 ); + byte[] signature; + + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + signature = new byte[ 256 ]; + buf.readBytes( signature ); + } else + { + signature = readArray( buf ); + } + signatures.put( name, signature ); } - signedPreview = buf.readBoolean(); - if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) + if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) + { + signedPreview = buf.readBoolean(); + } + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + seenMessages = new SeenMessages(); + seenMessages.read( buf, direction, protocolVersion ); + } else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) { chain = new ChatChain(); chain.read( buf, direction, protocolVersion ); @@ -61,11 +81,23 @@ public class ClientCommand extends DefinedPacket for ( Map.Entry entry : signatures.entrySet() ) { writeString( entry.getKey(), buf ); - writeArray( entry.getValue(), buf ); + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + buf.writeBytes( entry.getValue() ); + } else + { + writeArray( entry.getValue(), buf ); + } } - buf.writeBoolean( signedPreview ); - if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) + if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) + { + buf.writeBoolean( signedPreview ); + } + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + seenMessages.write( buf, direction, protocolVersion ); + } else if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) { chain.write( buf, direction, protocolVersion ); } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Commands.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Commands.java index 0eb3661b..80a16f65 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/Commands.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/Commands.java @@ -23,13 +23,11 @@ import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.RootCommandNode; import io.netty.buffer.ByteBuf; import java.util.ArrayDeque; -import java.util.ArrayList; import java.util.Collection; import java.util.Deque; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import lombok.AllArgsConstructor; @@ -309,7 +307,8 @@ public class Commands extends DefinedPacket { private static final Map PROVIDERS = new HashMap<>(); - private static final List PROVIDER_LIST = new ArrayList<>(); + private static final ArgumentSerializer[] IDS_1_19; + private static final ArgumentSerializer[] IDS_1_19_3; private static final Map, ProperArgumentSerializer> PROPER_PROVIDERS = new HashMap<>(); // private static final ArgumentSerializer VOID = new ArgumentSerializer() @@ -575,13 +574,124 @@ public class Commands extends DefinedPacket register( "minecraft:template_rotation", VOID ); // 1.19 register( "minecraft:uuid", VOID ); // 1.16 + register( "minecraft:gamemode", VOID ); // 1.19.3 + register( "minecraft:resource_or_tag_key", RAW_STRING ); // 1.19.3 + register( "minecraft:resource_key", RAW_STRING ); // 1.19.3 + register( "minecraft:nbt", VOID ); // 1.13 // removed + IDS_1_19 = new ArgumentSerializer[] + { + get( "brigadier:bool" ), + get( "brigadier:float" ), + get( "brigadier:double" ), + get( "brigadier:integer" ), + get( "brigadier:long" ), + get( "brigadier:string" ), + get( "minecraft:entity" ), + get( "minecraft:game_profile" ), + get( "minecraft:block_pos" ), + get( "minecraft:column_pos" ), + get( "minecraft:vec3" ), + get( "minecraft:vec2" ), + get( "minecraft:block_state" ), + get( "minecraft:block_predicate" ), + get( "minecraft:item_stack" ), + get( "minecraft:item_predicate" ), + get( "minecraft:color" ), + get( "minecraft:component" ), + get( "minecraft:message" ), + get( "minecraft:nbt_compound_tag" ), + get( "minecraft:nbt_tag" ), + get( "minecraft:nbt_path" ), + get( "minecraft:objective" ), + get( "minecraft:objective_criteria" ), + get( "minecraft:operation" ), + get( "minecraft:particle" ), + get( "minecraft:angle" ), + get( "minecraft:rotation" ), + get( "minecraft:scoreboard_slot" ), + get( "minecraft:score_holder" ), + get( "minecraft:swizzle" ), + get( "minecraft:team" ), + get( "minecraft:item_slot" ), + get( "minecraft:resource_location" ), + get( "minecraft:mob_effect" ), + get( "minecraft:function" ), + get( "minecraft:entity_anchor" ), + get( "minecraft:int_range" ), + get( "minecraft:float_range" ), + get( "minecraft:item_enchantment" ), + get( "minecraft:entity_summon" ), + get( "minecraft:dimension" ), + get( "minecraft:time" ), + get( "minecraft:resource_or_tag" ), + get( "minecraft:resource" ), + get( "minecraft:template_mirror" ), + get( "minecraft:template_rotation" ), + get( "minecraft:uuid" ) + }; + + IDS_1_19_3 = new ArgumentSerializer[] + { + get( "brigadier:bool" ), + get( "brigadier:float" ), + get( "brigadier:double" ), + get( "brigadier:integer" ), + get( "brigadier:long" ), + get( "brigadier:string" ), + get( "minecraft:entity" ), + get( "minecraft:game_profile" ), + get( "minecraft:block_pos" ), + get( "minecraft:column_pos" ), + get( "minecraft:vec3" ), + get( "minecraft:vec2" ), + get( "minecraft:block_state" ), + get( "minecraft:block_predicate" ), + get( "minecraft:item_stack" ), + get( "minecraft:item_predicate" ), + get( "minecraft:color" ), + get( "minecraft:component" ), + get( "minecraft:message" ), + get( "minecraft:nbt_compound_tag" ), + get( "minecraft:nbt_tag" ), + get( "minecraft:nbt_path" ), + get( "minecraft:objective" ), + get( "minecraft:objective_criteria" ), + get( "minecraft:operation" ), + get( "minecraft:particle" ), + get( "minecraft:angle" ), + get( "minecraft:rotation" ), + get( "minecraft:scoreboard_slot" ), + get( "minecraft:score_holder" ), + get( "minecraft:swizzle" ), + get( "minecraft:team" ), + get( "minecraft:item_slot" ), + get( "minecraft:resource_location" ), + get( "minecraft:function" ), + get( "minecraft:entity_anchor" ), + get( "minecraft:int_range" ), + get( "minecraft:float_range" ), + get( "minecraft:dimension" ), + get( "minecraft:gamemode" ), + get( "minecraft:time" ), + get( "minecraft:resource_or_tag" ), + get( "minecraft:resource_or_tag_key" ), + get( "minecraft:resource" ), + get( "minecraft:resource_key" ), + get( "minecraft:template_mirror" ), + get( "minecraft:template_rotation" ), + get( "minecraft:uuid" ) + }; } private static void register(String name, ArgumentSerializer serializer) { PROVIDERS.put( name, serializer ); - PROVIDER_LIST.add( serializer ); + } + + private static ArgumentSerializer get(String name) + { + return PROVIDERS.get( name ); } private static ArgumentType read(ByteBuf buf, int protocolVersion) @@ -592,7 +702,14 @@ public class Commands extends DefinedPacket if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) { key = readVarInt( buf ); - reader = PROVIDER_LIST.get( (Integer) key ); + + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + reader = IDS_1_19_3[(Integer) key]; + } else + { + reader = IDS_1_19[(Integer) key]; + } } else { key = readString( buf ); 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 8a60be9f..63e9d18d 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 @@ -23,7 +23,7 @@ public class EncryptionResponse extends DefinedPacket public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { sharedSecret = readArray( buf, 128 ); - if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19 || buf.readBoolean() ) + if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19 || protocolVersion >= ProtocolConstants.MINECRAFT_1_19_3 || buf.readBoolean() ) { verifyToken = readArray( buf, 128 ); } else @@ -38,7 +38,7 @@ public class EncryptionResponse extends DefinedPacket writeArray( sharedSecret, buf ); if ( verifyToken != null ) { - if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 && protocolVersion <= ProtocolConstants.MINECRAFT_1_19_3 ) { buf.writeBoolean( true ); } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginRequest.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginRequest.java index d9839973..5186a6a8 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginRequest.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/LoginRequest.java @@ -26,7 +26,7 @@ public class LoginRequest extends DefinedPacket public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { data = readString( buf, 16 ); - if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 && protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) { publicKey = readPublicKey( buf ); } @@ -43,7 +43,7 @@ public class LoginRequest extends DefinedPacket public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) { writeString( data, buf ); - if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 ) + if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19 && protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) { writePublicKey( publicKey, buf ); } 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 7dfdb58d..9b9c412d 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 @@ -123,21 +123,26 @@ public class PlayerListItem extends DefinedPacket { // ALL - private UUID uuid; + UUID uuid; // ADD_PLAYER - private String username; - private Property[] properties; - private PlayerPublicKey publicKey; + String username; + Property[] properties; + + UUID chatSessionId; + PlayerPublicKey publicKey; + + // UPDATE_LISTED + Boolean listed; // ADD_PLAYER & UPDATE_GAMEMODE - private int gamemode; + Integer gamemode; // ADD_PLAYER & UPDATE_LATENCY - private int ping; + Integer ping; // ADD_PLAYER & UPDATE_DISPLAY_NAME - private String displayName; + String displayName; } } diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemRemove.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemRemove.java new file mode 100644 index 00000000..49877246 --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemRemove.java @@ -0,0 +1,45 @@ +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; +import java.util.UUID; +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 +@EqualsAndHashCode(callSuper = false) +public class PlayerListItemRemove extends DefinedPacket +{ + + private UUID[] uuids; + + @Override + public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + uuids = new UUID[ DefinedPacket.readVarInt( buf ) ]; + for ( int i = 0; i < uuids.length; i++ ) + { + uuids[i] = DefinedPacket.readUUID( buf ); + } + } + + @Override + public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + DefinedPacket.writeVarInt( uuids.length, buf ); + for ( UUID uuid : uuids ) + { + DefinedPacket.writeUUID( uuid, buf ); + } + } + + @Override + public void handle(AbstractPacketHandler handler) throws Exception + { + handler.handle( this ); + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java new file mode 100644 index 00000000..21d87c29 --- /dev/null +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/PlayerListItemUpdate.java @@ -0,0 +1,133 @@ +package net.md_5.bungee.protocol.packet; + +import io.netty.buffer.ByteBuf; +import java.util.EnumSet; +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.PlayerPublicKey; +import net.md_5.bungee.protocol.ProtocolConstants; +import net.md_5.bungee.protocol.packet.PlayerListItem.Item; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = false) +public class PlayerListItemUpdate extends DefinedPacket +{ + + private EnumSet actions; + private Item[] items; + + @Override + public void read(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + actions = readEnumSet( PlayerListItemUpdate.Action.class, buf ); + + items = new Item[ DefinedPacket.readVarInt( buf ) ]; + for ( int i = 0; i < items.length; i++ ) + { + Item item = items[i] = new Item(); + item.setUuid( DefinedPacket.readUUID( buf ) ); + + for ( Action action : actions ) + { + switch ( action ) + { + case ADD_PLAYER: + item.username = DefinedPacket.readString( buf ); + item.properties = DefinedPacket.readProperties( buf ); + break; + case INITIALIZE_CHAT: + if ( buf.readBoolean() ) + { + item.chatSessionId = readUUID( buf ); + item.publicKey = new PlayerPublicKey( buf.readLong(), readArray( buf, 512 ), readArray( buf, 4096 ) ); + } + break; + case UPDATE_GAMEMODE: + item.gamemode = DefinedPacket.readVarInt( buf ); + break; + case UPDATE_LISTED: + item.listed = buf.readBoolean(); + break; + case UPDATE_LATENCY: + item.ping = DefinedPacket.readVarInt( buf ); + break; + case UPDATE_DISPLAY_NAME: + if ( buf.readBoolean() ) + { + item.displayName = DefinedPacket.readString( buf ); + } + break; + } + } + } + } + + @Override + public void write(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) + { + DefinedPacket.writeEnumSet( actions, PlayerListItemUpdate.Action.class, buf ); + + DefinedPacket.writeVarInt( items.length, buf ); + for ( Item item : items ) + { + DefinedPacket.writeUUID( item.uuid, buf ); + for ( Action action : actions ) + { + switch ( action ) + { + case ADD_PLAYER: + DefinedPacket.writeString( item.username, buf ); + DefinedPacket.writeProperties( item.properties, buf ); + break; + case INITIALIZE_CHAT: + buf.writeBoolean( item.chatSessionId != null ); + if ( item.chatSessionId != null ) + { + writeUUID( item.chatSessionId, buf ); + buf.writeLong( item.publicKey.getExpiry() ); + writeArray( item.publicKey.getKey(), buf ); + writeArray( item.publicKey.getSignature(), buf ); + } + break; + case UPDATE_GAMEMODE: + DefinedPacket.writeVarInt( item.gamemode, buf ); + break; + case UPDATE_LISTED: + buf.writeBoolean( item.listed ); + break; + case UPDATE_LATENCY: + DefinedPacket.writeVarInt( item.ping, buf ); + break; + case UPDATE_DISPLAY_NAME: + buf.writeBoolean( item.displayName != null ); + if ( item.displayName != null ) + { + DefinedPacket.writeString( item.displayName, buf ); + } + break; + } + } + } + } + + @Override + public void handle(AbstractPacketHandler handler) throws Exception + { + handler.handle( this ); + } + + public static enum Action + { + + ADD_PLAYER, + INITIALIZE_CHAT, + UPDATE_GAMEMODE, + UPDATE_LISTED, + UPDATE_LATENCY, + UPDATE_DISPLAY_NAME; + } +} diff --git a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ServerData.java b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ServerData.java index 7dafa0e5..721b4f90 100644 --- a/protocol/src/main/java/net/md_5/bungee/protocol/packet/ServerData.java +++ b/protocol/src/main/java/net/md_5/bungee/protocol/packet/ServerData.java @@ -33,7 +33,10 @@ public class ServerData extends DefinedPacket icon = readString( buf ); } - preview = buf.readBoolean(); + if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) + { + preview = buf.readBoolean(); + } if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) { @@ -62,7 +65,10 @@ public class ServerData extends DefinedPacket buf.writeBoolean( false ); } - buf.writeBoolean( preview ); + if ( protocolVersion < ProtocolConstants.MINECRAFT_1_19_3 ) + { + buf.writeBoolean( preview ); + } if ( protocolVersion >= ProtocolConstants.MINECRAFT_1_19_1 ) { 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 6f5ef07b..25fdc742 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 @@ -54,6 +54,8 @@ import net.md_5.bungee.protocol.packet.Commands; import net.md_5.bungee.protocol.packet.KeepAlive; import net.md_5.bungee.protocol.packet.Kick; import net.md_5.bungee.protocol.packet.PlayerListItem; +import net.md_5.bungee.protocol.packet.PlayerListItemRemove; +import net.md_5.bungee.protocol.packet.PlayerListItemUpdate; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.Respawn; import net.md_5.bungee.protocol.packet.ScoreboardDisplay; @@ -153,6 +155,20 @@ public class DownstreamBridge extends PacketHandler throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting } + @Override + public void handle(PlayerListItemRemove playerList) throws Exception + { + con.getTabListHandler().onUpdate( TabList.rewrite( playerList ) ); + throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting + } + + @Override + public void handle(PlayerListItemUpdate playerList) throws Exception + { + con.getTabListHandler().onUpdate( TabList.rewrite( playerList ) ); + throw CancelSendSignal.INSTANCE; // Always throw because of profile rewriting + } + @Override public void handle(ScoreboardObjective objective) throws Exception { 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 d2f90b93..d3e5384b 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 @@ -383,7 +383,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection return; } - if ( BungeeCord.getInstance().config.isEnforceSecureProfile() ) + if ( BungeeCord.getInstance().config.isEnforceSecureProfile() && getVersion() < ProtocolConstants.MINECRAFT_1_19_3 ) { PlayerPublicKey publicKey = loginRequest.getPublicKey(); if ( publicKey == null ) @@ -522,7 +522,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection if ( BungeeCord.getInstance().config.isEnforceSecureProfile() ) { - if ( getVersion() >= ProtocolConstants.MINECRAFT_1_19_1 ) + if ( getVersion() >= ProtocolConstants.MINECRAFT_1_19_1 && getVersion() < ProtocolConstants.MINECRAFT_1_19_3 ) { boolean secure = false; try 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 5f4a2d45..37a17c21 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 @@ -8,6 +8,7 @@ import io.netty.channel.Channel; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.UUID; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.ServerConnection.KeepAliveData; import net.md_5.bungee.UserConnection; @@ -31,6 +32,7 @@ import net.md_5.bungee.protocol.packet.ClientCommand; import net.md_5.bungee.protocol.packet.ClientSettings; import net.md_5.bungee.protocol.packet.KeepAlive; import net.md_5.bungee.protocol.packet.PlayerListItem; +import net.md_5.bungee.protocol.packet.PlayerListItemRemove; import net.md_5.bungee.protocol.packet.PluginMessage; import net.md_5.bungee.protocol.packet.TabCompleteRequest; import net.md_5.bungee.protocol.packet.TabCompleteResponse; @@ -75,17 +77,30 @@ public class UpstreamBridge extends PacketHandler // TODO: This should only done with server_unique // tab list (which is the only one supported // currently) - PlayerListItem packet = new PlayerListItem(); - packet.setAction( PlayerListItem.Action.REMOVE_PLAYER ); + PlayerListItem oldPacket = new PlayerListItem(); + oldPacket.setAction( PlayerListItem.Action.REMOVE_PLAYER ); PlayerListItem.Item item = new PlayerListItem.Item(); item.setUuid( con.getUniqueId() ); - packet.setItems( new PlayerListItem.Item[] + oldPacket.setItems( new PlayerListItem.Item[] { item } ); + + PlayerListItemRemove newPacket = new PlayerListItemRemove(); + newPacket.setUuids( new UUID[] + { + con.getUniqueId() + } ); + for ( ProxiedPlayer player : con.getServer().getInfo().getPlayers() ) { - player.unsafe().sendPacket( packet ); + if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_19_3 ) + { + player.unsafe().sendPacket( newPacket ); + } else + { + player.unsafe().sendPacket( oldPacket ); + } } 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 dc949c66..68c6ca2d 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 @@ -77,6 +77,7 @@ public abstract class EntityMap case ProtocolConstants.MINECRAFT_1_19: return EntityMap_1_16_2.INSTANCE_1_19; case ProtocolConstants.MINECRAFT_1_19_1: + case ProtocolConstants.MINECRAFT_1_19_3: return EntityMap_1_16_2.INSTANCE_1_19_1; } throw new RuntimeException( "Version " + version + " has no entity map" ); 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..29bab7a9 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,7 +4,10 @@ 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; +import net.md_5.bungee.protocol.packet.PlayerListItemRemove; +import net.md_5.bungee.protocol.packet.PlayerListItemUpdate; public class ServerUnique extends TabList { @@ -32,6 +35,32 @@ public class ServerUnique extends TabList player.unsafe().sendPacket( playerListItem ); } + @Override + public void onUpdate(PlayerListItemRemove playerListItem) + { + for ( UUID uuid : uuids ) + { + uuids.remove( uuid ); + } + player.unsafe().sendPacket( playerListItem ); + } + + @Override + public void onUpdate(PlayerListItemUpdate playerListItem) + { + for ( PlayerListItem.Item item : playerListItem.getItems() ) + { + for ( PlayerListItemUpdate.Action action : playerListItem.getActions() ) + { + if ( action == PlayerListItemUpdate.Action.ADD_PLAYER ) + { + uuids.add( item.getUuid() ); + } + } + } + player.unsafe().sendPacket( playerListItem ); + } + @Override public void onPingChange(int ping) { @@ -41,17 +70,25 @@ public class ServerUnique extends TabList @Override public void onServerChange() { - PlayerListItem packet = new PlayerListItem(); - packet.setAction( PlayerListItem.Action.REMOVE_PLAYER ); - PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() ]; - int i = 0; - for ( UUID uuid : uuids ) + if ( player.getPendingConnection().getVersion() >= ProtocolConstants.MINECRAFT_1_19_3 ) { - PlayerListItem.Item item = items[i++] = new PlayerListItem.Item(); - item.setUuid( uuid ); + PlayerListItemRemove packet = new PlayerListItemRemove(); + packet.setUuids( uuids.stream().toArray( UUID[]::new ) ); + player.unsafe().sendPacket( packet ); + } else + { + PlayerListItem packet = new PlayerListItem(); + packet.setAction( PlayerListItem.Action.REMOVE_PLAYER ); + PlayerListItem.Item[] items = new PlayerListItem.Item[ uuids.size() ]; + int i = 0; + for ( UUID uuid : uuids ) + { + PlayerListItem.Item item = items[i++] = new PlayerListItem.Item(); + item.setUuid( uuid ); + } + packet.setItems( items ); + player.unsafe().sendPacket( packet ); } - packet.setItems( items ); - player.unsafe().sendPacket( packet ); uuids.clear(); } @@ -66,4 +103,5 @@ public class ServerUnique extends TabList { } + } diff --git a/proxy/src/main/java/net/md_5/bungee/tab/TabList.java b/proxy/src/main/java/net/md_5/bungee/tab/TabList.java index 6fea5221..a0baa388 100644 --- a/proxy/src/main/java/net/md_5/bungee/tab/TabList.java +++ b/proxy/src/main/java/net/md_5/bungee/tab/TabList.java @@ -7,6 +7,8 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.connection.LoginResult; import net.md_5.bungee.protocol.Property; import net.md_5.bungee.protocol.packet.PlayerListItem; +import net.md_5.bungee.protocol.packet.PlayerListItemRemove; +import net.md_5.bungee.protocol.packet.PlayerListItemUpdate; @RequiredArgsConstructor public abstract class TabList @@ -16,6 +18,10 @@ public abstract class TabList public abstract void onUpdate(PlayerListItem playerListItem); + public abstract void onUpdate(PlayerListItemRemove playerListItem); + + public abstract void onUpdate(PlayerListItemUpdate playerListItem); + public abstract void onPingChange(int ping); public abstract void onServerChange(); @@ -28,14 +34,48 @@ public abstract class TabList { for ( PlayerListItem.Item item : playerListItem.getItems() ) { - if ( item.getUuid() == null ) // Old style ping - { - continue; - } - UserConnection player = BungeeCord.getInstance().getPlayerByOfflineUUID( item.getUuid() ); + rewrite( item ); + } + return playerListItem; + } + + public static PlayerListItemRemove rewrite(PlayerListItemRemove playerListItem) + { + for ( int i = 0; i < playerListItem.getUuids().length; i++ ) + { + UserConnection player = BungeeCord.getInstance().getPlayerByOfflineUUID( playerListItem.getUuids()[i] ); if ( player != null ) { - item.setUuid( player.getUniqueId() ); + playerListItem.getUuids()[i] = player.getUniqueId(); + + } + } + + return playerListItem; + } + + public static PlayerListItemUpdate rewrite(PlayerListItemUpdate playerListItem) + { + for ( PlayerListItem.Item item : playerListItem.getItems() ) + { + rewrite( item ); + } + return playerListItem; + } + + private static void rewrite(PlayerListItem.Item item) + { + if ( item.getUuid() == null ) // Old style ping + { + return; + } + UserConnection player = BungeeCord.getInstance().getPlayerByOfflineUUID( item.getUuid() ); + if ( player != null ) + { + item.setUuid( player.getUniqueId() ); + + if ( item.getProperties() != null ) + { LoginResult loginResult = player.getPendingConnection().getLoginProfile(); if ( loginResult != null && loginResult.getProperties() != null ) { @@ -49,16 +89,15 @@ public abstract class TabList { item.setProperties( new Property[ 0 ] ); } - if ( playerListItem.getAction() == PlayerListItem.Action.ADD_PLAYER || playerListItem.getAction() == PlayerListItem.Action.UPDATE_GAMEMODE ) - { - player.setGamemode( item.getGamemode() ); - } - if ( playerListItem.getAction() == PlayerListItem.Action.ADD_PLAYER || playerListItem.getAction() == PlayerListItem.Action.UPDATE_LATENCY ) - { - player.setPing( item.getPing() ); - } + } + if ( item.getGamemode() != null ) + { + player.setGamemode( item.getGamemode() ); + } + if ( item.getPing() != null ) + { + player.setPing( item.getPing() ); } } - return playerListItem; } }