From e807fde261fb619719e4c6326469e59e4c841c71 Mon Sep 17 00:00:00 2001 From: Brennan Ward <3682588+Shadows-of-Fire@users.noreply.github.com> Date: Sat, 24 Aug 2024 03:15:35 -0700 Subject: [PATCH] Implement common networking with config tasks --- .../ClientCommonPacketListenerImpl.java.patch | 4 +- .../ServerCommonPacketListenerImpl.java.patch | 4 +- .../network/ConfigurationInitialization.java | 18 +++++-- .../configuration/CommonRegisterTask.java | 37 ++++++++++++++ .../configuration/CommonVersionTask.java | 32 +++++++++++++ .../network/registration/NetworkRegistry.java | 48 ++++++++++--------- 6 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java create mode 100644 src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java diff --git a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch index fa6437a7c7..8bc8fe4f9c 100644 --- a/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/client/multiplayer/ClientCommonPacketListenerImpl.java.patch @@ -36,12 +36,12 @@ + } + + if (p_295727_.payload() instanceof net.neoforged.neoforge.network.payload.CommonVersionPayload commonVersionPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this.getConnection(), commonVersionPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this, commonVersionPayload); + return; + } + + if (p_295727_.payload() instanceof net.neoforged.neoforge.network.payload.CommonRegisterPayload commonRegisterPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this.getConnection(), commonRegisterPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this, commonRegisterPayload); + return; + } + diff --git a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index d289270c98..bc534702f9 100644 --- a/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/patches/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -36,12 +36,12 @@ + } + + if (p_294276_.payload() instanceof net.neoforged.neoforge.network.payload.CommonVersionPayload commonVersionPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this.getConnection(), commonVersionPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.checkCommonVersion(this, commonVersionPayload); + return; + } + + if (p_294276_.payload() instanceof net.neoforged.neoforge.network.payload.CommonRegisterPayload commonRegisterPayload) { -+ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this.getConnection(), commonRegisterPayload); ++ net.neoforged.neoforge.network.registration.NetworkRegistry.onCommonRegister(this, commonRegisterPayload); + return; + } + diff --git a/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java b/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java index c9713d4ed1..2c64664388 100644 --- a/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java +++ b/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java @@ -12,10 +12,14 @@ import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.network.configuration.CheckExtensibleEnums; +import net.neoforged.neoforge.network.configuration.CommonRegisterTask; +import net.neoforged.neoforge.network.configuration.CommonVersionTask; import net.neoforged.neoforge.network.configuration.RegistryDataMapNegotiation; import net.neoforged.neoforge.network.configuration.SyncConfig; import net.neoforged.neoforge.network.configuration.SyncRegistries; import net.neoforged.neoforge.network.event.RegisterConfigurationTasksEvent; +import net.neoforged.neoforge.network.payload.CommonRegisterPayload; +import net.neoforged.neoforge.network.payload.CommonVersionPayload; import net.neoforged.neoforge.network.payload.ConfigFilePayload; import net.neoforged.neoforge.network.payload.FrozenRegistryPayload; import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; @@ -39,12 +43,18 @@ public static void configureEarlyTasks(ServerConfigurationPacketListener listene @SubscribeEvent private static void configureModdedClient(RegisterConfigurationTasksEvent event) { - if (event.getListener().hasChannel(ConfigFilePayload.TYPE)) { - event.register(new SyncConfig(event.getListener())); + ServerConfigurationPacketListener listener = event.getListener(); + if (listener.hasChannel(CommonVersionPayload.TYPE) && listener.hasChannel(CommonRegisterPayload.TYPE)) { + event.register(new CommonVersionTask()); + event.register(new CommonRegisterTask()); + } + + if (listener.hasChannel(ConfigFilePayload.TYPE)) { + event.register(new SyncConfig(listener)); } //These two can always be registered they detect the listener connection type internally and will skip themselves. - event.register(new RegistryDataMapNegotiation(event.getListener())); - event.register(new CheckExtensibleEnums(event.getListener())); + event.register(new RegistryDataMapNegotiation(listener)); + event.register(new CheckExtensibleEnums(listener)); } } diff --git a/src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java b/src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java new file mode 100644 index 0000000000..de0b843bee --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/network/configuration/CommonRegisterTask.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.network.configuration; + +import java.util.function.Consumer; +import net.minecraft.network.ConnectionProtocol; +import net.minecraft.network.protocol.PacketFlow; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; +import net.neoforged.neoforge.network.payload.CommonRegisterPayload; +import net.neoforged.neoforge.network.registration.NetworkRegistry; +import org.jetbrains.annotations.ApiStatus; + +/** + * Common Register configuration task. After completion of {@link CommonVersionTask}, sends a {@link CommonRegisterPayload} to the client + * containing all known serverbound channels, and awaits a response containing the client's known clientbound channels. + */ +@ApiStatus.Internal +public record CommonRegisterTask() implements ICustomConfigurationTask { + public static final Type TYPE = new Type(ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "common_register")); + + @Override + public Type type() { + return TYPE; + } + + @Override + public void run(Consumer sender) { + // There is currently no implementation for a version handshake, and the only existing version is 1, so we only send 1. + // Version negotiation will have to be implemented properly if a version 2 is ever added. + sender.accept(new CommonRegisterPayload(1, ConnectionProtocol.PLAY, NetworkRegistry.getCommonPlayChannels(PacketFlow.SERVERBOUND))); + } +} diff --git a/src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java b/src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java new file mode 100644 index 0000000000..a8f018a1d3 --- /dev/null +++ b/src/main/java/net/neoforged/neoforge/network/configuration/CommonVersionTask.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) NeoForged and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.neoforged.neoforge.network.configuration; + +import java.util.function.Consumer; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; +import net.neoforged.neoforge.network.payload.CommonVersionPayload; +import org.jetbrains.annotations.ApiStatus; + +/** + * Common Version configuration task. Initiated after registry sync to begin the c:register handshake. + * The server will start the task, send c:version to the client, and await a reply. Upon reply, we transition to {@link CommonRegisterTask}. + */ +@ApiStatus.Internal +public record CommonVersionTask() implements ICustomConfigurationTask { + public static final Type TYPE = new Type(ResourceLocation.fromNamespaceAndPath(NeoForgeVersion.MOD_ID, "common_version")); + + @Override + public Type type() { + return TYPE; + } + + @Override + public void run(Consumer sender) { + sender.accept(new CommonVersionPayload()); + } +} diff --git a/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java b/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java index da26d5bb94..899598ef6d 100644 --- a/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java +++ b/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java @@ -48,6 +48,8 @@ import net.neoforged.neoforge.common.extensions.ICommonPacketListener; import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion; import net.neoforged.neoforge.network.configuration.CheckExtensibleEnums; +import net.neoforged.neoforge.network.configuration.CommonRegisterTask; +import net.neoforged.neoforge.network.configuration.CommonVersionTask; import net.neoforged.neoforge.network.connection.ConnectionType; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import net.neoforged.neoforge.network.filters.NetworkFilters; @@ -379,7 +381,6 @@ public static void initializeNeoForgeConnection(ServerConfigurationPacketListene nowListeningOn.addAll(getInitialListeningChannels(listener.flow())); nowListeningOn.addAll(setup.getChannels(ConnectionProtocol.CONFIGURATION).keySet()); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); } /** @@ -419,7 +420,6 @@ public static boolean initializeOtherConnection(ServerConfigurationPacketListene .filter(registration -> registration.getValue().optional()) .forEach(registration -> nowListeningOn.add(registration.getKey())); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); return true; } @@ -516,7 +516,6 @@ public static void initializeNeoForgeConnection(ClientConfigurationPacketListene nowListeningOn.addAll(getInitialListeningChannels(listener.flow())); nowListeningOn.addAll(setup.getChannels(ConnectionProtocol.CONFIGURATION).keySet()); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); } /** @@ -569,7 +568,6 @@ public static void initializeOtherConnection(ClientConfigurationPacketListener l .filter(registration -> registration.getValue().optional()) .forEach(registration -> nowListeningOn.add(registration.getKey())); listener.send(new MinecraftRegisterPayload(nowListeningOn.build())); - sendCommonPayloads(listener); } /** @@ -724,14 +722,22 @@ public static Set getInitialServerUnregisterChannels() { *

* Invoked on the network thread. * - * @param connection The current connection. - * @param payload The incoming version payload. + * @param listener The receiving listener. + * @param payload The incoming version payload. */ - public static void checkCommonVersion(Connection connection, CommonVersionPayload payload) { + public static void checkCommonVersion(ICommonPacketListener listener, CommonVersionPayload payload) { List otherVersions = payload.versions(); if (otherVersions.stream().noneMatch(SUPPORTED_COMMON_NETWORKING_VERSIONS::contains)) { String versions = String.join(", ", SUPPORTED_COMMON_NETWORKING_VERSIONS.stream().map(i -> i.toString()).toList()); - connection.disconnect(Component.literal("Unsupported common network version. This installation of NeoForge only supports: " + versions)); + listener.disconnect(Component.literal("Unsupported common network version. This installation of NeoForge only supports: " + versions)); + } + + if (listener.protocol() == ConnectionProtocol.CONFIGURATION) { + if (listener.flow() == PacketFlow.SERVERBOUND) { + ((ServerConfigurationPacketListener) listener).finishCurrentTask(CommonVersionTask.TYPE); + } else { + listener.send(new CommonVersionPayload()); + } } } @@ -740,13 +746,21 @@ public static void checkCommonVersion(Connection connection, CommonVersionPayloa *

* Invoked on the network thread. * - * @param connection The connection to add the channels to. - * @param payload The incoming register payload. + * @param listener The receiving listener. + * @param payload The incoming register payload. */ - public static void onCommonRegister(Connection connection, CommonRegisterPayload payload) { - Set channels = ChannelAttributes.getOrCreateCommonChannels(connection, payload.protocol()); + public static void onCommonRegister(ICommonPacketListener listener, CommonRegisterPayload payload) { + Set channels = ChannelAttributes.getOrCreateCommonChannels(listener.getConnection(), payload.protocol()); channels.clear(); channels.addAll(payload.channels()); + + if (listener.protocol() == ConnectionProtocol.CONFIGURATION) { + if (listener.flow() == PacketFlow.SERVERBOUND) { + ((ServerConfigurationPacketListener) listener).finishCurrentTask(CommonRegisterTask.TYPE); + } else { + listener.send(new CommonRegisterPayload(1, ConnectionProtocol.PLAY, getCommonPlayChannels(PacketFlow.CLIENTBOUND))); + } + } } public static Set getCommonPlayChannels(PacketFlow flow) { @@ -758,16 +772,6 @@ public static Set getCommonPlayChannels(PacketFlow flow) { .collect(Collectors.toSet()); } - public static void sendCommonPayloads(ICommonPacketListener listener) { - if (listener.hasChannel(CommonVersionPayload.ID)) { - listener.send(new CommonVersionPayload()); - } - - if (listener.hasChannel(CommonRegisterPayload.ID)) { - listener.send(new CommonRegisterPayload(1, ConnectionProtocol.PLAY, getCommonPlayChannels(listener.flow()))); - } - } - /** * Invoked when the configuration phase of a connection is completed. *