Simplify packet registration

This commit is contained in:
md_5 2019-02-26 13:05:02 +11:00
parent 6d6fbb5efa
commit 9133a6f511
2 changed files with 46 additions and 89 deletions

View File

@ -1,16 +1,13 @@
package net.md_5.bungee.protocol; package net.md_5.bungee.protocol;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import gnu.trove.map.TIntObjectMap; import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.TObjectIntMap; import gnu.trove.map.TObjectIntMap;
import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.map.hash.TObjectIntHashMap;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Arrays; import lombok.Data;
import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.protocol.packet.BossBar; import net.md_5.bungee.protocol.packet.BossBar;
import net.md_5.bungee.protocol.packet.Chat; import net.md_5.bungee.protocol.packet.Chat;
import net.md_5.bungee.protocol.packet.ClientSettings; import net.md_5.bungee.protocol.packet.ClientSettings;
@ -65,21 +62,18 @@ public enum Protocol
KeepAlive.class, KeepAlive.class,
map( ProtocolConstants.MINECRAFT_1_8, 0x00 ), map( ProtocolConstants.MINECRAFT_1_8, 0x00 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x1F ), map( ProtocolConstants.MINECRAFT_1_9, 0x1F ),
map( ProtocolConstants.MINECRAFT_1_12, 0x1F ),
map( ProtocolConstants.MINECRAFT_1_13, 0x21 ) map( ProtocolConstants.MINECRAFT_1_13, 0x21 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Login.class, Login.class,
map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), map( ProtocolConstants.MINECRAFT_1_8, 0x01 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x23 ), map( ProtocolConstants.MINECRAFT_1_9, 0x23 ),
map( ProtocolConstants.MINECRAFT_1_12, 0x23 ),
map( ProtocolConstants.MINECRAFT_1_13, 0x25 ) map( ProtocolConstants.MINECRAFT_1_13, 0x25 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Chat.class, Chat.class,
map( ProtocolConstants.MINECRAFT_1_8, 0x02 ), map( ProtocolConstants.MINECRAFT_1_8, 0x02 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x0F ), map( ProtocolConstants.MINECRAFT_1_9, 0x0F ),
map( ProtocolConstants.MINECRAFT_1_12, 0x0F ),
map( ProtocolConstants.MINECRAFT_1_13, 0x0E ) map( ProtocolConstants.MINECRAFT_1_13, 0x0E )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
@ -92,15 +86,12 @@ public enum Protocol
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
BossBar.class, BossBar.class,
map( ProtocolConstants.MINECRAFT_1_9, 0x0C ), map( ProtocolConstants.MINECRAFT_1_9, 0x0C )
map( ProtocolConstants.MINECRAFT_1_12, 0x0C ),
map( ProtocolConstants.MINECRAFT_1_13, 0x0C )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
PlayerListItem.class, // PlayerInfo PlayerListItem.class, // PlayerInfo
map( ProtocolConstants.MINECRAFT_1_8, 0x38 ), map( ProtocolConstants.MINECRAFT_1_8, 0x38 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x2D ), map( ProtocolConstants.MINECRAFT_1_9, 0x2D ),
map( ProtocolConstants.MINECRAFT_1_12, 0x2D ),
map( ProtocolConstants.MINECRAFT_1_12_1, 0x2E ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x2E ),
map( ProtocolConstants.MINECRAFT_1_13, 0x30 ) map( ProtocolConstants.MINECRAFT_1_13, 0x30 )
); );
@ -108,7 +99,6 @@ public enum Protocol
TabCompleteResponse.class, TabCompleteResponse.class,
map( ProtocolConstants.MINECRAFT_1_8, 0x3A ), map( ProtocolConstants.MINECRAFT_1_8, 0x3A ),
map( ProtocolConstants.MINECRAFT_1_9, 0x0E ), map( ProtocolConstants.MINECRAFT_1_9, 0x0E ),
map( ProtocolConstants.MINECRAFT_1_12, 0x0E ),
map( ProtocolConstants.MINECRAFT_1_13, 0x10 ) map( ProtocolConstants.MINECRAFT_1_13, 0x10 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
@ -147,14 +137,12 @@ public enum Protocol
PluginMessage.class, PluginMessage.class,
map( ProtocolConstants.MINECRAFT_1_8, 0x3F ), map( ProtocolConstants.MINECRAFT_1_8, 0x3F ),
map( ProtocolConstants.MINECRAFT_1_9, 0x18 ), map( ProtocolConstants.MINECRAFT_1_9, 0x18 ),
map( ProtocolConstants.MINECRAFT_1_12, 0x18 ),
map( ProtocolConstants.MINECRAFT_1_13, 0x19 ) map( ProtocolConstants.MINECRAFT_1_13, 0x19 )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
Kick.class, Kick.class,
map( ProtocolConstants.MINECRAFT_1_8, 0x40 ), map( ProtocolConstants.MINECRAFT_1_8, 0x40 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x1A ), map( ProtocolConstants.MINECRAFT_1_9, 0x1A ),
map( ProtocolConstants.MINECRAFT_1_12, 0x1A ),
map( ProtocolConstants.MINECRAFT_1_13, 0x1B ) map( ProtocolConstants.MINECRAFT_1_13, 0x1B )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
@ -177,7 +165,6 @@ public enum Protocol
EntityStatus.class, EntityStatus.class,
map( ProtocolConstants.MINECRAFT_1_8, 0x1A ), map( ProtocolConstants.MINECRAFT_1_8, 0x1A ),
map( ProtocolConstants.MINECRAFT_1_9, 0x1B ), map( ProtocolConstants.MINECRAFT_1_9, 0x1B ),
map( ProtocolConstants.MINECRAFT_1_12, 0x1B ),
map( ProtocolConstants.MINECRAFT_1_13, 0x1C ) map( ProtocolConstants.MINECRAFT_1_13, 0x1C )
); );
TO_CLIENT.registerPacket( TO_CLIENT.registerPacket(
@ -198,8 +185,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_8, 0x01 ), map( ProtocolConstants.MINECRAFT_1_8, 0x01 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x02 ), map( ProtocolConstants.MINECRAFT_1_9, 0x02 ),
map( ProtocolConstants.MINECRAFT_1_12, 0x03 ), map( ProtocolConstants.MINECRAFT_1_12, 0x03 ),
map( ProtocolConstants.MINECRAFT_1_12_1, 0x02 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x02 )
map( ProtocolConstants.MINECRAFT_1_13, 0x02 )
); );
TO_SERVER.registerPacket( TO_SERVER.registerPacket(
TabCompleteRequest.class, TabCompleteRequest.class,
@ -214,8 +200,7 @@ public enum Protocol
map( ProtocolConstants.MINECRAFT_1_8, 0x15 ), map( ProtocolConstants.MINECRAFT_1_8, 0x15 ),
map( ProtocolConstants.MINECRAFT_1_9, 0x04 ), map( ProtocolConstants.MINECRAFT_1_9, 0x04 ),
map( ProtocolConstants.MINECRAFT_1_12, 0x05 ), map( ProtocolConstants.MINECRAFT_1_12, 0x05 ),
map( ProtocolConstants.MINECRAFT_1_12_1, 0x04 ), map( ProtocolConstants.MINECRAFT_1_12_1, 0x04 )
map( ProtocolConstants.MINECRAFT_1_13, 0x04 )
); );
TO_SERVER.registerPacket( TO_SERVER.registerPacket(
PluginMessage.class, PluginMessage.class,
@ -294,8 +279,8 @@ public enum Protocol
/*========================================================================*/ /*========================================================================*/
public static final int MAX_PACKET_ID = 0xFF; public static final int MAX_PACKET_ID = 0xFF;
/*========================================================================*/ /*========================================================================*/
public final DirectionData TO_SERVER = new DirectionData( this, ProtocolConstants.Direction.TO_SERVER ); final DirectionData TO_SERVER = new DirectionData( this, ProtocolConstants.Direction.TO_SERVER );
public final DirectionData TO_CLIENT = new DirectionData( this, ProtocolConstants.Direction.TO_CLIENT ); final DirectionData TO_CLIENT = new DirectionData( this, ProtocolConstants.Direction.TO_CLIENT );
public static void main(String[] args) public static void main(String[] args)
{ {
@ -331,7 +316,7 @@ public enum Protocol
} }
} }
@RequiredArgsConstructor @Data
private static class ProtocolData private static class ProtocolData
{ {
@ -340,7 +325,7 @@ public enum Protocol
private final Constructor<? extends DefinedPacket>[] packetConstructors = new Constructor[ MAX_PACKET_ID ]; private final Constructor<? extends DefinedPacket>[] packetConstructors = new Constructor[ MAX_PACKET_ID ];
} }
@RequiredArgsConstructor @Data
private static class ProtocolMapping private static class ProtocolMapping
{ {
@ -354,66 +339,32 @@ public enum Protocol
return new ProtocolMapping( protocol, id ); return new ProtocolMapping( protocol, id );
} }
@RequiredArgsConstructor static final class DirectionData
public static class DirectionData
{ {
private final Protocol protocolPhase;
private final TIntObjectMap<ProtocolData> protocols = new TIntObjectHashMap<>(); private final TIntObjectMap<ProtocolData> protocols = new TIntObjectHashMap<>();
//
private final Protocol protocolPhase;
@Getter
private final ProtocolConstants.Direction direction;
public DirectionData(Protocol protocolPhase, ProtocolConstants.Direction direction)
{ {
this.protocolPhase = protocolPhase;
this.direction = direction;
for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS ) for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS )
{ {
protocols.put( protocol, new ProtocolData( protocol ) ); protocols.put( protocol, new ProtocolData( protocol ) );
} }
} }
private final TIntObjectMap<List<Integer>> linkedProtocols = new TIntObjectHashMap<>();
{
linkedProtocols.put( ProtocolConstants.MINECRAFT_1_8, Arrays.asList(
ProtocolConstants.MINECRAFT_1_9,
ProtocolConstants.MINECRAFT_1_12,
ProtocolConstants.MINECRAFT_1_13
) );
linkedProtocols.put( ProtocolConstants.MINECRAFT_1_9, Arrays.asList(
ProtocolConstants.MINECRAFT_1_9_1,
ProtocolConstants.MINECRAFT_1_9_2,
ProtocolConstants.MINECRAFT_1_9_4
) );
linkedProtocols.put( ProtocolConstants.MINECRAFT_1_9_4, Arrays.asList(
ProtocolConstants.MINECRAFT_1_10,
ProtocolConstants.MINECRAFT_1_11,
ProtocolConstants.MINECRAFT_1_11_1
) );
linkedProtocols.put( ProtocolConstants.MINECRAFT_1_12, Arrays.asList(
ProtocolConstants.MINECRAFT_1_12_1
) );
linkedProtocols.put( ProtocolConstants.MINECRAFT_1_12_1, Arrays.asList(
ProtocolConstants.MINECRAFT_1_12_2
) );
linkedProtocols.put( ProtocolConstants.MINECRAFT_1_13, Arrays.asList(
ProtocolConstants.MINECRAFT_1_13_1,
ProtocolConstants.MINECRAFT_1_13_2
) );
}
@Getter
private final ProtocolConstants.Direction direction;
private ProtocolData getProtocolData(int version)
{
ProtocolData protocol = protocols.get( version );
if ( protocol == null && ( protocolPhase != Protocol.GAME ) )
{
protocol = Iterables.getFirst( protocols.valueCollection(), null );
}
return protocol;
}
public final DefinedPacket createPacket(int id, int version) public final DefinedPacket createPacket(int id, int version)
{ {
ProtocolData protocolData = getProtocolData( version ); ProtocolData protocolData = protocols.get( version );
if ( protocolData == null ) if ( protocolData == null )
{ {
throw new BadPacketException( "Unsupported protocol version" ); throw new BadPacketException( "Unsupported protocol version " + version );
} }
if ( id > MAX_PACKET_ID ) if ( id > MAX_PACKET_ID )
{ {
@ -430,33 +381,38 @@ public enum Protocol
} }
} }
protected final void registerPacket(Class<? extends DefinedPacket> packetClass, ProtocolMapping... mappings) private void registerPacket(Class<? extends DefinedPacket> packetClass, ProtocolMapping... mappings)
{ {
try try
{ {
Constructor<? extends DefinedPacket> constructor = packetClass.getDeclaredConstructor(); Constructor<? extends DefinedPacket> constructor = packetClass.getDeclaredConstructor();
for ( ProtocolMapping mapping : mappings )
int mappingIndex = 0;
ProtocolMapping mapping = mappings[mappingIndex];
for ( int protocol : ProtocolConstants.SUPPORTED_VERSION_IDS )
{ {
ProtocolData data = protocols.get( 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.packetMap.put( packetClass, mapping.packetID );
data.packetConstructors[mapping.packetID] = constructor; data.packetConstructors[mapping.packetID] = constructor;
List<Integer> links = linkedProtocols.get( mapping.protocolVersion );
if ( links != null )
{
links: for ( int link : links )
{
// Check for manual mappings
for ( ProtocolMapping m : mappings )
{
if ( m == mapping ) continue;
if ( m.protocolVersion == link ) continue links;
List<Integer> innerLinks = linkedProtocols.get( m.protocolVersion );
if ( innerLinks != null && innerLinks.contains( link ) ) continue links;
}
registerPacket( packetClass, map( link, mapping.packetID ) );
}
}
} }
} catch ( NoSuchMethodException ex ) } catch ( NoSuchMethodException ex )
{ {
@ -467,7 +423,7 @@ public enum Protocol
final int getId(Class<? extends DefinedPacket> packet, int version) final int getId(Class<? extends DefinedPacket> packet, int version)
{ {
ProtocolData protocolData = getProtocolData( version ); ProtocolData protocolData = protocols.get( version );
if ( protocolData == null ) if ( protocolData == null )
{ {
throw new BadPacketException( "Unsupported protocol version" ); throw new BadPacketException( "Unsupported protocol version" );

View File

@ -28,7 +28,8 @@ public class ProtocolConstants
"1.12.x", "1.12.x",
"1.13.x" "1.13.x"
); );
public static final List<Integer> SUPPORTED_VERSION_IDS = Arrays.asList( ProtocolConstants.MINECRAFT_1_8, public static final List<Integer> SUPPORTED_VERSION_IDS = Arrays.asList(
ProtocolConstants.MINECRAFT_1_8,
ProtocolConstants.MINECRAFT_1_9, ProtocolConstants.MINECRAFT_1_9,
ProtocolConstants.MINECRAFT_1_9_1, ProtocolConstants.MINECRAFT_1_9_1,
ProtocolConstants.MINECRAFT_1_9_2, ProtocolConstants.MINECRAFT_1_9_2,