Skip to content

Commit

Permalink
Configuration networking improvements (#3832)
Browse files Browse the repository at this point in the history
* Configuration networking fixes

* Review fixes.

* Update fabric-networking-api-v1/src/testmodClient/java/net/fabricmc/fabric/test/networking/client/configuration/NetworkingConfigurationClientTest.java

Co-authored-by: Octol1ttle <l1ttleofficial@outlook.com>

---------

Co-authored-by: Octol1ttle <l1ttleofficial@outlook.com>
(cherry picked from commit 686dcdc)
  • Loading branch information
modmuss50 committed Jun 8, 2024
1 parent e0fdb01 commit 3cb1a7b
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public final class ClientConfigurationConnectionEvents {
/**
* Event indicating a connection entering the CONFIGURATION state, ready for registering channel handlers.
*
* <p>No packets should be sent when this event is invoked.
*
* @see ClientConfigurationNetworking#registerReceiver(CustomPayload.Id, ClientConfigurationNetworking.ConfigurationPayloadHandler)
*/
public static final Event<ClientConfigurationConnectionEvents.Init> INIT = EventFactory.createArrayBacked(ClientConfigurationConnectionEvents.Init.class, callbacks -> (handler, client) -> {
Expand All @@ -38,14 +40,25 @@ public final class ClientConfigurationConnectionEvents {
}
});

/**
* An event called after the connection has been initialized and is ready to start sending and receiving configuration packets.
*
* <p>Packets may be sent during this event.
*/
public static final Event<ClientConfigurationConnectionEvents.Start> START = EventFactory.createArrayBacked(ClientConfigurationConnectionEvents.Start.class, callbacks -> (handler, client) -> {
for (ClientConfigurationConnectionEvents.Start callback : callbacks) {
callback.onConfigurationStart(handler, client);
}
});

/**
* An event called after the ReadyS2CPacket has been received, just before switching to the PLAY state.
*
* <p>No packets should be sent when this event is invoked.
*/
public static final Event<ClientConfigurationConnectionEvents.Ready> READY = EventFactory.createArrayBacked(ClientConfigurationConnectionEvents.Ready.class, callbacks -> (handler, client) -> {
for (ClientConfigurationConnectionEvents.Ready callback : callbacks) {
callback.onConfigurationReady(handler, client);
public static final Event<ClientConfigurationConnectionEvents.Complete> COMPLETE = EventFactory.createArrayBacked(ClientConfigurationConnectionEvents.Complete.class, callbacks -> (handler, client) -> {
for (ClientConfigurationConnectionEvents.Complete callback : callbacks) {
callback.onConfigurationComplete(handler, client);
}
});

Expand All @@ -69,12 +82,38 @@ public interface Init {
}

@FunctionalInterface
public interface Ready {
void onConfigurationReady(ClientConfigurationNetworkHandler handler, MinecraftClient client);
public interface Start {
void onConfigurationStart(ClientConfigurationNetworkHandler handler, MinecraftClient client);
}

@FunctionalInterface
public interface Complete {
void onConfigurationComplete(ClientConfigurationNetworkHandler handler, MinecraftClient client);
}

@FunctionalInterface
public interface Disconnect {
void onConfigurationDisconnect(ClientConfigurationNetworkHandler handler, MinecraftClient client);
}

// Deprecated:

/**
* @deprecated replaced by {@link #COMPLETE}
*/
@Deprecated
public static final Event<ClientConfigurationConnectionEvents.Ready> READY = EventFactory.createArrayBacked(ClientConfigurationConnectionEvents.Ready.class, callbacks -> (handler, client) -> {
for (ClientConfigurationConnectionEvents.Ready callback : callbacks) {
callback.onConfigurationReady(handler, client);
}
});

/**
* @deprecated replaced by {@link ClientConfigurationConnectionEvents.Complete}
*/
@Deprecated
@FunctionalInterface
public interface Ready {
void onConfigurationReady(ClientConfigurationNetworkHandler handler, MinecraftClient client);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientConfigurationNetworkHandler;
import net.minecraft.network.NetworkPhase;
import net.minecraft.network.packet.BrandCustomPayload;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.Packet;
import net.minecraft.util.Identifier;
Expand All @@ -39,6 +40,7 @@
public final class ClientConfigurationNetworkAddon extends ClientCommonNetworkAddon<ClientConfigurationNetworking.ConfigurationPayloadHandler<?>, ClientConfigurationNetworkHandler> {
private final ContextImpl context;
private boolean sentInitialRegisterPacket;
private boolean hasStarted;

public ClientConfigurationNetworkAddon(ClientConfigurationNetworkHandler handler, MinecraftClient client) {
super(ClientNetworkingImpl.CONFIGURATION, ((ClientCommonNetworkHandlerAccessor) handler).getConnection(), "ClientPlayNetworkAddon for " + ((ClientConfigurationNetworkHandlerAccessor) handler).getProfile().getName(), handler, client);
Expand All @@ -53,13 +55,40 @@ protected void invokeInitEvent() {
ClientConfigurationConnectionEvents.INIT.invoker().onConfigurationInit(this.handler, this.client);
}

@Override
public void onServerReady() {
super.onServerReady();
invokeStartEvent();
}

@Override
protected void receiveRegistration(boolean register, RegistrationPayload payload) {
super.receiveRegistration(register, payload);

if (register && !this.sentInitialRegisterPacket) {
this.sendInitialChannelRegistrationPacket();
this.sentInitialRegisterPacket = true;

this.onServerReady();
}
}

@Override
public boolean handle(CustomPayload payload) {
boolean result = super.handle(payload);

if (payload instanceof BrandCustomPayload) {
// If we have received this without first receiving the registration packet, its likely a vanilla server.
invokeStartEvent();
}

return result;
}

private void invokeStartEvent() {
if (!hasStarted) {
hasStarted = true;
ClientConfigurationConnectionEvents.START.invoker().onConfigurationStart(this.handler, this.client);
}
}

Expand All @@ -84,7 +113,8 @@ protected void invokeUnregisterEvent(List<Identifier> ids) {
C2SConfigurationChannelEvents.UNREGISTER.invoker().onChannelUnregister(this.handler, this, this.client, ids);
}

public void handleReady() {
public void handleComplete() {
ClientConfigurationConnectionEvents.COMPLETE.invoker().onConfigurationComplete(this.handler, this.client);
ClientConfigurationConnectionEvents.READY.invoker().onConfigurationReady(this.handler, this.client);
ClientNetworkingImpl.setClientConfigurationAddon(null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ public static void setClientPlayAddon(ClientPlayNetworkAddon addon) {
}

public static void setClientConfigurationAddon(ClientConfigurationNetworkAddon addon) {
assert addon == null || currentPlayAddon == null;
currentConfigurationAddon = addon;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@

package net.fabricmc.fabric.mixin.networking.client;

import org.slf4j.Logger;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
Expand All @@ -34,10 +31,6 @@

@Mixin(ClientCommonNetworkHandler.class)
public abstract class ClientCommonNetworkHandlerMixin implements NetworkHandlerExtensions {
@Shadow
@Final
private static Logger LOGGER;

@Inject(method = "onCustomPayload(Lnet/minecraft/network/packet/s2c/common/CustomPayloadS2CPacket;)V", at = @At("HEAD"), cancellable = true)
public void onCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) {
final CustomPayload payload = packet.payload();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ private void initAddon(CallbackInfo ci) {
}

@Inject(method = "onReady", at = @At(value = "NEW", target = "(Lnet/minecraft/client/MinecraftClient;Lnet/minecraft/network/ClientConnection;Lnet/minecraft/client/network/ClientConnectionState;)Lnet/minecraft/client/network/ClientPlayNetworkHandler;"))
public void onReady(ReadyS2CPacket packet, CallbackInfo ci) {
this.addon.handleReady();
public void handleComplete(ReadyS2CPacket packet, CallbackInfo ci) {
this.addon.handleComplete();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import net.minecraft.network.packet.s2c.login.LoginQueryRequestS2CPacket;

import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions;
import net.fabricmc.fabric.impl.networking.client.ClientConfigurationNetworkAddon;
import net.fabricmc.fabric.impl.networking.client.ClientLoginNetworkAddon;
import net.fabricmc.fabric.impl.networking.payload.PacketByteBufLoginQueryRequestPayload;

Expand Down Expand Up @@ -65,12 +64,6 @@ private void handleQueryRequest(LoginQueryRequestS2CPacket packet, CallbackInfo
}
}

@Inject(method = "onSuccess", at = @At("TAIL"))
private void handleConfigurationReady(CallbackInfo ci) {
NetworkHandlerExtensions networkHandlerExtensions = (NetworkHandlerExtensions) connection.getPacketListener();
((ClientConfigurationNetworkAddon) networkHandlerExtensions.getAddon()).onServerReady();
}

@Override
public ClientLoginNetworkAddon getAddon() {
return this.addon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@

import java.util.function.Consumer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.Packet;
import net.minecraft.server.command.DebugConfigCommand;
import net.minecraft.server.network.ServerPlayerConfigurationTask;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;

import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationConnectionEvents;
import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking;
Expand All @@ -36,10 +41,13 @@
* Also see NetworkingConfigurationClientTest.
*/
public class NetworkingConfigurationTest implements ModInitializer {
private static final Logger LOGGER = LoggerFactory.getLogger(NetworkingConfigurationTest.class);

@Override
public void onInitialize() {
PayloadTypeRegistry.configurationS2C().register(ConfigurationPacket.ID, ConfigurationPacket.CODEC);
PayloadTypeRegistry.configurationC2S().register(ConfigurationCompletePacket.ID, ConfigurationCompletePacket.CODEC);
PayloadTypeRegistry.configurationC2S().register(ConfigurationStartPacket.ID, ConfigurationStartPacket.CODEC);

ServerConfigurationConnectionEvents.CONFIGURE.register((handler, server) -> {
// You must check to see if the client can handle your config task
Expand All @@ -54,6 +62,13 @@ public void onInitialize() {
ServerConfigurationNetworking.registerGlobalReceiver(ConfigurationCompletePacket.ID, (packet, context) -> {
context.networkHandler().completeTask(TestConfigurationTask.KEY);
});

ServerConfigurationNetworking.registerGlobalReceiver(ConfigurationStartPacket.ID, (packet, context) -> {
LOGGER.info("Received configuration start packet from client");
});

// Enable the vanilla debugconfig command
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> DebugConfigCommand.register(dispatcher));
}

public record TestConfigurationTask(String data) implements ServerPlayerConfigurationTask {
Expand Down Expand Up @@ -102,4 +117,18 @@ public Id<? extends CustomPayload> getId() {
return ID;
}
}

public static class ConfigurationStartPacket implements CustomPayload {
public static final ConfigurationStartPacket INSTANCE = new ConfigurationStartPacket();
public static final CustomPayload.Id<ConfigurationStartPacket> ID = new Id<>(Identifier.of(NetworkingTestmods.ID, "configure_start"));
public static final PacketCodec<PacketByteBuf, ConfigurationStartPacket> CODEC = PacketCodec.unit(INSTANCE);

private ConfigurationStartPacket() {
}

@Override
public Id<? extends CustomPayload> getId() {
return ID;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,17 @@

package net.fabricmc.fabric.test.networking.client.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationConnectionEvents;
import net.fabricmc.fabric.api.client.networking.v1.ClientConfigurationNetworking;
import net.fabricmc.fabric.test.networking.configuration.NetworkingConfigurationTest;

public class NetworkingConfigurationClientTest implements ClientModInitializer {
private static final Logger LOGGER = LoggerFactory.getLogger(NetworkingConfigurationTest.class);

@Override
public void onInitializeClient() {
ClientConfigurationNetworking.registerGlobalReceiver(NetworkingConfigurationTest.ConfigurationPacket.ID, (packet, context) -> {
Expand All @@ -29,5 +35,16 @@ public void onInitializeClient() {
// Respond back to the server that the task is complete
context.responseSender().sendPacket(NetworkingConfigurationTest.ConfigurationCompletePacket.INSTANCE);
});

ClientConfigurationConnectionEvents.START.register((handler, client) -> {
if (!ClientConfigurationNetworking.canSend(NetworkingConfigurationTest.ConfigurationStartPacket.ID)) {
// This isn't fatal as it will happen when connecting to a vanilla server.
LOGGER.warn("Not sending configuration start packet; is this a vanilla server?");
return;
}

LOGGER.info("Sending configuration start packet to server");
ClientConfigurationNetworking.send(NetworkingConfigurationTest.ConfigurationStartPacket.INSTANCE);
});
}
}

0 comments on commit 3cb1a7b

Please sign in to comment.