Fix networking v1 ()

* Handle registration of global handlers as early as possible.

This may not be correct?

* Do not handle packets on game thread

* Add PLAY_READY event

* READY -> JOIN, some javadoc clarifications and impl oversight fixes

* Omit redundant PLAY and LOGIN prefixes in events

* Checkstyle go brr
This commit is contained in:
i509VCB 2020-12-08 11:55:19 -06:00 committed by GitHub
parent 3775d21f76
commit 33708c72c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 165 additions and 105 deletions

View file

@ -18,6 +18,7 @@ package net.fabricmc.fabric.api.client.networking.v1;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientLoginNetworkHandler;
import net.minecraft.util.Identifier;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@ -30,14 +31,14 @@ import net.fabricmc.fabric.api.event.EventFactory;
@Environment(EnvType.CLIENT)
public final class ClientLoginConnectionEvents {
/**
* An event for when the client's login process has begun.
* Event indicating a connection entered the LOGIN state, ready for registering query request handlers.
* This event may be used by mods to prepare their client side state.
* This event does not guarantee that a login attempt will be successful.
*
* <p>No packets should be sent when this event is invoked.
* @see ClientLoginNetworking#registerReceiver(Identifier, ClientLoginNetworking.LoginQueryRequestHandler)
*/
public static final Event<LoginInit> LOGIN_INIT = EventFactory.createArrayBacked(LoginInit.class, callbacks -> (handler, client) -> {
for (LoginInit callback : callbacks) {
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, client) -> {
for (Init callback : callbacks) {
callback.onLoginStart(handler, client);
}
});
@ -56,8 +57,8 @@ public final class ClientLoginConnectionEvents {
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<LoginQueryStart> LOGIN_QUERY_START = EventFactory.createArrayBacked(LoginQueryStart.class, callbacks -> (handler, client) -> {
for (LoginQueryStart callback : callbacks) {
public static final Event<QueryStart> QUERY_START = EventFactory.createArrayBacked(QueryStart.class, callbacks -> (handler, client) -> {
for (QueryStart callback : callbacks) {
callback.onLoginQueryStart(handler, client);
}
});
@ -67,8 +68,8 @@ public final class ClientLoginConnectionEvents {
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<LoginDisconnect> LOGIN_DISCONNECT = EventFactory.createArrayBacked(LoginDisconnect.class, callbacks -> (handler, client) -> {
for (LoginDisconnect callback : callbacks) {
public static final Event<Disconnect> DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, client) -> {
for (Disconnect callback : callbacks) {
callback.onLoginDisconnect(handler, client);
}
});
@ -77,29 +78,29 @@ public final class ClientLoginConnectionEvents {
}
/**
* @see ClientLoginConnectionEvents#LOGIN_INIT
* @see ClientLoginConnectionEvents#INIT
*/
@Environment(EnvType.CLIENT)
@FunctionalInterface
public interface LoginInit {
public interface Init {
void onLoginStart(ClientLoginNetworkHandler handler, MinecraftClient client);
}
/**
* @see ClientLoginConnectionEvents#LOGIN_QUERY_START
* @see ClientLoginConnectionEvents#QUERY_START
*/
@Environment(EnvType.CLIENT)
@FunctionalInterface
public interface LoginQueryStart {
public interface QueryStart {
void onLoginQueryStart(ClientLoginNetworkHandler handler, MinecraftClient client);
}
/**
* @see ClientLoginConnectionEvents#LOGIN_DISCONNECT
* @see ClientLoginConnectionEvents#DISCONNECT
*/
@Environment(EnvType.CLIENT)
@FunctionalInterface
public interface LoginDisconnect {
public interface Disconnect {
void onLoginDisconnect(ClientLoginNetworkHandler handler, MinecraftClient client);
}
}

View file

@ -51,7 +51,7 @@ public final class ClientLoginNetworking {
* A global receiver is registered to all connections, in the present and future.
*
* <p>If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterGlobalReceiver(Identifier)} to unregister the existing handler.</p>
* Use {@link #unregisterGlobalReceiver(Identifier)} to unregister the existing handler.
*
* @param channelName the id of the channel
* @param queryHandler the handler
@ -67,7 +67,7 @@ public final class ClientLoginNetworking {
* Removes the handler of a query request channel.
* A global receiver is registered to all connections, in the present and future.
*
* <p>The {@code channel} is guaranteed not to have a handler after this call.</p>
* <p>The {@code channel} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel
@ -93,7 +93,7 @@ public final class ClientLoginNetworking {
* Registers a handler to a query request channel.
*
* <p>If a handler is already registered to the {@code channelName}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterReceiver(Identifier)} to unregister the existing handler.</p>
* Use {@link #unregisterReceiver(Identifier)} to unregister the existing handler.
*
* @param channelName the id of the channel
* @param queryHandler the handler
@ -117,7 +117,7 @@ public final class ClientLoginNetworking {
/**
* Removes the handler of a query request channel.
*
* <p>The {@code channelName} is guaranteed not to have a handler after this call.</p>
* <p>The {@code channelName} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel name

View file

@ -18,6 +18,7 @@ package net.fabricmc.fabric.api.client.networking.v1;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.util.Identifier;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@ -31,13 +32,25 @@ import net.fabricmc.fabric.api.networking.v1.PacketSender;
@Environment(EnvType.CLIENT)
public final class ClientPlayConnectionEvents {
/**
* An event for the initialization of the client play network handler.
* Event indicating a connection entered the PLAY state, ready for registering channel handlers.
*
* @see ClientPlayNetworking#registerReceiver(Identifier, ClientPlayNetworking.PlayChannelHandler)
*/
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, client) -> {
for (Init callback : callbacks) {
callback.onPlayInit(handler, client);
}
});
/**
* An event for notification when the client play network handler is ready to send packets to the server.
*
* <p>At this stage, the network handler is ready to send packets to the server.
* Since the client's local state has been setup.
*/
public static final Event<PlayInit> PLAY_INIT = EventFactory.createArrayBacked(PlayInit.class, callbacks -> (handler, sender, client) -> {
for (PlayInit callback : callbacks) {
callback.onPlayInit(handler, sender, client);
public static final Event<Join> JOIN = EventFactory.createArrayBacked(Join.class, callbacks -> (handler, sender, client) -> {
for (Join callback : callbacks) {
callback.onPlayReady(handler, sender, client);
}
});
@ -46,8 +59,8 @@ public final class ClientPlayConnectionEvents {
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<PlayDisconnect> PLAY_DISCONNECT = EventFactory.createArrayBacked(PlayDisconnect.class, callbacks -> (handler, client) -> {
for (PlayDisconnect callback : callbacks) {
public static final Event<Disconnect> DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, client) -> {
for (Disconnect callback : callbacks) {
callback.onPlayDisconnect(handler, client);
}
});
@ -57,13 +70,19 @@ public final class ClientPlayConnectionEvents {
@Environment(EnvType.CLIENT)
@FunctionalInterface
public interface PlayInit {
void onPlayInit(ClientPlayNetworkHandler handler, PacketSender sender, MinecraftClient client);
public interface Init {
void onPlayInit(ClientPlayNetworkHandler handler, MinecraftClient client);
}
@Environment(EnvType.CLIENT)
@FunctionalInterface
public interface PlayDisconnect {
public interface Join {
void onPlayReady(ClientPlayNetworkHandler handler, PacketSender sender, MinecraftClient client);
}
@Environment(EnvType.CLIENT)
@FunctionalInterface
public interface Disconnect {
void onPlayDisconnect(ClientPlayNetworkHandler handler, MinecraftClient client);
}
}

View file

@ -51,7 +51,7 @@ public final class ClientPlayNetworking {
* A global receiver is registered to all connections, in the present and future.
*
* <p>If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterGlobalReceiver(Identifier)} to unregister the existing handler.</p>
* Use {@link #unregisterGlobalReceiver(Identifier)} to unregister the existing handler.
*
* @param channelName the id of the channel
* @param channelHandler the handler
@ -67,7 +67,7 @@ public final class ClientPlayNetworking {
* Removes the handler of a channel.
* A global receiver is registered to all connections, in the present and future.
*
* <p>The {@code channel} is guaranteed not to have a handler after this call.</p>
* <p>The {@code channel} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel
@ -93,11 +93,15 @@ public final class ClientPlayNetworking {
* Registers a handler to a channel.
*
* <p>If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterReceiver(Identifier)} to unregister the existing handler.</p>
* Use {@link #unregisterReceiver(Identifier)} to unregister the existing handler.
*
* <p>For example, if you only register a receiver using this method when a {@linkplain ClientLoginNetworking#registerGlobalReceiver(Identifier, ClientLoginNetworking.LoginQueryRequestHandler)}
* login query has been received, you should use {@link ClientPlayConnectionEvents#INIT} to register the channel handler.
*
* @param channelName the id of the channel
* @return false if a handler is already registered to the channel
* @throws IllegalStateException if the client is not connected to a server
* @see ClientPlayConnectionEvents#INIT
*/
public static boolean registerReceiver(Identifier channelName, PlayChannelHandler channelHandler) {
if (MinecraftClient.getInstance().getNetworkHandler() != null) {
@ -110,7 +114,7 @@ public final class ClientPlayNetworking {
/**
* Removes the handler of a channel.
*
* <p>The {@code channel} is guaranteed not to have a handler after this call.</p>
* <p>The {@code channelName} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel
@ -157,15 +161,15 @@ public final class ClientPlayNetworking {
* Checks if the connected server declared the ability to receive a packet on a specified channel name.
*
* @param channelName the channel name
* @return True if the connected server has declared the ability to receive a packet on the specified channel
* @throws IllegalStateException if the client is not connected to a server
* @return True if the connected server has declared the ability to receive a packet on the specified channel.
* False if the client is not in game.
*/
public static boolean canSend(Identifier channelName) throws IllegalArgumentException {
if (MinecraftClient.getInstance().getNetworkHandler() != null) {
return ClientNetworkingImpl.getAddon(MinecraftClient.getInstance().getNetworkHandler()).getSendableChannels().contains(channelName);
}
throw new IllegalStateException("Cannot check whether the server can receive a packet while not in game!");
return false;
}
/**

View file

@ -28,14 +28,12 @@ import net.fabricmc.fabric.api.event.EventFactory;
*/
public final class ServerLoginConnectionEvents {
/**
* An event for the initialization of the server login network handler.
* This event may be used to register {@link ServerLoginNetworking.LoginQueryResponseHandler login query response handlers}
* using {@link ServerLoginNetworking#registerReceiver(ServerLoginNetworkHandler, Identifier, ServerLoginNetworking.LoginQueryResponseHandler)}.
* Event indicating a connection entered the LOGIN state, ready for registering query response handlers.
*
* <p>No packets should be sent when this event is invoked.
* @see ServerLoginNetworking#registerReceiver(ServerLoginNetworkHandler, Identifier, ServerLoginNetworking.LoginQueryResponseHandler)
*/
public static final Event<LoginInit> LOGIN_INIT = EventFactory.createArrayBacked(LoginInit.class, callbacks -> (handler, server) -> {
for (LoginInit callback : callbacks) {
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, server) -> {
for (Init callback : callbacks) {
callback.onLoginInit(handler, server);
}
});
@ -48,8 +46,8 @@ public final class ServerLoginConnectionEvents {
*
* <p>You may send login queries to the connected client using the provided {@link PacketSender}.
*/
public static final Event<LoginQueryStart> LOGIN_QUERY_START = EventFactory.createArrayBacked(LoginQueryStart.class, callbacks -> (handler, server, sender, synchronizer) -> {
for (LoginQueryStart callback : callbacks) {
public static final Event<QueryStart> QUERY_START = EventFactory.createArrayBacked(QueryStart.class, callbacks -> (handler, server, sender, synchronizer) -> {
for (QueryStart callback : callbacks) {
callback.onLoginStart(handler, server, sender, synchronizer);
}
});
@ -59,8 +57,8 @@ public final class ServerLoginConnectionEvents {
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<LoginDisconnect> LOGIN_DISCONNECT = EventFactory.createArrayBacked(LoginDisconnect.class, callbacks -> (handler, server) -> {
for (LoginDisconnect callback : callbacks) {
public static final Event<Disconnect> DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, server) -> {
for (Disconnect callback : callbacks) {
callback.onLoginDisconnect(handler, server);
}
});
@ -69,26 +67,26 @@ public final class ServerLoginConnectionEvents {
}
/**
* @see ServerLoginConnectionEvents#LOGIN_INIT
* @see ServerLoginConnectionEvents#INIT
*/
@FunctionalInterface
public interface LoginInit {
public interface Init {
void onLoginInit(ServerLoginNetworkHandler handler, MinecraftServer server);
}
/**
* @see ServerLoginConnectionEvents#LOGIN_QUERY_START
* @see ServerLoginConnectionEvents#QUERY_START
*/
@FunctionalInterface
public interface LoginQueryStart {
public interface QueryStart {
void onLoginStart(ServerLoginNetworkHandler handler, MinecraftServer server, PacketSender sender, ServerLoginNetworking.LoginSynchronizer synchronizer);
}
/**
* @see ServerLoginConnectionEvents#LOGIN_DISCONNECT
* @see ServerLoginConnectionEvents#DISCONNECT
*/
@FunctionalInterface
public interface LoginDisconnect {
public interface Disconnect {
void onLoginDisconnect(ServerLoginNetworkHandler handler, MinecraftServer server);
}
}

View file

@ -88,7 +88,7 @@ public final class ServerLoginNetworking {
* Registers a handler to a query response channel.
*
* <p>If a handler is already registered to the {@code channelName}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterReceiver(ServerLoginNetworkHandler, Identifier)} to unregister the existing handler.</p>
* Use {@link #unregisterReceiver(ServerLoginNetworkHandler, Identifier)} to unregister the existing handler.
*
* @param networkHandler the handler
* @param channelName the id of the channel
@ -104,7 +104,7 @@ public final class ServerLoginNetworking {
/**
* Removes the handler of a query response channel.
*
* <p>The {@code channelName} is guaranteed not to have a handler after this call.</p>
* <p>The {@code channelName} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel name

View file

@ -18,6 +18,7 @@ package net.fabricmc.fabric.api.networking.v1;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
@ -27,23 +28,34 @@ import net.fabricmc.fabric.api.event.EventFactory;
*/
public final class ServerPlayConnectionEvents {
/**
* An event for the initialization of the server play network handler.
* Event indicating a connection entered the PLAY state, ready for registering channel handlers.
*
* @see ServerPlayNetworking#registerReceiver(ServerPlayNetworkHandler, Identifier, ServerPlayNetworking.PlayChannelHandler)
*/
public static final Event<Init> INIT = EventFactory.createArrayBacked(Init.class, callbacks -> (handler, server) -> {
for (Init callback : callbacks) {
callback.onPlayInit(handler, server);
}
});
/**
* An event for notification when the server play network handler is ready to send packets to the client.
*
* <p>At this stage, the network handler is ready to send packets to the client.
*/
public static final Event<PlayInit> PLAY_INIT = EventFactory.createArrayBacked(PlayInit.class, callbacks -> (handler, sender, server) -> {
for (PlayInit callback : callbacks) {
callback.onPlayInit(handler, sender, server);
public static final Event<Join> JOIN = EventFactory.createArrayBacked(Join.class, callbacks -> (handler, sender, server) -> {
for (Join callback : callbacks) {
callback.onPlayReady(handler, sender, server);
}
});
/**
* An event for the disconnection of the server play network handler.
*
* <p>No packets should be sent when this event is invoked.</p>
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<PlayDisconnect> PLAY_DISCONNECT = EventFactory.createArrayBacked(PlayDisconnect.class, callbacks -> (handler, server) -> {
for (PlayDisconnect callback : callbacks) {
public static final Event<Disconnect> DISCONNECT = EventFactory.createArrayBacked(Disconnect.class, callbacks -> (handler, server) -> {
for (Disconnect callback : callbacks) {
callback.onPlayDisconnect(handler, server);
}
});
@ -52,12 +64,17 @@ public final class ServerPlayConnectionEvents {
}
@FunctionalInterface
public interface PlayInit {
void onPlayInit(ServerPlayNetworkHandler handler, PacketSender sender, MinecraftServer server);
public interface Init {
void onPlayInit(ServerPlayNetworkHandler handler, MinecraftServer server);
}
@FunctionalInterface
public interface PlayDisconnect {
public interface Join {
void onPlayReady(ServerPlayNetworkHandler handler, PacketSender sender, MinecraftServer server);
}
@FunctionalInterface
public interface Disconnect {
void onPlayDisconnect(ServerPlayNetworkHandler handler, MinecraftServer server);
}
}

View file

@ -48,7 +48,7 @@ public final class ServerPlayNetworking {
* A global receiver is registered to all connections, in the present and future.
*
* <p>If a handler is already registered to the {@code channel}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterReceiver(ServerPlayNetworkHandler, Identifier)} to unregister the existing handler.</p>
* Use {@link #unregisterReceiver(ServerPlayNetworkHandler, Identifier)} to unregister the existing handler.
*
* @param channelName the id of the channel
* @param channelHandler the handler
@ -64,7 +64,7 @@ public final class ServerPlayNetworking {
* Removes the handler of a channel.
* A global receiver is registered to all connections, in the present and future.
*
* <p>The {@code channel} is guaranteed not to have a handler after this call.</p>
* <p>The {@code channel} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel
@ -88,14 +88,20 @@ public final class ServerPlayNetworking {
/**
* Registers a handler to a channel.
* This method differs from {@link ServerPlayNetworking#registerGlobalReceiver(Identifier, PlayChannelHandler)} since
* the channel handler will only be applied to the player represented by the {@link ServerPlayNetworkHandler}.
*
* <p>For example, if you only register a receiver using this method when a {@linkplain ServerLoginNetworking#registerGlobalReceiver(Identifier, ServerLoginNetworking.LoginQueryResponseHandler)}
* login response has been received, you should use {@link ServerPlayConnectionEvents#INIT} to register the channel handler.
*
* <p>If a handler is already registered to the {@code channelName}, this method will return {@code false}, and no change will be made.
* Use {@link #unregisterReceiver(ServerPlayNetworkHandler, Identifier)} to unregister the existing handler.</p>
* Use {@link #unregisterReceiver(ServerPlayNetworkHandler, Identifier)} to unregister the existing handler.
*
* @param networkHandler the handler
* @param channelName the id of the channel
* @param channelHandler the handler
* @return false if a handler is already registered to the channel name
* @see ServerPlayConnectionEvents#INIT
*/
public static boolean registerReceiver(ServerPlayNetworkHandler networkHandler, Identifier channelName, PlayChannelHandler channelHandler) {
Objects.requireNonNull(networkHandler, "Network handler cannot be null");
@ -106,7 +112,7 @@ public final class ServerPlayNetworking {
/**
* Removes the handler of a channel.
*
* <p>The {@code channelName} is guaranteed not to have a handler after this call.</p>
* <p>The {@code channelName} is guaranteed not to have a handler after this call.
*
* @param channelName the id of the channel
* @return the previous handler, or {@code null} if no handler was bound to the channel name

View file

@ -106,7 +106,7 @@ public abstract class AbstractChanneledNetworkAddon<H> extends AbstractNetworkAd
protected abstract void receive(H handler, PacketByteBuf buf);
public void sendChannelRegistrationPacket() {
protected void sendInitialChannelRegistrationPacket() {
final PacketByteBuf buf = this.createRegistrationPacket(this.receiver.getChannels());
if (buf != null) {

View file

@ -50,7 +50,7 @@ public final class NetworkingImpl {
public static void init() {
// Login setup
ServerLoginConnectionEvents.LOGIN_QUERY_START.register((handler, server, sender, synchronizer) -> {
ServerLoginConnectionEvents.QUERY_START.register((handler, server, sender, synchronizer) -> {
// Send early registration packet
PacketByteBuf buf = PacketByteBufs.create();
Collection<Identifier> channelsNames = ServerPlayNetworking.getGlobalReceivers();

View file

@ -52,7 +52,7 @@ public final class ClientLoginNetworkAddon extends AbstractNetworkAddon<ClientLo
this.handler = handler;
this.client = client;
ClientLoginConnectionEvents.LOGIN_INIT.invoker().onLoginStart(this.handler, this.client);
ClientLoginConnectionEvents.INIT.invoker().onLoginStart(this.handler, this.client);
this.receiver.startSession(this);
}
@ -70,7 +70,7 @@ public final class ClientLoginNetworkAddon extends AbstractNetworkAddon<ClientLo
ClientLoginNetworking.registerReceiver(entry.getKey(), entry.getValue());
}
ClientLoginConnectionEvents.LOGIN_QUERY_START.invoker().onLoginQueryStart(this.handler, this.client);
ClientLoginConnectionEvents.QUERY_START.invoker().onLoginQueryStart(this.handler, this.client);
this.firstResponse = false;
}
@ -113,7 +113,7 @@ public final class ClientLoginNetworkAddon extends AbstractNetworkAddon<ClientLo
@Override
public void invokeDisconnectEvent() {
ClientLoginConnectionEvents.LOGIN_DISCONNECT.invoker().onLoginDisconnect(this.handler, this.client);
ClientLoginConnectionEvents.DISCONNECT.invoker().onLoginDisconnect(this.handler, this.client);
this.receiver.endSession(this);
}

View file

@ -40,7 +40,7 @@ import net.fabricmc.fabric.impl.networking.NetworkingImpl;
public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<ClientPlayNetworking.PlayChannelHandler> {
private final ClientPlayNetworkHandler handler;
private final MinecraftClient client;
private boolean canSendPackets;
private boolean sentInitialRegisterPacket;
public ClientPlayNetworkAddon(ClientPlayNetworkHandler handler, MinecraftClient client) {
super(ClientNetworkingImpl.PLAY, handler.getConnection(), "ClientPlayNetworkAddon for " + handler.getProfile().getName());
@ -49,21 +49,23 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
// Must register pending channels via lateinit
this.registerPendingChannels((ChannelInfoHolder) this.connection);
}
// also expose sendRegistration
// Register global receivers and attach to session
this.receiver.startSession(this);
public void onServerReady() {
// Register global receivers
for (Map.Entry<Identifier, ClientPlayNetworking.PlayChannelHandler> entry : ClientNetworkingImpl.PLAY.getHandlers().entrySet()) {
for (Map.Entry<Identifier, ClientPlayNetworking.PlayChannelHandler> entry : this.receiver.getHandlers().entrySet()) {
this.registerChannel(entry.getKey(), entry.getValue());
}
this.sendChannelRegistrationPacket();
this.canSendPackets = true;
ClientPlayConnectionEvents.INIT.invoker().onPlayInit(handler, this.client);
}
ClientPlayConnectionEvents.PLAY_INIT.invoker().onPlayInit(this.handler, this, this.client);
this.receiver.startSession(this);
public void onServerReady() {
ClientPlayConnectionEvents.JOIN.invoker().onPlayReady(this.handler, this, this.client);
// The client cannot send any packets, including `minecraft:register` until after GameJoinS2CPacket is received.
this.sendInitialChannelRegistrationPacket();
this.sentInitialRegisterPacket = true;
}
/**
@ -73,6 +75,11 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
* @return true if the packet has been handled
*/
public boolean handle(CustomPayloadS2CPacket packet) {
// Do not handle the packet on game thread
if (this.client.isOnThread()) {
return false;
}
PacketByteBuf buf = packet.getData();
try {
@ -112,7 +119,7 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
@Override
protected void handleRegistration(Identifier channelName) {
// If we can already send packets, immediately send the register packet for this channel
if (this.canSendPackets) {
if (this.sentInitialRegisterPacket) {
final PacketByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName));
if (buf != null) {
@ -124,7 +131,7 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
@Override
protected void handleUnregistration(Identifier channelName) {
// If we can already send packets, immediately send the unregister packet for this channel
if (this.canSendPackets) {
if (this.sentInitialRegisterPacket) {
final PacketByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName));
if (buf != null) {
@ -135,7 +142,7 @@ public final class ClientPlayNetworkAddon extends AbstractChanneledNetworkAddon<
@Override
public void invokeDisconnectEvent() {
ClientPlayConnectionEvents.PLAY_DISCONNECT.invoker().onPlayDisconnect(this.handler, this.client);
ClientPlayConnectionEvents.DISCONNECT.invoker().onPlayDisconnect(this.handler, this.client);
this.receiver.endSession(this);
}

View file

@ -64,7 +64,7 @@ public final class ServerLoginNetworkAddon extends AbstractNetworkAddon<ServerLo
this.server = ((ServerLoginNetworkHandlerAccessor) handler).getServer();
this.queryIdFactory = QueryIdFactory.create();
ServerLoginConnectionEvents.LOGIN_INIT.invoker().onLoginInit(handler, this.server);
ServerLoginConnectionEvents.INIT.invoker().onLoginInit(handler, this.server);
this.receiver.startSession(this);
}
@ -79,7 +79,7 @@ public final class ServerLoginNetworkAddon extends AbstractNetworkAddon<ServerLo
ServerLoginNetworking.registerReceiver(this.handler, entry.getKey(), entry.getValue());
}
ServerLoginConnectionEvents.LOGIN_QUERY_START.invoker().onLoginStart(this.handler, this.server, this, this.waits::add);
ServerLoginConnectionEvents.QUERY_START.invoker().onLoginStart(this.handler, this.server, this, this.waits::add);
this.firstQueryTick = false;
}
@ -200,7 +200,7 @@ public final class ServerLoginNetworkAddon extends AbstractNetworkAddon<ServerLo
@Override
public void invokeDisconnectEvent() {
ServerLoginConnectionEvents.LOGIN_DISCONNECT.invoker().onLoginDisconnect(this.handler, this.server);
ServerLoginConnectionEvents.DISCONNECT.invoker().onLoginDisconnect(this.handler, this.server);
this.receiver.endSession(this);
}

View file

@ -38,7 +38,7 @@ import net.fabricmc.fabric.mixin.networking.accessor.CustomPayloadC2SPacketAcces
public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<ServerPlayNetworking.PlayChannelHandler> {
private final ServerPlayNetworkHandler handler;
private final MinecraftServer server;
private boolean canSendPackets = false;
private boolean sentInitialRegisterPacket;
public ServerPlayNetworkAddon(ServerPlayNetworkHandler handler, MinecraftServer server) {
super(ServerNetworkingImpl.PLAY, handler.getConnection(), "ServerPlayNetworkAddon for " + handler.player.getEntityName());
@ -47,19 +47,22 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<
// Must register pending channels via lateinit
this.registerPendingChannels((ChannelInfoHolder) this.connection);
}
public void onClientReady() {
// Register global receivers
for (Map.Entry<Identifier, ServerPlayNetworking.PlayChannelHandler> entry : ServerNetworkingImpl.PLAY.getHandlers().entrySet()) {
// Register global receivers and attach to session
this.receiver.startSession(this);
for (Map.Entry<Identifier, ServerPlayNetworking.PlayChannelHandler> entry : this.receiver.getHandlers().entrySet()) {
this.registerChannel(entry.getKey(), entry.getValue());
}
this.sendChannelRegistrationPacket();
this.canSendPackets = true;
ServerPlayConnectionEvents.INIT.invoker().onPlayInit(this.handler, this.server);
}
ServerPlayConnectionEvents.PLAY_INIT.invoker().onPlayInit(this.handler, this, this.server);
this.receiver.startSession(this);
public void onClientReady() {
ServerPlayConnectionEvents.JOIN.invoker().onPlayReady(this.handler, this, this.server);
this.sendInitialChannelRegistrationPacket();
this.sentInitialRegisterPacket = true;
}
/**
@ -69,6 +72,11 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<
* @return true if the packet has been handled
*/
public boolean handle(CustomPayloadC2SPacket packet) {
// Do not handle the packet on game thread
if (this.server.isOnThread()) {
return false;
}
CustomPayloadC2SPacketAccessor access = (CustomPayloadC2SPacketAccessor) packet;
return this.handle(access.getChannel(), access.getData());
}
@ -103,7 +111,7 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<
@Override
protected void handleRegistration(Identifier channelName) {
// If we can already send packets, immediately send the register packet for this channel
if (this.canSendPackets) {
if (this.sentInitialRegisterPacket) {
final PacketByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName));
if (buf != null) {
@ -115,7 +123,7 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<
@Override
protected void handleUnregistration(Identifier channelName) {
// If we can already send packets, immediately send the unregister packet for this channel
if (this.canSendPackets) {
if (this.sentInitialRegisterPacket) {
final PacketByteBuf buf = this.createRegistrationPacket(Collections.singleton(channelName));
if (buf != null) {
@ -126,7 +134,7 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<
@Override
public void invokeDisconnectEvent() {
ServerPlayConnectionEvents.PLAY_DISCONNECT.invoker().onPlayDisconnect(this.handler, this.server);
ServerPlayConnectionEvents.DISCONNECT.invoker().onPlayDisconnect(this.handler, this.server);
this.receiver.endSession(this);
}

View file

@ -64,11 +64,11 @@ public final class NetworkingChannelClientTest implements ClientModInitializer {
});
// State destruction on disconnection:
ClientLoginConnectionEvents.LOGIN_DISCONNECT.register((handler, client) -> {
ClientLoginConnectionEvents.DISCONNECT.register((handler, client) -> {
SUPPORTED_C2S_CHANNELS.clear();
});
ClientPlayConnectionEvents.PLAY_DISCONNECT.register((handler, client) -> {
ClientPlayConnectionEvents.DISCONNECT.register((handler, client) -> {
SUPPORTED_C2S_CHANNELS.clear();
});
}

View file

@ -45,7 +45,7 @@ public final class NetworkingKeybindPacketTest implements ModInitializer {
@Override
public void onInitialize() {
ServerPlayConnectionEvents.PLAY_INIT.register((handler, sender, server) -> {
ServerPlayConnectionEvents.INIT.register((handler, server) -> {
ServerPlayNetworking.registerReceiver(handler, KEYBINDING_PACKET_ID, NetworkingKeybindPacketTest::receive);
});
}

View file

@ -36,8 +36,8 @@ public final class NetworkingLoginQueryTest implements ModInitializer {
@Override
public void onInitialize() {
ServerLoginConnectionEvents.LOGIN_QUERY_START.register(this::onLoginStart);
ServerLoginConnectionEvents.LOGIN_QUERY_START.register(this::delaySimply);
ServerLoginConnectionEvents.QUERY_START.register(this::onLoginStart);
ServerLoginConnectionEvents.QUERY_START.register(this::delaySimply);
// login delaying example
ServerLoginNetworking.registerGlobalReceiver(NetworkingPlayPacketTest.TEST_CHANNEL, (server, handler, understood, buf, synchronizer, sender) -> {

View file

@ -31,7 +31,7 @@ public final class NetworkingPlayPacketClientTest implements ClientModInitialize
public void onInitializeClient() {
//ClientPlayNetworking.registerGlobalReceiver(NetworkingPlayPacketTest.TEST_CHANNEL, this::receive);
ClientPlayConnectionEvents.PLAY_INIT.register((handler, sender, client) -> {
ClientPlayConnectionEvents.INIT.register((handler, client) -> {
ClientPlayNetworking.registerReceiver(NetworkingPlayPacketTest.TEST_CHANNEL, (client1, handler1, buf, sender1) -> receive(handler1, sender1, client1, buf));
});
}