Paklet is annotation based Java library for simple and fast packet crafting.
- Simplicity – The annotation system is straightforward and easy to use
- Flexibility – You can customize the serialization of each packet field or even the whole packet
- Expandable – Paklet can be easily extended to automate the serialization of custom types.
- Speed – Bytecode manipulation in the background ensures the packet serialization is fast
All classes annotated with @Packet
are considered packets. All their fields, if they are not static, transient,
or annotated with @Ignore
are automatically serialized by default serializers if not specified otherwise.
All field values are expected to be not null by default, but this behaviour can be changed
with the use of @Optional annotation.
@Packet(id = 0x00, group = "ClientBoundStatus", catalogue = ClientBoundStatusPackets.class)
publicclassStatusResponsePacket {
privateStringjsonResponse;
// getters and setters
}Each packet needs to specify its numeric ID, catalogue class, and can specify its group in case the packet IDs overlap, this is later used for deserialization.
Packet IDs can be alternatively resolved using @PacketID
annotation for packets that require dynamic IDs.
@Packet(id = DYNAMIC_PACKET, group = "ClientBoundStatus", catalogue = ClientBoundStatusPackets.class)
publicclassStatusResponsePacket {
@PacketIDpublicstaticfinalintID = PacketUtil.getID(StatusResponsePacket.class);
privateStringjsonResponse;
// getters and setters
}To specify which serializer to use for each packet field serialization, Paklet offers
@SerializeWith annotation
and serializer annotation aliases.
@Packet(id = 0x01, catalogue = TestPackets.class)
publicclassPingPacket {
// with the usage of SerializeWithprivate@SerializeWith(VarIntSerializer.class) intvalue;
// with the aliasprivate@VarIntintalias;
}Some types can be annotated with additional metadata. Default set of supported metadata by Paklet can be found in metadata package.
Both modifiers and metadata can be used for parameters, e.g. List<@VarLong Long>.
For packets that require fully custom serialization, Paklet offers the
CustomPacket interface. This is
meant to be used for packets that require more complicated serialization that can not be
resolved with automatic serialization.
Note
Paklet also offers VarIntSerializer
and VarLongSerializer compatible with the Minecraft Java Protocol.
For more examples see tests of the paklet-core module.
Paklet allows simple way of creating custom serializers.
To create a custom serializer, implement Serializer interface.
@Supports({Integer.class, int.class})
publicclassMyCustomSerializerimplementsSerializer<Integer> {
@Overridepublicvoidserialize(SerializerContextcontext, DataVisitorvisitor, Integervalue) {
// serialization
}
@OverridepublicIntegerdeserialize(SerializerContextcontext, DataVisitorvisitor) {
// deserialization
}
}@Supports annotation specifies which types the serializer supports,
if more complex rule for choosing the types is needed (e.g. array types), the array can stay empty and custom
SerializationRule needs to be implemented.
All serializers annotated with @DefaultSerializer are automatically registered with given catalogue.
SerializerContext provided for each serialization action gives
access to currently registered serializers and type of field that is currently being serialized.
| Serializer | Supported types | Catalogue |
|---|---|---|
| Boolean | Boolean, boolean | DefaultSerializers |
| Byte | Byte, byte | DefaultSerializers |
| Short | Short, short | DefaultSerializers |
| Integer | Integer, int | DefaultSerializers |
| Long | Long, long | DefaultSerializers |
| Float | Float, float | DefaultSerializers |
| Double | Double, double | DefaultSerializers |
| Character | Character, char | DefaultSerializers |
| Number | Number, BigDecimal, BigInteger | DefaultSerializers |
| String | String | DefaultSerializers |
| Collection | Collection, SequencedCollection, List, LinkedList, ArrayList, Set, LinkedHashSet, HashSet | DefaultSerializers |
| Map | Map, SequencedMap, HashMap, LinkedHashMap, TreeMap | DefaultSerializers |
| UUID | UUID | DefaultSerializers |
| Instant | Instant | DefaultSerializers |
| BitSet | BitSet | DefaultSerializers |
| Enum | none, has to be specified | DefaultSerializers |
| Array | none, has to be specified | DefaultSerializers |
| Serializable | none, has to be specified | DefaultSerializers |
| VarIntSerializer | Integer, int | none |
| VarLongSerializer | Long, long | none |
For more examples of serializer implementation, see Serializers.
To read and write packets, instance of PacketFactory is required.
The default implementation is provided in paklet-core module as PacketFactoryImpl.
publicstaticPacketFactorycreateFactory() {
// Creates new serializer providerSerializerProviderserializerProvider = newSerializerProviderImpl();
// Registers default serializers and serialization rules provided by PakletserializerProvider.addSerializers(DefaultSerializers.class);
serializerProvider.addSerializationRules(DefaultSerializationRules.class);
// Creates new packet factoryPacketFactorypacketFactory = newPacketFactoryImpl(PacketEncoder.varInt(), serializerProvider);
// Registers custom packetspacketFactory.addPackets(MyPacketsCatalogue.class);
returnpacketFactory;
}Packets can be then read and written as such:
// implementation of data visitor backed by netty's byte buffer provided by Paklet.DataVisitorvisitor = newNettyDataVisitor(Unpooled.buffer());
MyPacketpacket = newMyPacket();
packet.setContent("Hello World");
// Serializationfactory.write(packet, visitor);
// DeserializationMyPacketpacketClone = factory.create(packetGroup, visitor);Paklet has much more tools to offer than shown in this README, developers are encouraged to explore the source code and discover additional APIs! :)
For more examples see tests of the paklet-core module.
repositories {
maven {
name ="machinemcRepositoryReleases"
url = uri("https://repo.machinemc.org/releases")
}
}
dependencies {
implementation("org.machinemc:paklet-api:VERSION")
annotationProcessor("org.machinemc:paklet-processor:VERSION")
}repositories {
maven {
name ="machinemcRepositoryReleases"
url = uri("https://repo.machinemc.org/releases")
}
}
dependencies {
implementation("org.machinemc:paklet-core:VERSION")
}Note
Gradle plugin is a key feature of Paklet. It modifies bytecode of compiled packet classes later used by generated packet readers and writers to achieve higher speeds.
buildscript {
repositories {
maven {
url = uri("https://repo.machinemc.org/releases")
}
}
dependencies {
classpath("org.machinemc:paklet-plugin:VERSION")
}
}
apply<PakletPlugin>()Paklet is free software licensed under the MIT license.

