ModificationStation / StationAPI

A general use API for Fabric Loader mods on legacy Minecraft versions.
86 stars 20 forks source link

Packet types #123

Closed mineLdiver closed 4 weeks ago

mineLdiver commented 4 months ago

This pull request aims to address a few issues with the current identifiable packet system in StationAPI.

Specifically:

  1. Packet size. Each packet writes its string identifier in full instead of using a more compact ID.
  2. Awkward API. Current API tries to mimic the vanilla packets system, awkwardly so, and not taking enough advantage of the systems StationAPI provides within itself.
  3. Name conflicts. IdentifiablePacket interface adds the getId() method, which works fine with biny mappings, since it takes on the modern approach of naming numeric IDs "raw" IDs, thus naming the vanilla ID method getRawId(), but breaks with mappings such as Nostalgia which use getId() instead of getRawId(), making the mappings unusable with StationAPI.

Following changes were implemented:

Concise API

Instead of trying to mimic the vanilla packet system, this pull request implements its own system centered around PacketType class and StationAPI's registries.

Since packets are short-lived objects, they can't be managed by a registry, thus the PacketType class is created to hold the packet's properties and factory method. This is way more intuitive compared to the current implementation, which has these values scattered all over the system across multiple collections.

All the packet class has to do itself is implement ManagedPacket and return its packet type in the getType() method, which doesn't conflict with Nostalgia mappings.

However, additionally, each packet can also define its type in a static field, giving better encapsulation of the packet's properties and factory method (default constructor can be made private).

Raw IDs

Every packet type requires that it's added to the PacketTypeRegistry before the game finishes initialization. This behavior enables us to take advantage of the registry's raw IDs and remapping capabilities to greatly reduce packet size.

This is achieved by reserving raw ID 0 to the client registry remap packet and with the fact that it's the first custom packet sent between client and server.

However, since packet reading is async, the read thread must be blocked until the remapping is finished. This is achieved with the introduction of the blocking flag in packet types, which forces the read thread to wait until the blocking packet is finished applying.


However, the public API backwards compatibility does break with this new system. Mods that use MessagePacket are fine, however, mods that use IdentifiablePacket will have to switch to ManagedPacket.