From 00982f3620d5f54af118b08bd1438bc942225be4 Mon Sep 17 00:00:00 2001 From: Janmm14 Date: Fri, 11 Jun 2021 16:53:31 +1000 Subject: [PATCH] #3104: Use lambdas rather than reflection to create packets --- .../net/md_5/bungee/protocol/Protocol.java | 119 +++++++++++------- 1 file changed, 74 insertions(+), 45 deletions(-) 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 de94bfda..f29355bb 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 @@ -6,7 +6,7 @@ import gnu.trove.map.TIntObjectMap; import gnu.trove.map.TObjectIntMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TObjectIntHashMap; -import java.lang.reflect.Constructor; +import java.util.function.Supplier; import lombok.Data; import lombok.Getter; import net.md_5.bungee.protocol.packet.BossBar; @@ -55,6 +55,7 @@ public enum Protocol { TO_SERVER.registerPacket( Handshake.class, + Handshake::new, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) ); } @@ -66,6 +67,7 @@ public enum Protocol { TO_CLIENT.registerPacket( KeepAlive.class, + KeepAlive::new, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ), map( ProtocolConstants.MINECRAFT_1_9, 0x1F ), map( ProtocolConstants.MINECRAFT_1_13, 0x21 ), @@ -77,6 +79,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( Login.class, + Login::new, map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), map( ProtocolConstants.MINECRAFT_1_9, 0x23 ), map( ProtocolConstants.MINECRAFT_1_13, 0x25 ), @@ -87,6 +90,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( Chat.class, + Chat::new, map( ProtocolConstants.MINECRAFT_1_8, 0x02 ), map( ProtocolConstants.MINECRAFT_1_9, 0x0F ), map( ProtocolConstants.MINECRAFT_1_13, 0x0E ), @@ -96,6 +100,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( Respawn.class, + Respawn::new, map( ProtocolConstants.MINECRAFT_1_8, 0x07 ), map( ProtocolConstants.MINECRAFT_1_9, 0x33 ), map( ProtocolConstants.MINECRAFT_1_12, 0x34 ), @@ -109,6 +114,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( BossBar.class, + BossBar::new, map( ProtocolConstants.MINECRAFT_1_9, 0x0C ), map( ProtocolConstants.MINECRAFT_1_15, 0x0D ), map( ProtocolConstants.MINECRAFT_1_16, 0x0C ), @@ -116,6 +122,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( PlayerListItem.class, // PlayerInfo + PlayerListItem::new, map( ProtocolConstants.MINECRAFT_1_8, 0x38 ), map( ProtocolConstants.MINECRAFT_1_9, 0x2D ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x2E ), @@ -128,6 +135,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( TabCompleteResponse.class, + TabCompleteResponse::new, map( ProtocolConstants.MINECRAFT_1_8, 0x3A ), map( ProtocolConstants.MINECRAFT_1_9, 0x0E ), map( ProtocolConstants.MINECRAFT_1_13, 0x10 ), @@ -138,6 +146,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( ScoreboardObjective.class, + ScoreboardObjective::new, map( ProtocolConstants.MINECRAFT_1_8, 0x3B ), map( ProtocolConstants.MINECRAFT_1_9, 0x3F ), map( ProtocolConstants.MINECRAFT_1_12, 0x41 ), @@ -149,6 +158,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( ScoreboardScore.class, + ScoreboardScore::new, map( ProtocolConstants.MINECRAFT_1_8, 0x3C ), map( ProtocolConstants.MINECRAFT_1_9, 0x42 ), map( ProtocolConstants.MINECRAFT_1_12, 0x44 ), @@ -160,6 +170,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( ScoreboardDisplay.class, + ScoreboardDisplay::new, map( ProtocolConstants.MINECRAFT_1_8, 0x3D ), map( ProtocolConstants.MINECRAFT_1_9, 0x38 ), map( ProtocolConstants.MINECRAFT_1_12, 0x3A ), @@ -171,6 +182,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( Team.class, + Team::new, map( ProtocolConstants.MINECRAFT_1_8, 0x3E ), map( ProtocolConstants.MINECRAFT_1_9, 0x41 ), map( ProtocolConstants.MINECRAFT_1_12, 0x43 ), @@ -182,6 +194,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( PluginMessage.class, + PluginMessage::new, map( ProtocolConstants.MINECRAFT_1_8, 0x3F ), map( ProtocolConstants.MINECRAFT_1_9, 0x18 ), map( ProtocolConstants.MINECRAFT_1_13, 0x19 ), @@ -193,6 +206,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( Kick.class, + Kick::new, map( ProtocolConstants.MINECRAFT_1_8, 0x40 ), map( ProtocolConstants.MINECRAFT_1_9, 0x1A ), map( ProtocolConstants.MINECRAFT_1_13, 0x1B ), @@ -204,6 +218,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( Title.class, + Title::new, map( ProtocolConstants.MINECRAFT_1_8, 0x45 ), map( ProtocolConstants.MINECRAFT_1_12, 0x47 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x48 ), @@ -213,18 +228,24 @@ public enum Protocol map( ProtocolConstants.MINECRAFT_1_16, 0x4F ), map( ProtocolConstants.MINECRAFT_1_17, 0x59 ) ); - TO_CLIENT.registerPacket( ClearTitles.class, + TO_CLIENT.registerPacket( + ClearTitles.class, + ClearTitles::new, map( ProtocolConstants.MINECRAFT_1_17, 0x10 ) ); TO_CLIENT.registerPacket( Subtitle.class, + Subtitle::new, map( ProtocolConstants.MINECRAFT_1_17, 0x57 ) ); - TO_CLIENT.registerPacket( TitleTimes.class, + TO_CLIENT.registerPacket( + TitleTimes.class, + TitleTimes::new, map( ProtocolConstants.MINECRAFT_1_17, 0x5A ) ); TO_CLIENT.registerPacket( PlayerListHeaderFooter.class, + PlayerListHeaderFooter::new, map( ProtocolConstants.MINECRAFT_1_8, 0x47 ), map( ProtocolConstants.MINECRAFT_1_9, 0x48 ), map( ProtocolConstants.MINECRAFT_1_9_4, 0x47 ), @@ -238,6 +259,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( EntityStatus.class, + EntityStatus::new, map( ProtocolConstants.MINECRAFT_1_8, 0x1A ), map( ProtocolConstants.MINECRAFT_1_9, 0x1B ), map( ProtocolConstants.MINECRAFT_1_13, 0x1C ), @@ -249,6 +271,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( Commands.class, + Commands::new, map( ProtocolConstants.MINECRAFT_1_13, 0x11 ), map( ProtocolConstants.MINECRAFT_1_15, 0x12 ), map( ProtocolConstants.MINECRAFT_1_16, 0x11 ), @@ -257,6 +280,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( GameState.class, + GameState::new, map( ProtocolConstants.MINECRAFT_1_15, 0x1F ), map( ProtocolConstants.MINECRAFT_1_16, 0x1E ), map( ProtocolConstants.MINECRAFT_1_16_2, 0x1D ), @@ -264,6 +288,7 @@ public enum Protocol ); TO_CLIENT.registerPacket( ViewDistance.class, + ViewDistance::new, map( ProtocolConstants.MINECRAFT_1_14, 0x41 ), map( ProtocolConstants.MINECRAFT_1_15, 0x42 ), map( ProtocolConstants.MINECRAFT_1_16, 0x41 ), @@ -272,6 +297,7 @@ public enum Protocol TO_SERVER.registerPacket( KeepAlive.class, + KeepAlive::new, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ), map( ProtocolConstants.MINECRAFT_1_9, 0x0B ), map( ProtocolConstants.MINECRAFT_1_12, 0x0C ), @@ -283,6 +309,7 @@ public enum Protocol ); TO_SERVER.registerPacket( Chat.class, + Chat::new, map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), map( ProtocolConstants.MINECRAFT_1_9, 0x02 ), map( ProtocolConstants.MINECRAFT_1_12, 0x03 ), @@ -291,6 +318,7 @@ public enum Protocol ); TO_SERVER.registerPacket( TabCompleteRequest.class, + TabCompleteRequest::new, map( ProtocolConstants.MINECRAFT_1_8, 0x14 ), map( ProtocolConstants.MINECRAFT_1_9, 0x01 ), map( ProtocolConstants.MINECRAFT_1_12, 0x02 ), @@ -300,6 +328,7 @@ public enum Protocol ); TO_SERVER.registerPacket( ClientSettings.class, + ClientSettings::new, map( ProtocolConstants.MINECRAFT_1_8, 0x15 ), map( ProtocolConstants.MINECRAFT_1_9, 0x04 ), map( ProtocolConstants.MINECRAFT_1_12, 0x05 ), @@ -308,6 +337,7 @@ public enum Protocol ); TO_SERVER.registerPacket( PluginMessage.class, + PluginMessage::new, map( ProtocolConstants.MINECRAFT_1_8, 0x17 ), map( ProtocolConstants.MINECRAFT_1_9, 0x09 ), map( ProtocolConstants.MINECRAFT_1_12, 0x0A ), @@ -325,19 +355,23 @@ public enum Protocol { TO_CLIENT.registerPacket( StatusResponse.class, + StatusResponse::new, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) ); TO_CLIENT.registerPacket( PingPacket.class, + PingPacket::new, map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) ); TO_SERVER.registerPacket( StatusRequest.class, + StatusRequest::new, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) ); TO_SERVER.registerPacket( PingPacket.class, + PingPacket::new, map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) ); } @@ -349,35 +383,43 @@ public enum Protocol { TO_CLIENT.registerPacket( Kick.class, + Kick::new, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) ); TO_CLIENT.registerPacket( EncryptionRequest.class, + EncryptionRequest::new, map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) ); TO_CLIENT.registerPacket( LoginSuccess.class, + LoginSuccess::new, map( ProtocolConstants.MINECRAFT_1_8, 0x02 ) ); TO_CLIENT.registerPacket( SetCompression.class, + SetCompression::new, map( ProtocolConstants.MINECRAFT_1_8, 0x03 ) ); TO_CLIENT.registerPacket( LoginPayloadRequest.class, + LoginPayloadRequest::new, map( ProtocolConstants.MINECRAFT_1_13, 0x04 ) ); TO_SERVER.registerPacket( LoginRequest.class, + LoginRequest::new, map( ProtocolConstants.MINECRAFT_1_8, 0x00 ) ); TO_SERVER.registerPacket( EncryptionResponse.class, + EncryptionResponse::new, map( ProtocolConstants.MINECRAFT_1_8, 0x01 ) ); TO_SERVER.registerPacket( LoginPayloadResponse.class, + LoginPayloadResponse::new, map( ProtocolConstants.MINECRAFT_1_13, 0x02 ) ); } @@ -428,7 +470,8 @@ public enum Protocol private final int protocolVersion; private final TObjectIntMap> packetMap = new TObjectIntHashMap<>( MAX_PACKET_ID ); - private final Constructor[] packetConstructors = new Constructor[ MAX_PACKET_ID ]; + @SuppressWarnings("unchecked") + private final Supplier[] packetConstructors = new Supplier[ MAX_PACKET_ID ]; } @Data @@ -484,55 +527,41 @@ public enum Protocol } if ( id > MAX_PACKET_ID ) { - throw new BadPacketException( "Packet with id " + id + " outside of range " ); + throw new BadPacketException( "Packet with id " + id + " outside of range" ); } - Constructor constructor = protocolData.packetConstructors[id]; - try - { - return ( constructor == null ) ? null : constructor.newInstance(); - } catch ( ReflectiveOperationException ex ) - { - throw new BadPacketException( "Could not construct packet with id " + id, ex ); - } + Supplier constructor = protocolData.packetConstructors[id]; + return ( constructor == null ) ? null : constructor.get(); } - private void registerPacket(Class packetClass, ProtocolMapping... mappings) + private void registerPacket(Class packetClass, Supplier constructor, ProtocolMapping... mappings) { - try + int mappingIndex = 0; + ProtocolMapping mapping = mappings[mappingIndex]; + for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS ) { - Constructor constructor = packetClass.getDeclaredConstructor(); - - int mappingIndex = 0; - ProtocolMapping mapping = mappings[mappingIndex]; - for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS ) + if ( protocol < mapping.protocolVersion ) { - if ( protocol < mapping.protocolVersion ) - { - // This is a new packet, skip it till we reach the next protocol - continue; - } - - if ( mapping.protocolVersion < protocol && mappingIndex + 1 < mappings.length ) - { - // Mapping is non current, but the next one may be ok - ProtocolMapping nextMapping = mappings[mappingIndex + 1]; - if ( nextMapping.protocolVersion == protocol ) - { - Preconditions.checkState( nextMapping.packetID != mapping.packetID, "Duplicate packet mapping (%s, %s)", mapping.protocolVersion, nextMapping.protocolVersion ); - - mapping = nextMapping; - mappingIndex++; - } - } - - ProtocolData data = protocols.get( protocol ); - data.packetMap.put( packetClass, mapping.packetID ); - data.packetConstructors[mapping.packetID] = constructor; + // This is a new packet, skip it till we reach the next protocol + continue; } - } catch ( NoSuchMethodException ex ) - { - throw new BadPacketException( "No NoArgsConstructor for packet class " + packetClass ); + + if ( mapping.protocolVersion < protocol && mappingIndex + 1 < mappings.length ) + { + // Mapping is non current, but the next one may be ok + ProtocolMapping nextMapping = mappings[mappingIndex + 1]; + if ( nextMapping.protocolVersion == protocol ) + { + Preconditions.checkState( nextMapping.packetID != mapping.packetID, "Duplicate packet mapping (%s, %s)", mapping.protocolVersion, nextMapping.protocolVersion ); + + mapping = nextMapping; + mappingIndex++; + } + } + + ProtocolData data = protocols.get( protocol ); + data.packetMap.put( packetClass, mapping.packetID ); + data.packetConstructors[mapping.packetID] = constructor; } }