Skip to content

Conversation

@SpaceWalkerRS
Copy link
Member

@SpaceWalkerRS SpaceWalkerRS commented Sep 1, 2025

This PR rewrites some of the Networking API to make it more uniform. To achieve this, a lot of code was separated out into a networking library with just 5 modules, which contains most of the API. Most of the implementation details have been moved into a smaller networking-impl library, which has a lot more modules as a result.

API Changes

Payload Channels

Where previously, payload channels were represented by Strings in 1.13-pre2 and below and Identifiers in 1.13-pre4 and above, now OSL Core's NamespacedIdentifier is used instead. It is essentially equivalent to Identifier, but it can be used in all Minecraft versions.

All API code now references these "channel identifiers" instead of Strings or Identifiers. To construct a channel identifier, use the helper methods in the ChannelIdentifiers class:

NamespacedIdentifier COOKIE_CHANNEL = ChannelIdentifiers.from("example", "cookie");

Channels should be registered through the ChannelRegistry class:

ChannelRegistry.register(COOKIE_CHANNEL, true, false);

Registering payload listeners and sending payloads now requires passing in a channel identifier:

ClientPlayNetworking.registerListener(COOKIE_CHANNEL, (ctx, data) -> { });
ClientPlayNetworking.send(COOKIE_CHANNEL, data);

Packet Buffers

Where previously, payload reading and writing was done through either the DataInput and DataOutput interfaces or the PacketByteBuf class, OSL now provides its own PacketBuffer. In 13w41a and above, this class is essentially a wrapper around PacketByteBuf, making it a simple drop-in replacement for PacketByteBuf. Mods that target 13w39b and below may require more work to update to this, as it is very different from the DataInput and DataOutput interfaces.

Listener Context

Packet listeners are now given a context object rather than direct access to the game instances and network handlers. These can now be accessed through the context. For example:

(ctx, data) -> {
    Minecraft minecraft = ctx.minecraft();
    ClientPlayNetworkHandler networkHandler = ctx.networkHandler();
}

Async packet handling is now also controlled through this context. Rather separate register and registerAsync methods for registering listeners, all listeners can now be invoked asynchronously by default. To ensure your code is running on the main thread, call ensureOnMainThread on the context:

(ctx, data) -> {
    ctx.ensureOnMainThread();
    // following code is now guaranteed to run on the main thread
}

Internal Changes

Handshakes

The handshake payload now carries a protocol number, which can be updated if changes are made to the handshake process.

Handshakes now also only sync valid channels with valid (i.e. to OSL spec) identifiers. Channels with invalid identifiers are not sent via OSL anyway.

Channel Length Limit

The length limit for String channels has been effectively removed.

Async Packet Handling

Support for asynchronous packet handling has been added to versions prior to 14w21a.

@SpaceWalkerRS
Copy link
Member Author

This is almost done. I just realized there are ambiguities in the methods for registering listeners though...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants