From eeccd5b3e8eee15d23285d18fc2cdd683466111b Mon Sep 17 00:00:00 2001 From: Moulberry Date: Thu, 21 Nov 2024 02:11:13 +0800 Subject: [PATCH] Packet fixes - disable neoforge splitter and send minecraft:register (#170) * Disable NeoForge packet splitting for Fabric packets * Send minecraft:register for Fabric packets * Remove unused import --- .../client/ClientPlayNetworkHandlerMixin.java | 13 +++++ .../client/NeoClientCommonNetworking.java | 10 ++-- .../client/NeoClientPlayNetworking.java | 7 ++- .../GenericPacketSplitterMixin.java | 48 +++++++++++++++++++ .../server/NeoServerPlayNetworking.java | 7 ++- .../fabric-networking-api-v1.mixins.json | 11 +++-- 6 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/GenericPacketSplitterMixin.java diff --git a/fabric-networking-api-v1/src/client/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java b/fabric-networking-api-v1/src/client/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java index 7878d4afc..dacf8d77e 100644 --- a/fabric-networking-api-v1/src/client/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java +++ b/fabric-networking-api-v1/src/client/java/net/fabricmc/fabric/mixin/networking/client/ClientPlayNetworkHandlerMixin.java @@ -23,22 +23,35 @@ import net.minecraft.client.multiplayer.CommonListenerCookie; import net.minecraft.network.Connection; import net.minecraft.network.protocol.game.ClientboundLoginPacket; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.registration.ChannelAttributes; +import org.sinytra.fabric.networking_api.client.NeoClientCommonNetworking; import org.sinytra.fabric.networking_api.client.NeoClientPlayNetworking; import org.sinytra.fabric.networking_api.NeoListenableNetworkHandler; 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; +import java.util.List; +import java.util.Set; + // We want to apply a bit earlier than other mods which may not use us in order to prevent refCount issues @Mixin(value = ClientPacketListener.class, priority = 999) abstract class ClientPlayNetworkHandlerMixin extends ClientCommonPacketListenerImpl implements NeoListenableNetworkHandler { + @Shadow + public abstract Connection getConnection(); + protected ClientPlayNetworkHandlerMixin(Minecraft client, Connection connection, CommonListenerCookie connectionState) { super(client, connection, connectionState); } @Inject(method = "", at = @At("RETURN")) private void initAddon(CallbackInfo ci) { + Set channels = ChannelAttributes.getOrCreateCommonChannels(this.getConnection(), this.protocol()); + NeoClientCommonNetworking.onRegisterPacket((ClientPacketListener) (Object) this, channels); + NeoClientPlayNetworking.setTempPacketListener((ClientPacketListener) (Object) this); ClientPlayConnectionEvents.INIT.invoker().onPlayInit((ClientPacketListener) (Object) this, this.minecraft); } diff --git a/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientCommonNetworking.java b/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientCommonNetworking.java index ad5171fc0..16a3e736f 100644 --- a/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientCommonNetworking.java +++ b/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientCommonNetworking.java @@ -15,19 +15,21 @@ public class NeoClientCommonNetworking { public static void onRegisterPacket(ICommonPacketListener listener, Set ids) { ConnectionProtocol protocol = listener.protocol(); + List listIds = List.copyOf(ids); if (protocol == ConnectionProtocol.CONFIGURATION) { - listener.getMainThreadEventLoop().execute(() -> C2SConfigurationChannelEvents.REGISTER.invoker().onChannelRegister((ClientConfigurationPacketListenerImpl) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), List.copyOf(ids))); + listener.getMainThreadEventLoop().execute(() -> C2SConfigurationChannelEvents.REGISTER.invoker().onChannelRegister((ClientConfigurationPacketListenerImpl) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), listIds)); } else if (protocol == ConnectionProtocol.PLAY) { - listener.getMainThreadEventLoop().execute(() -> C2SPlayChannelEvents.REGISTER.invoker().onChannelRegister((ClientPacketListener) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), List.copyOf(ids))); + listener.getMainThreadEventLoop().execute(() -> C2SPlayChannelEvents.REGISTER.invoker().onChannelRegister((ClientPacketListener) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), listIds)); } } public static void onUnregisterPacket(ICommonPacketListener listener, Set ids) { ConnectionProtocol protocol = listener.protocol(); + List listIds = List.copyOf(ids); if (protocol == ConnectionProtocol.CONFIGURATION) { - listener.getMainThreadEventLoop().execute(() -> C2SConfigurationChannelEvents.UNREGISTER.invoker().onChannelUnregister((ClientConfigurationPacketListenerImpl) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), List.copyOf(ids))); + listener.getMainThreadEventLoop().execute(() -> C2SConfigurationChannelEvents.UNREGISTER.invoker().onChannelUnregister((ClientConfigurationPacketListenerImpl) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), listIds)); } else if (protocol == ConnectionProtocol.PLAY) { - listener.getMainThreadEventLoop().execute(() -> C2SPlayChannelEvents.UNREGISTER.invoker().onChannelUnregister((ClientPacketListener) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), List.copyOf(ids))); + listener.getMainThreadEventLoop().execute(() -> C2SPlayChannelEvents.UNREGISTER.invoker().onChannelUnregister((ClientPacketListener) listener, new NeoClientPacketSender(listener.getConnection()), Minecraft.getInstance(), listIds)); } } } diff --git a/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientPlayNetworking.java b/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientPlayNetworking.java index 868d37a0c..8205a95d0 100644 --- a/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientPlayNetworking.java +++ b/fabric-networking-api-v1/src/client/java/org/sinytra/fabric/networking_api/client/NeoClientPlayNetworking.java @@ -14,6 +14,7 @@ import net.minecraft.resources.ResourceLocation; import net.neoforged.neoforge.common.extensions.ICommonPacketListener; import net.neoforged.neoforge.network.handling.IPayloadContext; +import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload; import net.neoforged.neoforge.network.registration.NetworkRegistry; import org.jetbrains.annotations.Nullable; import org.sinytra.fabric.networking_api.NeoCommonNetworking; @@ -70,11 +71,15 @@ public static PacketSender getSender() { } public static void onServerReady(ClientPacketListener handler, Minecraft client) { + NeoClientPacketSender packetSender = new NeoClientPacketSender(handler.getConnection()); try { - ClientPlayConnectionEvents.JOIN.invoker().onPlayReady(handler, new NeoClientPacketSender(handler.getConnection()), client); + ClientPlayConnectionEvents.JOIN.invoker().onPlayReady(handler, packetSender, client); } catch (RuntimeException e) { LOGGER.error("Exception thrown while invoking ClientPlayConnectionEvents.JOIN", e); } + + MinecraftRegisterPayload registerPacket = new MinecraftRegisterPayload(NeoCommonNetworking.PLAY_REGISTRY.getGlobalReceivers(PacketFlow.CLIENTBOUND)); + packetSender.sendPacket(registerPacket); } @Nullable diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/GenericPacketSplitterMixin.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/GenericPacketSplitterMixin.java new file mode 100644 index 000000000..2e27c5f8b --- /dev/null +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/mixin/networking/GenericPacketSplitterMixin.java @@ -0,0 +1,48 @@ +package net.fabricmc.fabric.mixin.networking; + +import io.netty.channel.ChannelHandlerContext; +import net.minecraft.network.HandlerNames; +import net.minecraft.network.PacketEncoder; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.PacketFlow; +import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; +import net.neoforged.neoforge.network.filters.GenericPacketSplitter; +import net.neoforged.neoforge.network.payload.SplitPacketPayload; +import org.sinytra.fabric.networking_api.NeoNetworkRegistrar; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(GenericPacketSplitter.class) +public class GenericPacketSplitterMixin { + + /* + * Disable NeoForge packet splitting for Fabric packets + */ + + @Inject(method = "encode(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/protocol/Packet;Ljava/util/List;)V", at = @At("HEAD"), cancellable = true) + public void encode(ChannelHandlerContext ctx, Packet packet, List out, CallbackInfo ci) { + if (packet instanceof ClientboundCustomPayloadPacket clientboundCustomPayloadPacket) { + if (ctx.pipeline().get(HandlerNames.ENCODER) instanceof PacketEncoder encoder) { + var registry = NeoNetworkRegistrar.getPayloadRegistry(encoder.getProtocolInfo().id(), PacketFlow.CLIENTBOUND); + if (registry.get(clientboundCustomPayloadPacket.payload().type()) != null) { + out.add(packet); + ci.cancel(); + } + } + } else if (packet instanceof ServerboundCustomPayloadPacket serverboundCustomPayloadPacket) { + if (ctx.pipeline().get(HandlerNames.ENCODER) instanceof PacketEncoder encoder) { + var registry = NeoNetworkRegistrar.getPayloadRegistry(encoder.getProtocolInfo().id(), PacketFlow.SERVERBOUND); + if (registry.get(serverboundCustomPayloadPacket.payload().type()) != null) { + out.add(packet); + ci.cancel(); + } + } + } + } + +} diff --git a/fabric-networking-api-v1/src/main/java/org/sinytra/fabric/networking_api/server/NeoServerPlayNetworking.java b/fabric-networking-api-v1/src/main/java/org/sinytra/fabric/networking_api/server/NeoServerPlayNetworking.java index c3d67ee30..a1d960366 100644 --- a/fabric-networking-api-v1/src/main/java/org/sinytra/fabric/networking_api/server/NeoServerPlayNetworking.java +++ b/fabric-networking-api-v1/src/main/java/org/sinytra/fabric/networking_api/server/NeoServerPlayNetworking.java @@ -12,6 +12,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.neoforged.neoforge.network.handling.IPayloadContext; +import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload; import net.neoforged.neoforge.network.registration.NetworkRegistry; import org.sinytra.fabric.networking_api.NeoCommonNetworking; @@ -57,7 +58,11 @@ public static PacketSender getSender(ServerGamePacketListenerImpl handler) { } public static void onClientReady(ServerPlayer player) { - ServerPlayConnectionEvents.JOIN.invoker().onPlayReady(player.connection, new NeoServerPacketSender(player.connection.getConnection()), player.server); + NeoServerPacketSender packetSender = new NeoServerPacketSender(player.connection.getConnection()); + ServerPlayConnectionEvents.JOIN.invoker().onPlayReady(player.connection,packetSender, player.server); + + MinecraftRegisterPayload registerPacket = new MinecraftRegisterPayload(NeoCommonNetworking.PLAY_REGISTRY.getGlobalReceivers(PacketFlow.SERVERBOUND)); + packetSender.sendPacket(registerPacket); } private record ServerNeoContextWrapper(IPayloadContext context) implements ServerPlayNetworking.Context { diff --git a/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json b/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json index 6fe667027..687a46802 100644 --- a/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json +++ b/fabric-networking-api-v1/src/main/resources/fabric-networking-api-v1.mixins.json @@ -5,18 +5,19 @@ "mixins": [ "ClientConnectionMixin", "EntityTrackerEntryMixin", + "GenericPacketSplitterMixin", "LoginQueryRequestS2CPacketMixin", "LoginQueryResponseC2SPacketMixin", + "NetworkRegistryMixin", + "ServerCommonNetworkHandlerMixin", "ServerConfigurationNetworkHandlerMixin", "ServerLoginNetworkHandlerMixin", "ServerPlayNetworkHandlerMixin", - "NetworkRegistryMixin", - "ServerCommonNetworkHandlerMixin", "accessor.EntityTrackerAccessor", - "accessor.ServerCommonNetworkHandlerAccessor", - "accessor.ServerLoginNetworkHandlerAccessor", + "accessor.NetworkRegistryAccessor", "accessor.ServerChunkLoadingManagerAccessor", - "accessor.NetworkRegistryAccessor" + "accessor.ServerCommonNetworkHandlerAccessor", + "accessor.ServerLoginNetworkHandlerAccessor" ], "injectors": { "defaultRequire": 1