From db5e66823d18a24fbb6e17a9b790be351cf5fc30 Mon Sep 17 00:00:00 2001 From: modmuss <modmuss50@gmail.com> Date: Sun, 16 Mar 2025 13:35:17 +0000 Subject: [PATCH] Add ServerPlayNetworking.reconfigure (#4493) * Add ServerPlayNetworking.reconfigure * Add ServerConfigurationNetworking.isReconfiguring, allowing tasks to be skipped if not required again. --- .../v1/ServerConfigurationNetworking.java | 12 ++++++++++ .../networking/v1/ServerPlayNetworking.java | 22 +++++++++++++++++++ .../ServerConfigurationNetworkAddon.java | 9 ++++++++ .../server/ServerPlayNetworkAddon.java | 17 +++++++++++++- .../ServerPlayNetworkHandlerMixin.java | 18 +++++++++++++++ .../NetworkingConfigurationTest.java | 4 ++++ .../play/NetworkingPlayPacketTest.java | 7 +++++- 7 files changed, 87 insertions(+), 2 deletions(-) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerConfigurationNetworking.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerConfigurationNetworking.java index 7f6c36cef..b0c6eb897 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerConfigurationNetworking.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerConfigurationNetworking.java @@ -235,6 +235,18 @@ public final class ServerConfigurationNetworking { return ((ServerCommonNetworkHandlerAccessor) handler).getServer(); } + /** + * Returns true if the client has previously completed configuration, and has re-entered the configuration phase. + * + * @param handler the server configuration network handler + * @return {@code true} if the client is reconfiguring + */ + public static boolean isReconfiguring(ServerConfigurationNetworkHandler handler) { + Objects.requireNonNull(handler, "Server configuration network handler cannot be null"); + + return ServerNetworkingImpl.getAddon(handler).isReconfiguring(); + } + private ServerConfigurationNetworking() { } diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java index 23d415919..fdffa32cf 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/api/networking/v1/ServerPlayNetworking.java @@ -293,6 +293,28 @@ public final class ServerPlayNetworking { player.networkHandler.sendPacket(createS2CPacket(payload)); } + /** + * Put the player back into configuration phase and re-run all of the configuration tasks. + * + * @param player the player + */ + public static void reconfigure(ServerPlayerEntity player) { + Objects.requireNonNull(player, "Server player entity cannot be null"); + + reconfigure(player.networkHandler); + } + + /** + * Put the player back into configuration phase and re-run all of the configuration tasks. + * + * @param handler the network handler + */ + public static void reconfigure(ServerPlayNetworkHandler handler) { + Objects.requireNonNull(handler, "Server play network handler cannot be null"); + + ServerNetworkingImpl.getAddon(handler).reconfigure(); + } + private ServerPlayNetworking() { } diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java index e3179cba0..34b5eb884 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java @@ -49,6 +49,7 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw private RegisterState registerState = RegisterState.NOT_SENT; @Nullable private String clientBrand = null; + private boolean isReconfiguring = false; public ServerConfigurationNetworkAddon(ServerConfigurationNetworkHandler handler, MinecraftServer server) { super(ServerNetworkingImpl.CONFIGURATION, ((ServerCommonNetworkHandlerAccessor) handler).getConnection(), "ServerConfigurationNetworkAddon for " + handler.getDebugProfile().getName()); @@ -188,6 +189,14 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw return clientBrand; } + public boolean isReconfiguring() { + return isReconfiguring; + } + + public void setReconfiguring() { + isReconfiguring = true; + } + private enum RegisterState { NOT_SENT, SENT, diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java index 2406133a0..b8fe3e8a1 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerPlayNetworkAddon.java @@ -41,9 +41,11 @@ import net.fabricmc.fabric.impl.networking.RegistrationPayload; public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon<ServerPlayNetworking.PlayPayloadHandler<?>> { private final ServerPlayNetworkHandler handler; private final MinecraftServer server; - private boolean sentInitialRegisterPacket; private final ServerPlayNetworking.Context context; + private boolean sentInitialRegisterPacket; + private boolean requestedReconfigure = false; + public ServerPlayNetworkAddon(ServerPlayNetworkHandler handler, ClientConnection connection, MinecraftServer server) { super(ServerNetworkingImpl.PLAY, connection, "ServerPlayNetworkAddon for " + handler.player.getDisplayName()); this.handler = handler; @@ -129,6 +131,19 @@ public final class ServerPlayNetworkAddon extends AbstractChanneledNetworkAddon< return NetworkingImpl.isReservedCommonChannel(channelName); } + public void reconfigure() { + if (requestedReconfigure) { + throw new IllegalStateException("Already requested reconfigure"); + } + + requestedReconfigure = true; + handler.reconfigure(); + } + + public boolean requestedReconfigure() { + return requestedReconfigure; + } + private record ContextImpl(MinecraftServer server, ServerPlayNetworkHandler handler, PacketSender responseSender) implements ServerPlayNetworking.Context { private ContextImpl { Objects.requireNonNull(server, "server"); diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java index 7fae773f1..192f527d8 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/ServerPlayNetworkHandlerMixin.java @@ -16,6 +16,8 @@ package net.fabricmc.fabric.mixin.networking; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -23,14 +25,18 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.network.ClientConnection; +import net.minecraft.network.NetworkState; +import net.minecraft.network.listener.PacketListener; import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ConnectedClientData; import net.minecraft.server.network.ServerCommonNetworkHandler; +import net.minecraft.server.network.ServerConfigurationNetworkHandler; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.fabricmc.fabric.impl.networking.NetworkHandlerExtensions; import net.fabricmc.fabric.impl.networking.UntrackedNetworkHandler; +import net.fabricmc.fabric.impl.networking.server.ServerNetworkingImpl; import net.fabricmc.fabric.impl.networking.server.ServerPlayNetworkAddon; // We want to apply a bit earlier than other mods which may not use us in order to prevent refCount issues @@ -60,6 +66,18 @@ abstract class ServerPlayNetworkHandlerMixin extends ServerCommonNetworkHandler } } + @WrapOperation(method = "onAcknowledgeReconfiguration", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;transitionInbound(Lnet/minecraft/network/NetworkState;Lnet/minecraft/network/listener/PacketListener;)V")) + private <T extends PacketListener> void onAcknowledgeReconfiguration(ClientConnection instance, NetworkState<T> state, T packetListener, Operation<Void> original) { + original.call(instance, state, packetListener); + + ServerConfigurationNetworkHandler networkHandler = (ServerConfigurationNetworkHandler) packetListener; + ServerNetworkingImpl.getAddon(networkHandler).setReconfiguring(); + + if (addon.requestedReconfigure()) { + networkHandler.sendConfigurations(); + } + } + @Override public ServerPlayNetworkAddon getAddon() { return this.addon; diff --git a/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/configuration/NetworkingConfigurationTest.java b/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/configuration/NetworkingConfigurationTest.java index f2f331428..f9ed8a09d 100644 --- a/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/configuration/NetworkingConfigurationTest.java +++ b/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/configuration/NetworkingConfigurationTest.java @@ -50,6 +50,10 @@ public class NetworkingConfigurationTest implements ModInitializer { PayloadTypeRegistry.configurationC2S().register(ConfigurationStartPacket.ID, ConfigurationStartPacket.CODEC); ServerConfigurationConnectionEvents.CONFIGURE.register((handler, server) -> { + if (ServerConfigurationNetworking.isReconfiguring(handler)) { + LOGGER.info("Reconfiguring client"); + } + // You must check to see if the client can handle your config task if (ServerConfigurationNetworking.canSend(handler, ConfigurationPacket.ID)) { handler.addTask(new TestConfigurationTask("Example data")); diff --git a/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java b/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java index 3cc4305a0..767a6140e 100644 --- a/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java +++ b/fabric-networking-api-v1/src/testmod/java/net/fabricmc/fabric/test/networking/play/NetworkingPlayPacketTest.java @@ -90,7 +90,12 @@ public final class NetworkingPlayPacketTest implements ModInitializer { )); ServerPlayNetworking.getSender(ctx.getSource().getPlayer()).sendPacket(packet); return Command.SINGLE_SUCCESS; - }))); + })) + .then(literal("reconfigure").executes(ctx -> { + ServerPlayNetworking.reconfigure(ctx.getSource().getPlayer()); + return Command.SINGLE_SUCCESS; + })) + ); } @Override