From cc8f31acfa0999622b43cd20774a577e3160ec81 Mon Sep 17 00:00:00 2001 From: Hei Piao Date: Thu, 20 Mar 2025 23:23:55 +0800 Subject: [PATCH 1/5] Port a little more for shearapi-network... --- shearapi-network/build.gradle | 6 +- .../network/registration/NetworkRegistry.java | 57 ++++++++-------- .../injection/IConnectionExtension.java | 7 ++ .../IConnectionProtocolExtension.java | 6 ++ .../IServerCommonPacketListenerExtension.java | 42 ++---------- .../network/mixin/ConnectionMixin.java | 18 +++++ .../mixin/ConnectionProtocolMixin.java | 21 ++++++ .../network/mixin/FriendlyByteBufMixin.java | 9 +++ .../ServerCommonPacketListenerImplMixin.java | 66 +++++++++++++++++++ ...rConfigurationPacketListenerImplMixin.java | 35 ++++++++++ ...erverConfigurationPacketListenerMixin.java | 10 +++ .../src/main/resources/fabric.mod.json | 1 + .../resources/shearapi-network.accesswidener | 3 + .../resources/shearapi-network.mixins.json | 7 +- 14 files changed, 222 insertions(+), 66 deletions(-) create mode 100644 shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionExtension.java create mode 100644 shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension.java create mode 100644 shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionMixin.java create mode 100644 shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionProtocolMixin.java create mode 100644 shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/FriendlyByteBufMixin.java create mode 100644 shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java create mode 100644 shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerMixin.java create mode 100644 shearapi-network/src/main/resources/shearapi-network.accesswidener diff --git a/shearapi-network/build.gradle b/shearapi-network/build.gradle index 41ef612..b39be99 100644 --- a/shearapi-network/build.gradle +++ b/shearapi-network/build.gradle @@ -1,4 +1,8 @@ +loom { + accessWidenerPath = file("src/main/resources/shearapi-network.accesswidener") +} + dependencies { api project(path: ":shearapi-utils", configuration: "namedElements") api project(path: ":shearapi-runtime", configuration: "namedElements") -} \ No newline at end of file +} diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java index 1c4ba5b..c197c09 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java @@ -43,7 +43,6 @@ import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; import net.minecraft.server.network.ServerPlayerConnection; import net.minecraft.util.thread.ReentrantBlockableEventLoop; -import net.neoforged.fml.config.ConfigTracker; import net.pillowmc.shearapi.runtime.ShearAPIRuntime; import net.neoforged.neoforge.network.connection.ConnectionPhase; import net.neoforged.neoforge.network.connection.ConnectionType; @@ -284,7 +283,7 @@ public FriendlyByteBuf.Reader getReader(ResourceL * @param packet The packet that was received. */ public void onModdedPacketAtServer(ServerCommonPacketListener listener, ServerboundCustomPayloadPacket packet) { - final NetworkPayloadSetup payloadSetup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + final NetworkPayloadSetup payloadSetup = listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get(); //Check if this client was even setup properly. if (payloadSetup == null) { LOGGER.warn("Received a modded custom payload packet from a client that has not negotiated with the server. Disconnecting client."); @@ -319,7 +318,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo configurationPacketListener::finishCurrentTask, new EventLoopSynchronizedWorkHandler<>(configurationPacketListener.getMainThreadEventLoop(), packet.payload()), PacketFlow.SERVERBOUND, - listener.getConnection().channel().pipeline().lastContext(), + listener.getConnection().channel.pipeline().lastContext(), Optional.empty())); } else if (listener instanceof ServerGamePacketListener playPacketListener) { //Get the configuration channel for the packet. @@ -347,7 +346,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo new ServerPacketHandler(playPacketListener), new EventLoopSynchronizedWorkHandler<>(playPacketListener.getMainThreadEventLoop(), packet.payload()), PacketFlow.SERVERBOUND, - listener.getConnection().channel().pipeline().lastContext(), + listener.getConnection().channel.pipeline().lastContext(), listener instanceof ServerPlayerConnection connection ? Optional.of(connection.getPlayer()) : Optional.empty())); } else { LOGGER.error("Received a modded custom payload packet from a client that is not in the configuration or play phase. Disconnecting client."); @@ -372,7 +371,7 @@ public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, Clien return false; } - final NetworkPayloadSetup payloadSetup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + final NetworkPayloadSetup payloadSetup = listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get(); //Check if this server was even setup properly. if (payloadSetup == null) { LOGGER.warn("Received a modded custom payload packet from a server that has not negotiated with the client. Disconnecting server."); @@ -407,7 +406,7 @@ public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, Clien (task) -> LOGGER.warn("Tried to finish a task on the client. This should not happen. Ignoring. Task: {}", task), new EventLoopSynchronizedWorkHandler<>(configurationPacketListener.getMainThreadEventLoop(), packet.payload()), PacketFlow.CLIENTBOUND, - listener.getConnection().channel().pipeline().lastContext(), + listener.getConnection().channel.pipeline().lastContext(), Optional.ofNullable(configurationPacketListener.getMinecraft().player))); } else if (listener instanceof ClientGamePacketListener playPacketListener) { //Get the configuration channel for the packet. @@ -435,7 +434,7 @@ public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, Clien new ClientPacketHandler(playPacketListener), new EventLoopSynchronizedWorkHandler<>(playPacketListener.getMainThreadEventLoop(), packet.payload()), PacketFlow.CLIENTBOUND, - listener.getConnection().channel().pipeline().lastContext(), + listener.getConnection().channel.pipeline().lastContext(), Optional.ofNullable(playPacketListener.getMinecraft().player))); } else { LOGGER.error("Received a modded custom payload packet from a server that is not in the configuration or play phase. Disconnecting server."); @@ -469,9 +468,9 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener .map(entry -> new NegotiableNetworkComponent(entry.id(), entry.version(), entry.flow(), entry.optional())) .toList()); - sender.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType()); - sender.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); - sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); + sender.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType()); + sender.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); + sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); //Negotiation failed. Disconnect the client. if (!configurationNegotiationResult.success()) { @@ -508,7 +507,7 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener .map(entry -> new NetworkChannel(entry.id(), entry.version())) .collect(Collectors.toSet())); - sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); + sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); NetworkFilters.injectIfNecessary(sender.getConnection(), sender.getConnectionType()); @@ -537,9 +536,9 @@ public boolean onVanillaOrOtherConnectionDetectedAtServer(ServerConfigurationPac List.of()); //Because we are in vanilla land, no matter what we are not able to support any custom channels. - sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); - sender.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType()); - sender.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); + sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); + sender.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType()); + sender.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); //Negotiation failed. Disconnect the client. if (!configurationNegotiationResult.success()) { @@ -678,11 +677,11 @@ public boolean canSendPacket(Packet packet, ClientCommonPacketListener listen * Returns a mutable map of the currently known ad-hoc channels. */ private Set getKnownAdHocChannelsOfOtherEnd(Connection connection) { - var map = connection.channel().attr(ATTRIBUTE_ADHOC_CHANNELS).get(); + var map = connection.channel.attr(ATTRIBUTE_ADHOC_CHANNELS).get(); if (map == null) { map = new HashSet<>(); - connection.channel().attr(ATTRIBUTE_ADHOC_CHANNELS).set(map); + connection.channel.attr(ATTRIBUTE_ADHOC_CHANNELS).set(map); } return map; @@ -766,9 +765,9 @@ public void onModdedNetworkConnectionEstablished(ClientConfigurationPacketListen NetworkFilters.injectIfNecessary(listener.getConnection(), listener.getConnectionType()); - listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); - listener.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType()); - listener.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND); + listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); + listener.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(listener.getConnectionType()); + listener.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND); final ImmutableSet.Builder nowListeningOn = ImmutableSet.builder(); nowListeningOn.addAll(getInitialClientListeningChannels()); @@ -798,9 +797,9 @@ public boolean onVanillaNetworkConnectionEstablished(ClientConfigurationPacketLi .toList()); //Because we are in vanilla land, no matter what we are not able to support any custom channels. - sender.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); - sender.getConnection().channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType()); - sender.getConnection().channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND); + sender.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); + sender.getConnection().channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(sender.getConnectionType()); + sender.getConnection().channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.CLIENTBOUND); //Negotiation failed. Disconnect the client. if (!configurationNegotiationResult.success()) { @@ -867,7 +866,7 @@ public boolean isConnected(ClientCommonPacketListener listener, ResourceLocation * @return True if the connection has a connection setup that can transmit the given payload id, false otherwise. */ public boolean isConnected(final Connection connection, ConnectionPhase connectionPhase, ResourceLocation payloadId) { - final NetworkPayloadSetup payloadSetup = connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + final NetworkPayloadSetup payloadSetup = connection.channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get(); if (payloadSetup == null) { return getKnownAdHocChannelsOfOtherEnd(connection).contains(payloadId); } @@ -933,9 +932,9 @@ public List> filterGameBundlePackets(Channe * @param connection The connection to configure. */ public void configureMockConnection(final Connection connection) { - connection.channel().attr(ATTRIBUTE_CONNECTION_TYPE).set(ConnectionType.NEOFORGE); - connection.channel().attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); - connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); + connection.channel.attr(ATTRIBUTE_CONNECTION_TYPE).set(ConnectionType.NEOFORGE); + connection.channel.attr(ATTRIBUTE_FLOW).set(PacketFlow.SERVERBOUND); + connection.channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(NetworkPayloadSetup.empty()); final NetworkPayloadSetup setup = NetworkPayloadSetup.from( this.knownConfigurationRegistrations.entrySet().stream() @@ -945,7 +944,7 @@ public void configureMockConnection(final Connection connection) { .map(entry -> new NetworkChannel(entry.getKey(), entry.getValue().version())) .collect(Collectors.toSet())); - connection.channel().attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); + connection.channel.attr(ATTRIBUTE_PAYLOAD_SETUP).set(setup); NetworkFilters.injectIfNecessary(connection, ConnectionType.NEOFORGE); } @@ -1041,7 +1040,7 @@ private static Set getInitialClientListeningChannels() { } public void onConfigurationFinished(ServerConfigurationPacketListener serverConfigurationPacketListener) { - final NetworkPayloadSetup setup = serverConfigurationPacketListener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + final NetworkPayloadSetup setup = serverConfigurationPacketListener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get(); if (setup == null) { LOGGER.error("Somebody tried to finish the configuration phase of a connection that has not negotiated with the client. Not finishing configuration."); return; @@ -1067,7 +1066,7 @@ public void onConfigurationFinished(ServerConfigurationPacketListener serverConf } public void onConfigurationFinished(ClientConfigurationPacketListener listener) { - final NetworkPayloadSetup setup = listener.getConnection().channel().attr(ATTRIBUTE_PAYLOAD_SETUP).get(); + final NetworkPayloadSetup setup = listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get(); if (setup == null) { LOGGER.error("Somebody tried to finish the configuration phase of a connection that has not negotiated with the server. Not finishing configuration."); return; diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionExtension.java new file mode 100644 index 0000000..a5d889b --- /dev/null +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionExtension.java @@ -0,0 +1,7 @@ +package net.pillowmc.shearapi.network.injection; + +import io.netty.channel.Channel; + +public interface IConnectionExtension { + Channel channel(); +} diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension.java new file mode 100644 index 0000000..d497be3 --- /dev/null +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension.java @@ -0,0 +1,6 @@ +package net.pillowmc.shearapi.network.injection; + +public interface IConnectionProtocolExtension { + boolean isPlay(); + boolean isConfiguration(); +} diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java index 900faf2..39ce141 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java @@ -25,19 +25,6 @@ *

*/ public interface IServerCommonPacketListenerExtension { - /** - * {@return the {@link ServerCommonPacketListener} that the extensions is attached to} - */ - private ServerCommonPacketListener self() { - return (ServerCommonPacketListener) this; - } - - /** - * Sends a packet to the client which this listener is attached to. - * - * @param packet The packet to send - */ - void send(Packet packet); /** * Sends a custom payload to the client which this listener is attached to. @@ -45,17 +32,9 @@ private ServerCommonPacketListener self() { * @param packetPayload The payload to send */ default void send(CustomPacketPayload packetPayload) { - this.send(new ClientboundCustomPayloadPacket(packetPayload)); + throw new AssertionError("This should be implemented by mixin!"); } - /** - * Sends a packet to the client which this listener is attached to. - * - * @param packet The packet to send - * @param packetSendListener The listener to call when the packet is sent - */ - void send(Packet packet, @Nullable PacketSendListener packetSendListener); - /** * Sends a custom payload to the client which this listener is attached to. * @@ -63,16 +42,9 @@ default void send(CustomPacketPayload packetPayload) { * @param listener The listener to call when the packet is sent */ default void send(CustomPacketPayload packetPayload, @Nullable PacketSendListener listener) { - this.send(new ClientboundCustomPayloadPacket(packetPayload), listener); + throw new AssertionError("This should be implemented by mixin!"); } - /** - * Triggers a disconnection with the given reason. - * - * @param reason The reason for the disconnection - */ - void disconnect(Component reason); - /** * {@return the connection this listener is attached to} */ @@ -85,12 +57,12 @@ default void send(CustomPacketPayload packetPayload, @Nullable PacketSendListene /** * {@return true if the connection is to a vanilla client} - * + * * @deprecated Use {@link #getConnectionType()} instead */ @Deprecated(forRemoval = true) default boolean isVanillaConnection() { - return getConnectionType().isVanilla(); + throw new AssertionError("This should be implemented by mixin!"); } /** @@ -99,16 +71,16 @@ default boolean isVanillaConnection() { * @param payloadId The payload id to check */ default boolean isConnected(final ResourceLocation payloadId) { - return NetworkRegistry.getInstance().isConnected(self(), payloadId); + throw new AssertionError("This should be implemented by mixin!"); } /** * {@return true if the custom payload is usable by this connection} - * + * * @param payload The payload to check */ default boolean isConnected(final CustomPacketPayload payload) { - return isConnected(payload.id()); + throw new AssertionError("This should be implemented by mixin!"); } /** diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionMixin.java new file mode 100644 index 0000000..92a64da --- /dev/null +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionMixin.java @@ -0,0 +1,18 @@ +package net.pillowmc.shearapi.network.mixin; + +import io.netty.channel.Channel; +import net.minecraft.network.Connection; +import net.pillowmc.shearapi.network.injection.IConnectionExtension; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(Connection.class) +public class ConnectionMixin implements IConnectionExtension { + @Shadow + public Channel channel; + + @Override + public Channel channel() { + return this.channel; + } +} diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionProtocolMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionProtocolMixin.java new file mode 100644 index 0000000..94bbea5 --- /dev/null +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ConnectionProtocolMixin.java @@ -0,0 +1,21 @@ +package net.pillowmc.shearapi.network.mixin; + +import net.minecraft.network.ConnectionProtocol; +import net.pillowmc.shearapi.network.injection.IConnectionProtocolExtension; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ConnectionProtocol.class) +public class ConnectionProtocolMixin implements IConnectionProtocolExtension { + + @Override + public boolean isPlay() { + return (Object) this == ConnectionProtocol.PLAY; + } + + @Override + public boolean isConfiguration() { + return (Object) this == ConnectionProtocol.CONFIGURATION; + } +} diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/FriendlyByteBufMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/FriendlyByteBufMixin.java new file mode 100644 index 0000000..8b16328 --- /dev/null +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/FriendlyByteBufMixin.java @@ -0,0 +1,9 @@ +package net.pillowmc.shearapi.network.mixin; + +import net.minecraft.network.FriendlyByteBuf; +import net.pillowmc.shearapi.network.injection.IFriendlyByteBufExtension; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(FriendlyByteBuf.class) +public class FriendlyByteBufMixin implements IFriendlyByteBufExtension { +} diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java index ed098f0..0fb0245 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java @@ -1,10 +1,76 @@ package net.pillowmc.shearapi.network.mixin; +import net.minecraft.network.Connection; +import net.minecraft.network.PacketSendListener; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.ServerCommonPacketListener; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerCommonPacketListenerImpl; +import net.minecraft.util.thread.ReentrantBlockableEventLoop; +import net.neoforged.neoforge.network.connection.ConnectionType; +import net.neoforged.neoforge.network.registration.NetworkRegistry; import net.pillowmc.shearapi.network.injection.IServerCommonPacketListenerExtension; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; @Mixin(ServerCommonPacketListenerImpl.class) public abstract class ServerCommonPacketListenerImplMixin implements IServerCommonPacketListenerExtension { + @Override + public Connection getConnection() { + return connection; + } + + @Shadow + @Final + protected Connection connection; + + @Shadow + @Final + protected MinecraftServer server; + + @Shadow + public abstract void send(Packet packet); + + @Shadow + public abstract void send(Packet packet, @Nullable PacketSendListener packetSendListener); + + @Override + public ReentrantBlockableEventLoop getMainThreadEventLoop() { + return server; + } + + @Override + public abstract ConnectionType getConnectionType(); + + @Override + public void send(CustomPacketPayload packetPayload) { + this.send(new ClientboundCustomPayloadPacket(packetPayload)); + } + + @Override + public void send(CustomPacketPayload packetPayload, @Nullable PacketSendListener listener) { + this.send(new ClientboundCustomPayloadPacket(packetPayload), listener); + } + + @Override + public boolean isVanillaConnection() { + return getConnectionType().isVanilla(); + } + + @Override + public boolean isConnected(ResourceLocation payloadId) { + return NetworkRegistry.getInstance().isConnected((ServerCommonPacketListener) (Object)this, payloadId); + } + + @Override + public boolean isConnected(CustomPacketPayload payload) { + return this.isConnected(payload.id()); + } } diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java new file mode 100644 index 0000000..5cbc6a7 --- /dev/null +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java @@ -0,0 +1,35 @@ +package net.pillowmc.shearapi.network.mixin; + +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener; +import net.minecraft.server.network.ConfigurationTask; +import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; +import net.minecraft.util.thread.ReentrantBlockableEventLoop; +import net.neoforged.neoforge.network.connection.ConnectionType; +import net.pillowmc.shearapi.network.injection.IServerConfigurationPacketListenerExtension; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(ServerConfigurationPacketListenerImpl.class) +public abstract class ServerConfigurationPacketListenerImplMixin implements IServerConfigurationPacketListenerExtension { + + @Override + @Shadow + public abstract void finishCurrentTask(ConfigurationTask.Type task); + + @Override + public Connection getConnection() { + return null; + } + + @Override + public ReentrantBlockableEventLoop getMainThreadEventLoop() { + return null; + } + + @Override + public ConnectionType getConnectionType() { + return null; + } +} diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerMixin.java new file mode 100644 index 0000000..9e3b4f7 --- /dev/null +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerMixin.java @@ -0,0 +1,10 @@ +package net.pillowmc.shearapi.network.mixin; + +import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener; +import net.pillowmc.shearapi.network.injection.IServerConfigurationPacketListenerExtension; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(ServerConfigurationPacketListener.class) +public interface ServerConfigurationPacketListenerMixin extends IServerConfigurationPacketListenerExtension { + +} diff --git a/shearapi-network/src/main/resources/fabric.mod.json b/shearapi-network/src/main/resources/fabric.mod.json index d4e7913..a13d489 100644 --- a/shearapi-network/src/main/resources/fabric.mod.json +++ b/shearapi-network/src/main/resources/fabric.mod.json @@ -22,6 +22,7 @@ "shearapi-utils": "~${version}", "shearapi-runtime": "~${version}" }, + "accessWidener": "shearapi-network.accesswidener", "entrypoints": { "client": ["net.pillowmc.shearapi.network.client.ShearAPINetworkClient"], "shearapi-runtime:mod_bus_subscriber": ["net.neoforged.neoforge.network.ConfigurationInitialization::clazz"] diff --git a/shearapi-network/src/main/resources/shearapi-network.accesswidener b/shearapi-network/src/main/resources/shearapi-network.accesswidener new file mode 100644 index 0000000..c83c15d --- /dev/null +++ b/shearapi-network/src/main/resources/shearapi-network.accesswidener @@ -0,0 +1,3 @@ +accessWidener v1 named +accessible field net/minecraft/network/Connection channel Lio/netty/channel/Channel; +#accessible method net/minecraft/network/ServerConfigurationPacketListenerImpl finishCurrentTask (Lnet/minecraft/server/network/ConfigurationTask$Type;)V diff --git a/shearapi-network/src/main/resources/shearapi-network.mixins.json b/shearapi-network/src/main/resources/shearapi-network.mixins.json index dcd8685..d96013a 100644 --- a/shearapi-network/src/main/resources/shearapi-network.mixins.json +++ b/shearapi-network/src/main/resources/shearapi-network.mixins.json @@ -3,7 +3,12 @@ "package": "net.pillowmc.shearapi.network.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ - "ServerCommonPacketListenerMixin" + "ConnectionMixin", + "ConnectionProtocolMixin", + "FriendlyByteBufMixin", + "ServerCommonPacketListenerImplMixin", + "ServerCommonPacketListenerMixin", + "ServerConfigurationPacketListenerMixin" ], "injectors": { "defaultRequire": 1 From 20362cd82257182ece66ebdb1378a7cd80ae838c Mon Sep 17 00:00:00 2001 From: Hei Piao Date: Sat, 22 Mar 2025 08:59:01 +0800 Subject: [PATCH 2/5] Port a little more for shearapi-network... --- ...rConfigurationPacketListenerExtension.java | 6 +++ .../ServerCommonPacketListenerImplMixin.java | 48 +++++++++++++++++++ ...rConfigurationPacketListenerImplMixin.java | 44 ++++++++++++++--- .../resources/shearapi-network.accesswidener | 2 +- 4 files changed, 93 insertions(+), 7 deletions(-) diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java index c9ad80b..6340c4f 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension.java @@ -5,9 +5,11 @@ package net.pillowmc.shearapi.network.injection; +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener; import net.minecraft.server.network.ConfigurationTask; import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; +import net.neoforged.neoforge.network.connection.ConnectionType; /** * Extension class for {@link ServerConfigurationPacketListener} @@ -20,4 +22,8 @@ public interface IServerConfigurationPacketListenerExtension extends IServerComm * @implNote This forces the normally private method implementation in {@link ServerConfigurationPacketListenerImpl#finishCurrentTask(ConfigurationTask.Type)} to become public, and adds this to the signature of {@link ServerConfigurationPacketListener} */ void finishCurrentTask(ConfigurationTask.Type task); + + void shearapi$setConnectionType(ConnectionType type); + boolean shearapi$isHandlingModdedConfigurationPhase(); + void shearapi$setHandlingModdedConfigurationPhase(); } diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java index 0fb0245..7761265 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java @@ -6,18 +6,26 @@ import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; import net.minecraft.network.protocol.common.ServerCommonPacketListener; +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerCommonPacketListenerImpl; +import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; import net.minecraft.util.thread.ReentrantBlockableEventLoop; import net.neoforged.neoforge.network.connection.ConnectionType; +import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload; +import net.neoforged.neoforge.network.payload.MinecraftUnregisterPayload; +import net.neoforged.neoforge.network.payload.ModdedNetworkQueryPayload; import net.neoforged.neoforge.network.registration.NetworkRegistry; import net.pillowmc.shearapi.network.injection.IServerCommonPacketListenerExtension; import org.jetbrains.annotations.Nullable; 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; @Mixin(ServerCommonPacketListenerImpl.class) public abstract class ServerCommonPacketListenerImplMixin implements IServerCommonPacketListenerExtension { @@ -73,4 +81,44 @@ public boolean isConnected(ResourceLocation payloadId) { public boolean isConnected(CustomPacketPayload payload) { return this.isConnected(payload.id()); } + + // This should be in ServerConfigurationPacketListenerImplMixin... + @Inject(method = "handleCustomPayload", at = @At("HEAD"), cancellable = true) + private void handleCustomPayloadHead(ServerboundCustomPayloadPacket packet, CallbackInfo ci) { + if (!((Object)this instanceof ServerConfigurationPacketListenerImpl self)) return; + if (packet.payload() instanceof MinecraftRegisterPayload payload) { + self.shearapi$setConnectionType(self.getConnectionType().withMinecraftRegisterPayload()); + NetworkRegistry.getInstance().onMinecraftRegister(self, payload.newChannels()); + return; + } + + if (packet.payload() instanceof MinecraftUnregisterPayload payload) { + self.shearapi$setConnectionType(self.getConnectionType().withMinecraftRegisterPayload()); + NetworkRegistry.getInstance().onMinecraftUnregister(self, payload.forgottenChannels()); + return; + } + + if (packet.payload() instanceof ModdedNetworkQueryPayload payload) { + self.shearapi$setConnectionType(self.getConnectionType().withNeoForgeQueryPayload()); + NetworkRegistry.getInstance().onModdedConnectionDetectedAtServer( + self, + payload.configuration(), + payload.play() + ); + return; + } + + if (self.shearapi$isHandlingModdedConfigurationPhase()) { + NetworkRegistry.getInstance().onModdedPacketAtServer(self, packet); + ci.cancel(); + } + + } + + @Inject(method = "handleCustomPayload", at = @At("TAIL")) + private void handleCustomPayloadTail(ServerboundCustomPayloadPacket packet, CallbackInfo ci) { + if ((Object)this instanceof ServerConfigurationPacketListenerImpl self) { + NetworkRegistry.getInstance().onModdedPacketAtServer(self, packet); + } + } } diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java index 5cbc6a7..82a2a3f 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerConfigurationPacketListenerImplMixin.java @@ -1,35 +1,67 @@ package net.pillowmc.shearapi.network.mixin; import net.minecraft.network.Connection; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; import net.minecraft.network.protocol.configuration.ServerConfigurationPacketListener; +import net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket; import net.minecraft.server.network.ConfigurationTask; import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; import net.minecraft.util.thread.ReentrantBlockableEventLoop; import net.neoforged.neoforge.network.connection.ConnectionType; +import net.neoforged.neoforge.network.payload.MinecraftRegisterPayload; +import net.neoforged.neoforge.network.payload.MinecraftUnregisterPayload; +import net.neoforged.neoforge.network.payload.ModdedNetworkQueryPayload; +import net.neoforged.neoforge.network.registration.NetworkRegistry; import net.pillowmc.shearapi.network.injection.IServerConfigurationPacketListenerExtension; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.gen.Invoker; +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.Set; @Mixin(ServerConfigurationPacketListenerImpl.class) public abstract class ServerConfigurationPacketListenerImplMixin implements IServerConfigurationPacketListenerExtension { + private ConnectionType connectionType = ConnectionType.VANILLA; + private boolean isHandlingModdedConfigurationPhase = false; @Override @Shadow public abstract void finishCurrentTask(ConfigurationTask.Type task); @Override - public Connection getConnection() { - return null; + public ConnectionType getConnectionType() { + return connectionType; } @Override - public ReentrantBlockableEventLoop getMainThreadEventLoop() { - return null; + public void shearapi$setConnectionType(ConnectionType connectionType) { + this.connectionType = connectionType; } @Override - public ConnectionType getConnectionType() { - return null; + public boolean shearapi$isHandlingModdedConfigurationPhase() { + return isHandlingModdedConfigurationPhase; + } + + @Override + public void shearapi$setHandlingModdedConfigurationPhase() { + isHandlingModdedConfigurationPhase = true; + } + + @Inject(method = "handleConfigurationFinished", at = @At("HEAD")) + private void handleConfigurationFinished(ServerboundFinishConfigurationPacket serverboundFinishConfigurationPacket, CallbackInfo ci) { + if (this.connectionType == ConnectionType.OTHER) { + NetworkRegistry.getInstance().onModdedConnectionDetectedAtServer( + (ServerConfigurationPacketListener) this, + Set.of(), + Set.of() + ); + } + NetworkRegistry.getInstance().onConfigurationFinished((ServerConfigurationPacketListener) this); } } diff --git a/shearapi-network/src/main/resources/shearapi-network.accesswidener b/shearapi-network/src/main/resources/shearapi-network.accesswidener index c83c15d..6983b0c 100644 --- a/shearapi-network/src/main/resources/shearapi-network.accesswidener +++ b/shearapi-network/src/main/resources/shearapi-network.accesswidener @@ -1,3 +1,3 @@ accessWidener v1 named accessible field net/minecraft/network/Connection channel Lio/netty/channel/Channel; -#accessible method net/minecraft/network/ServerConfigurationPacketListenerImpl finishCurrentTask (Lnet/minecraft/server/network/ConfigurationTask$Type;)V +accessible method net/minecraft/server/network/ServerConfigurationPacketListenerImpl finishCurrentTask (Lnet/minecraft/server/network/ConfigurationTask$Type;)V From 3f7c017075b0361bc0e6d9a6af14924a203d5660 Mon Sep 17 00:00:00 2001 From: Hei Piao Date: Wed, 26 Mar 2025 22:55:42 +0800 Subject: [PATCH 3/5] wip: port a little more for shearapi-network --- .../network/registration/NetworkRegistry.java | 29 ++++++++---- .../IServerCommonPacketListenerExtension.java | 46 ++++++++++++++++--- .../ServerCommonPacketListenerImplMixin.java | 33 +++---------- .../src/main/resources/fabric.mod.json | 3 +- .../resources/shearapi-network.accesswidener | 2 + 5 files changed, 72 insertions(+), 41 deletions(-) diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java index c197c09..1eb98e8 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/registration/NetworkRegistry.java @@ -64,6 +64,7 @@ import net.neoforged.neoforge.network.payload.ModdedNetworkQueryComponent; import net.neoforged.neoforge.network.payload.ModdedNetworkQueryPayload; import net.neoforged.neoforge.network.payload.ModdedNetworkSetupFailedPayload; +import net.pillowmc.shearapi.runtime.ShearAPIVersion; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -287,7 +288,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo //Check if this client was even setup properly. if (payloadSetup == null) { LOGGER.warn("Received a modded custom payload packet from a client that has not negotiated with the server. Disconnecting client."); - listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion()))); + listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion()))); return; } @@ -298,7 +299,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo //Check if the channel should even be processed. if (channel == null && !isAdhocConfigurationChannelReadable(packet.payload().id(), PacketFlow.SERVERBOUND)) { LOGGER.warn("Received a modded custom payload packet from a client with an unknown or not accepted channel. Disconnecting client."); - listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion()))); + listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion()))); return; } @@ -327,7 +328,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo //Check if the channel should even be processed. if (channel == null && !isAdhocPlayChannelReadable(packet.payload().id(), PacketFlow.SERVERBOUND)) { LOGGER.warn("Received a modded custom payload packet from a client with an unknown or not accepted channel. Disconnecting client."); - listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion()))); + listener.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion()))); return; } @@ -366,6 +367,7 @@ public void onModdedPacketAtServer(ServerCommonPacketListener listener, Serverbo * @param listener The listener which received the packet. * @param packet The packet that was received. */ + // TODO: (ShearAPI) move to client public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, ClientboundCustomPayloadPacket packet) { if (packet.payload().id().getNamespace().equals("minecraft")) { return false; @@ -415,7 +417,7 @@ public boolean onModdedPacketAtClient(ClientCommonPacketListener listener, Clien //Check if the channel should even be processed. if (channel == null && !isAdhocPlayChannelReadable(packet.payload().id(), PacketFlow.CLIENTBOUND)) { LOGGER.warn("Received a modded custom payload packet from a server with an unknown or not accepted channel. Disconnecting server."); - listener.getConnection().disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion()))); + listener.getConnection().disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion()))); return false; } @@ -478,7 +480,7 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener sender.send(new ModdedNetworkSetupFailedPayload(configurationNegotiationResult.failureReasons())); } - sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion()))); + sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion()))); return; } @@ -496,7 +498,7 @@ public void onModdedConnectionDetectedAtServer(ServerConfigurationPacketListener sender.send(new ModdedNetworkSetupFailedPayload(playNegotiationResult.failureReasons())); } - sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(NeoForgeVersion.getVersion()))); + sender.disconnect(Component.translatable("multiplayer.disconnect.incompatible", "NeoForge %s".formatted(ShearAPIVersion.getVersion()))); } final NetworkPayloadSetup setup = NetworkPayloadSetup.from( @@ -542,7 +544,7 @@ public boolean onVanillaOrOtherConnectionDetectedAtServer(ServerConfigurationPac //Negotiation failed. Disconnect the client. if (!configurationNegotiationResult.success()) { - sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", NeoForgeVersion.getVersion())); + sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", ShearAPIVersion.getVersion())); return false; } @@ -554,7 +556,7 @@ public boolean onVanillaOrOtherConnectionDetectedAtServer(ServerConfigurationPac //Negotiation failed. Disconnect the client. if (!playNegotiationResult.success()) { - sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", NeoForgeVersion.getVersion())); + sender.disconnect(Component.translatableWithFallback("neoforge.network.negotiation.failure.vanilla.client.not_supported", "You are trying to connect to a server that is running NeoForge, but you are not. Please install NeoForge Version: %s to connect to this server.", ShearAPIVersion.getVersion())); return false; } @@ -643,6 +645,7 @@ public boolean shouldSendPacketRaw(Packet packet) { * @param listener The listener that wants to send the packet. * @return True if the packet can be sent, false otherwise. */ + // TODO: (ShearAPI) move to client public boolean canSendPacket(Packet packet, ClientCommonPacketListener listener) { if (!(packet instanceof ServerboundCustomPayloadPacket customPayloadPacket)) { return true; @@ -732,6 +735,7 @@ private boolean isAdhocPlayChannelReadable(ResourceLocation id, PacketFlow flow) * * @param listener The listener which received the query. */ + // TODO: (ShearAPI) move to client public void onNetworkQuery(ClientConfigurationPacketListener listener) { final ModdedNetworkQueryPayload payload = new ModdedNetworkQueryPayload( knownConfigurationRegistrations.entrySet().stream() @@ -754,6 +758,7 @@ public void onNetworkQuery(ClientConfigurationPacketListener listener) { * @param configuration The configuration channels that were negotiated. * @param play The play channels that were negotiated. */ + // TODO: (ShearAPI) move to client public void onModdedNetworkConnectionEstablished(ClientConfigurationPacketListener listener, Set configuration, Set play) { final NetworkPayloadSetup setup = NetworkPayloadSetup.from( configuration.stream() @@ -787,6 +792,7 @@ public void onModdedNetworkConnectionEstablished(ClientConfigurationPacketListen * @param sender The listener which received the brand payload. * @return True if the vanilla connection should be handled by the client, false otherwise. */ + // TODO: (ShearAPI) move to client public boolean onVanillaNetworkConnectionEstablished(ClientConfigurationPacketListener sender) { NetworkFilters.cleanIfNecessary(sender.getConnection()); @@ -853,6 +859,7 @@ public boolean isConnected(ServerCommonPacketListener listener, ResourceLocation * @param payloadId The payload id to check. * @return True if the listener has a connection setup that can transmit the given payload id, false otherwise. */ + // TODO: (ShearAPI) move to client public boolean isConnected(ClientCommonPacketListener listener, ResourceLocation payloadId) { return isConnected(listener.getConnection(), ConnectionPhase.fromPacketListener(listener), payloadId); } @@ -955,6 +962,7 @@ public void configureMockConnection(final Connection connection) { * @param listener The listener which received the payload. * @param resourceLocations The resource locations that were registered. */ + // TODO: (ShearAPI) move to client public void onMinecraftRegister(ClientCommonPacketListener listener, Set resourceLocations) { onMinecraftRegister(resourceLocations, listener.getConnection()); } @@ -985,6 +993,7 @@ private void onMinecraftRegister(Set resourceLocations, Connec * @param listener The listener which received the payload. * @param resourceLocations The resource locations that were unregistered. */ + // TODO: (ShearAPI) move to client public void onMinecraftUnregister(ClientCommonPacketListener listener, Set resourceLocations) { onMinecraftUnregister(resourceLocations, listener.getConnection()); } @@ -1030,6 +1039,7 @@ public Set getInitialServerUnregisterChannels() { return nowForgottenChannels.build(); } + // TODO: (ShearAPI) move to client private static Set getInitialClientListeningChannels() { return Set.of( MinecraftRegisterPayload.ID, @@ -1065,6 +1075,7 @@ public void onConfigurationFinished(ServerConfigurationPacketListener serverConf serverConfigurationPacketListener.send(new MinecraftRegisterPayload(nowListeningOn.build())); } + // TODO: (ShearAPI) move to client public void onConfigurationFinished(ClientConfigurationPacketListener listener) { final NetworkPayloadSetup setup = listener.getConnection().channel.attr(ATTRIBUTE_PAYLOAD_SETUP).get(); if (setup == null) { @@ -1156,6 +1167,7 @@ private static void resolvePacketGenerics(Packet p } } + // TODO: (ShearAPI) move to client @SuppressWarnings("unchecked") private record ClientPacketHandler(ClientCommonPacketListener listener) implements IPacketHandler { @Override @@ -1194,6 +1206,7 @@ public void disconnect(Component reason) { } } + // TODO: (ShearAPI) move to client private record ClientReplyHandler(ClientCommonPacketListener listener) implements IReplyHandler { @Override public void send(CustomPacketPayload payload) { diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java index 39ce141..0c3f772 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension.java @@ -26,12 +26,31 @@ */ public interface IServerCommonPacketListenerExtension { + /** + * Sends a packet to the client which this listener is attached to. + * + * @param packet The packet to send + */ + default void send(Packet packet) { + throw new AssertionError("This should be implemented by mixin!"); + } + /** * Sends a custom payload to the client which this listener is attached to. * * @param packetPayload The payload to send */ default void send(CustomPacketPayload packetPayload) { + this.send(new ClientboundCustomPayloadPacket(packetPayload)); + } + + /** + * Sends a packet to the client which this listener is attached to. + * + * @param packet The packet to send + * @param packetSendListener The listener to call when the packet is sent + */ + default void send(Packet packet, @Nullable PacketSendListener packetSendListener) { throw new AssertionError("This should be implemented by mixin!"); } @@ -42,18 +61,31 @@ default void send(CustomPacketPayload packetPayload) { * @param listener The listener to call when the packet is sent */ default void send(CustomPacketPayload packetPayload, @Nullable PacketSendListener listener) { + this.send(new ClientboundCustomPayloadPacket(packetPayload), listener); + } + + /** + * Triggers a disconnection with the given reason. + * + * @param reason The reason for the disconnection + */ + default void disconnect(Component reason) { throw new AssertionError("This should be implemented by mixin!"); } /** * {@return the connection this listener is attached to} */ - Connection getConnection(); + default Connection getConnection() { + throw new AssertionError("This should be implemented by mixin!"); + } /** * {@return the main thread event loop} */ - ReentrantBlockableEventLoop getMainThreadEventLoop(); + default ReentrantBlockableEventLoop getMainThreadEventLoop() { + throw new AssertionError("This should be implemented by mixin!"); + } /** * {@return true if the connection is to a vanilla client} @@ -62,7 +94,7 @@ default void send(CustomPacketPayload packetPayload, @Nullable PacketSendListene */ @Deprecated(forRemoval = true) default boolean isVanillaConnection() { - throw new AssertionError("This should be implemented by mixin!"); + return getConnectionType().isVanilla(); } /** @@ -71,7 +103,7 @@ default boolean isVanillaConnection() { * @param payloadId The payload id to check */ default boolean isConnected(final ResourceLocation payloadId) { - throw new AssertionError("This should be implemented by mixin!"); + return NetworkRegistry.getInstance().isConnected((ServerCommonPacketListener) this, payloadId); } /** @@ -80,11 +112,13 @@ default boolean isConnected(final ResourceLocation payloadId) { * @param payload The payload to check */ default boolean isConnected(final CustomPacketPayload payload) { - throw new AssertionError("This should be implemented by mixin!"); + return isConnected(payload.id()); } /** * {@return the connection type of the connection} */ - ConnectionType getConnectionType(); + default ConnectionType getConnectionType() { + throw new AssertionError("This should be implemented by mixin!"); + } } diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java index 7761265..edff5b1 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/mixin/ServerCommonPacketListenerImplMixin.java @@ -44,9 +44,11 @@ public Connection getConnection() { protected MinecraftServer server; @Shadow + @Override public abstract void send(Packet packet); @Shadow + @Override public abstract void send(Packet packet, @Nullable PacketSendListener packetSendListener); @Override @@ -54,32 +56,11 @@ public ReentrantBlockableEventLoop getMainThreadEventLoop() { return server; } - @Override - public abstract ConnectionType getConnectionType(); - - @Override - public void send(CustomPacketPayload packetPayload) { - this.send(new ClientboundCustomPayloadPacket(packetPayload)); - } - - @Override - public void send(CustomPacketPayload packetPayload, @Nullable PacketSendListener listener) { - this.send(new ClientboundCustomPayloadPacket(packetPayload), listener); - } - - @Override - public boolean isVanillaConnection() { - return getConnectionType().isVanilla(); - } - - @Override - public boolean isConnected(ResourceLocation payloadId) { - return NetworkRegistry.getInstance().isConnected((ServerCommonPacketListener) (Object)this, payloadId); - } - - @Override - public boolean isConnected(CustomPacketPayload payload) { - return this.isConnected(payload.id()); + @Inject(method = "send(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketSendListener;)V", at = @At("HEAD"), cancellable = true) + private void injectSend(Packet packet, PacketSendListener packetSendListener, CallbackInfo ci) { + if (!NetworkRegistry.getInstance().canSendPacket(packet, (ServerCommonPacketListener) this)) { + ci.cancel(); + } } // This should be in ServerConfigurationPacketListenerImplMixin... diff --git a/shearapi-network/src/main/resources/fabric.mod.json b/shearapi-network/src/main/resources/fabric.mod.json index a13d489..446dd9e 100644 --- a/shearapi-network/src/main/resources/fabric.mod.json +++ b/shearapi-network/src/main/resources/fabric.mod.json @@ -33,7 +33,8 @@ "net/minecraft/class_8706": ["net/pillowmc/shearapi/network/injection/IServerCommonPacketListenerExtension"], "net/minecraft/class_8735": ["net/pillowmc/shearapi/network/injection/IServerConfigurationPacketListenerExtension"], "net/minecraft/class_2792": ["net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension"], - "net/minecraft/class_2540": ["net/pillowmc/shearapi/network/injection/IFriendlyByteBufExtension"] + "net/minecraft/class_2540": ["net/pillowmc/shearapi/network/injection/IFriendlyByteBufExtension"], + "net/minecraft/class_2539": ["net/pillowmc/shearapi/network/injection/IConnectionProtocolExtension"] }, "modmenu": { "parent": "shearapi", diff --git a/shearapi-network/src/main/resources/shearapi-network.accesswidener b/shearapi-network/src/main/resources/shearapi-network.accesswidener index 6983b0c..e0b04e2 100644 --- a/shearapi-network/src/main/resources/shearapi-network.accesswidener +++ b/shearapi-network/src/main/resources/shearapi-network.accesswidener @@ -1,3 +1,5 @@ accessWidener v1 named accessible field net/minecraft/network/Connection channel Lio/netty/channel/Channel; accessible method net/minecraft/server/network/ServerConfigurationPacketListenerImpl finishCurrentTask (Lnet/minecraft/server/network/ConfigurationTask$Type;)V +accessible field net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket KNOWN_TYPES Ljava/util/Map; +accessible field net/minecraft/network/protocol/common/ClientboundCustomPayloadPacket KNOWN_TYPES Ljava/util/Map; From 873d23460ba7e8823b4cf8212f1875769249c7c0 Mon Sep 17 00:00:00 2001 From: Hei Piao Date: Sat, 12 Apr 2025 13:36:26 +0800 Subject: [PATCH 4/5] feat: move classes that deals with network out of shearapi-withpillow --- settings.gradle | 1 + shearapi-fmlstuff/build.gradle | 13 +++++++ .../client/ShearAPIFMLStuffClient.java | 18 ++++----- .../neoforge/event/ModMismatchEvent.java | 0 .../neoforge/network/ConfigSync.java | 0 .../network/configuration/SyncConfig.java | 0 .../network/payload/ConfigFilePayload.java | 0 .../shearapi/fmlstuff/ShearAPIFMLStuff.java | 19 +++++++++ .../assets/shearapi-fmlstuff/icon.png | Bin 0 -> 13899 bytes .../src/main/resources/fabric.mod.json | 36 ++++++++++++++++++ shearapi-withpillow/build.gradle | 1 - .../withpillow/ShearAPIWithPillow.java | 12 ------ .../src/main/resources/fabric.mod.json | 4 -- 13 files changed, 78 insertions(+), 26 deletions(-) create mode 100644 shearapi-fmlstuff/build.gradle rename shearapi-withpillow/src/client/java/net/pillowmc/shearapi/withpillow/client/ShearAPIWithPillowClient.java => shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java (72%) rename {shearapi-withpillow => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java (100%) rename {shearapi-withpillow => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/network/ConfigSync.java (100%) rename {shearapi-withpillow => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java (100%) rename {shearapi-withpillow => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java (100%) create mode 100644 shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java create mode 100644 shearapi-fmlstuff/src/main/resources/assets/shearapi-fmlstuff/icon.png create mode 100644 shearapi-fmlstuff/src/main/resources/fabric.mod.json diff --git a/settings.gradle b/settings.gradle index 9b7af0c..3f5a83b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -29,3 +29,4 @@ include("shearapi-conditions") include("shearapi-network") include("shearapi-holderset") include("shearapi-resource") +include("shearapi-fmlstuff") diff --git a/shearapi-fmlstuff/build.gradle b/shearapi-fmlstuff/build.gradle new file mode 100644 index 0000000..4e967b5 --- /dev/null +++ b/shearapi-fmlstuff/build.gradle @@ -0,0 +1,13 @@ +repositories { + maven { + url "https://maven.neoforged.net/releases/" + name "NeoForged Releases" + } +} + +dependencies { + implementation "net.neoforged.fancymodloader:loader:${project.fancy_mod_loader_version}" + api project(path: ":shearapi-runtime", configuration: "namedElements") + api project(path: ":shearapi-withpillow", configuration: "namedElements") + api project(path: ":shearapi-network", configuration: "namedElements") +} diff --git a/shearapi-withpillow/src/client/java/net/pillowmc/shearapi/withpillow/client/ShearAPIWithPillowClient.java b/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java similarity index 72% rename from shearapi-withpillow/src/client/java/net/pillowmc/shearapi/withpillow/client/ShearAPIWithPillowClient.java rename to shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java index 1e58c0d..79b34d6 100644 --- a/shearapi-withpillow/src/client/java/net/pillowmc/shearapi/withpillow/client/ShearAPIWithPillowClient.java +++ b/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java @@ -1,4 +1,4 @@ -package net.pillowmc.shearapi.withpillow.client; +package net.pillowmc.shearapi.fmlstuff.client; import net.minecraft.client.Minecraft; import net.neoforged.bus.api.SubscribeEvent; @@ -13,21 +13,21 @@ import java.util.Optional; -public class ShearAPIWithPillowClient { - public static Class clazz = ShearAPIWithPillowClient.class; +public class ShearAPIFMLStuffClient { + public static Class clazz = ShearAPIFMLStuffClient.class; @SubscribeEvent public static void onRegisterPayloadHandlerEvent(RegisterPayloadHandlerEvent event) { if (!(ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow)) { return; } final IPayloadRegistrar registrar = event.registrar(ShearAPIRuntime.MOD_ID) - .versioned(ShearAPIVersion.getSpec()) - .optional(); + .versioned(ShearAPIVersion.getSpec()) + .optional(); registrar - .configuration( - ConfigFilePayload.ID, - ConfigFilePayload::new, - handlers -> handlers.client(ShearAPIWithPillowClient::handleConfigFile)); + .configuration( + ConfigFilePayload.ID, + ConfigFilePayload::new, + handlers -> handlers.client(ShearAPIFMLStuffClient::handleConfigFile)); } private static void handleConfigFile(ConfigFilePayload payload, IPayloadContext context) { diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java similarity index 100% rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/event/ModMismatchEvent.java diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/ConfigSync.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/ConfigSync.java similarity index 100% rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/ConfigSync.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/ConfigSync.java diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java similarity index 100% rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncConfig.java diff --git a/shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java similarity index 100% rename from shearapi-withpillow/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/ConfigFilePayload.java diff --git a/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java b/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java new file mode 100644 index 0000000..8346126 --- /dev/null +++ b/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java @@ -0,0 +1,19 @@ +package net.pillowmc.shearapi.fmlstuff; + +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.network.configuration.SyncConfig; +import net.neoforged.neoforge.network.event.OnGameConfigurationEvent; +import net.neoforged.neoforge.network.payload.ConfigFilePayload; +import net.pillowmc.shearapi.runtime.ShearAPIRuntime; +import net.pillowmc.shearapi.withpillow.ShearAPIWithPillow; + +public class ShearAPIFMLStuff { + public static Class clazz = ShearAPIFMLStuff.class; + + @SubscribeEvent + public static void onGameConfigurationEvent(OnGameConfigurationEvent event) { + if (event.getListener().isConnected(ConfigFilePayload.ID) && ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow) { + event.register(new SyncConfig(event.getListener())); + } + } +} diff --git a/shearapi-fmlstuff/src/main/resources/assets/shearapi-fmlstuff/icon.png b/shearapi-fmlstuff/src/main/resources/assets/shearapi-fmlstuff/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a1d73a6662ea8060ffad89e0f2235f4bd608d4e7 GIT binary patch literal 13899 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 WOGS*{p@8vSeQ7Z zm9!*g5k>e$ppU*RpHM!^h<{ntpXB~UlXc3i)x>iU>j+SRV-6)3$~cZS7jr{z-J7*} zCHrRiE>gB*>$4e9QKGErkf`_v`&Er@_BoSFk5@^|S^s3Ub)l}>`xkXxZ-k^fu(7}e z^#-Y-}xUrGlh=)nVd6KmX{Bcgabwk-3ay_vHq&2(w6TY65X3L3(utO#SSDSNa z5dVnb9_xvDn%5B=u}17`-1z~-L-{&H(qmLm>;-#hakKL5PKL6IG6hFT%i%*KG;kF7 z)S?1nQ7M->CA|^*%M=VX1zYUG;%v`7+m-qdmOW<@_L_)CYLx*o=g*bFS(6Fu&{?`y zh|&3rb4DYBmVpub{7ZwG}Y6evH4sGQX>^F~kuS zqZ+5DE7%Zs(Y=9PxHS*;&R1PP7*$W#rHsFA-oq~3!W%Mlu zA);@@Q+Q^AJ?(pNhcI@e^!L4Qy}w`@t3L}a&U3k%u0XW$*b{nioE?oM2=tA<`+#O+ z&@QX{Fv47|ypXUJp|=-p&hDwJOYxV~%J~KR0@o2XO?~AutljF(&%Ufl9e3zL+ms)P z$a)64Jj+PQH5D^(9I!iiE&;Qwutgf1uP0}NMMT9d%Pe+2K6-VjBV(Hs7kWuECx!@?~kOf1zuK8nW{Gye*M z%y#rX%KQn9NuaEHr&99K@ z{%aB5_c}Ay-C`5L>idKqQZs{C`AwI7uD!7cX@Cp^;!@7~F6l2%vQ6`s;@TMQ+LI8t zibjG>(Xs(1m9vc7AjktoI-Ka?fl&ZTDai7hz0j4kazuR#EaW86_JxImZZ^mSAIXrm z)4s``O;zqNZ-1vw>(d!be_*M=zqdLb)VEv46lq1676QKfQVX2bRAF#*90=h+9*ACU z!zCIB^w^~TVd*B=&`BX$0iOAm`pXlg2;>x?8p)>P^GQKc=5PZCvljR*8~U?|*1K}4 zBHsVm5BdfeGMPzdJ&gw;d&B;NxnGe;ET-Jb;)#l25sl@q^B%0%lgYIGrK^D|UdD|6TO||DJvphK*tMBFaqv S0(?6RBqOOHQ6XmF|9=2|mMORZ literal 0 HcmV?d00001 diff --git a/shearapi-fmlstuff/src/main/resources/fabric.mod.json b/shearapi-fmlstuff/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..c9a5604 --- /dev/null +++ b/shearapi-fmlstuff/src/main/resources/fabric.mod.json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "id": "shearapi-fmlstuff", + "version": "${version}", + "name": "Shear API (FML Stuff)", + "description": "Deal with stuff things if FML installed", + "authors": [ + "PillowMC" + ], + "contact": { + "homepage": "https://github.com/PillowMC/ShearAPI", + "sources": "https://github.com/PillowMC/ShearAPI" + }, + "license": "LGPL-2.1", + "icon": "assets/shearapi-fmlstuff/icon.png", + "environment": "*", + "depends": { + "fabricloader": ">=0.15.6", + "minecraft": "~1.20.4", + "java": ">=17", + "fabric-api": "*", + "shearapi-runtime": "~${version}", + "shearapi-network": "~${version}", + "shearapi-withpillow": "~${version}" + }, + "entrypoints": { + "shearapi-runtime:client_mod_bus_subscriber": ["net.pillowmc.shearapi.fmlstuff.client.ShearAPIFMLStuffClient::clazz"], + "shearapi-runtime:mod_bus_subscriber": ["net.pillowmc.shearapi.fmlstuff.ShearAPIFMLStuff::clazz"] + }, + "custom": { + "modmenu": { + "parent": "shearapi", + "badges": ["library"] + } + } +} diff --git a/shearapi-withpillow/build.gradle b/shearapi-withpillow/build.gradle index fd95694..d7df97c 100644 --- a/shearapi-withpillow/build.gradle +++ b/shearapi-withpillow/build.gradle @@ -9,5 +9,4 @@ dependencies { implementation "net.neoforged.fancymodloader:loader:${project.fancy_mod_loader_version}" api project(path: ":shearapi-runtime", configuration: "namedElements") api project(path: ":shearapi-withoutpillow", configuration: "namedElements") - api project(path: ":shearapi-network", configuration: "namedElements") } diff --git a/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java b/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java index 78e2f9e..0676729 100644 --- a/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java +++ b/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java @@ -1,25 +1,13 @@ package net.pillowmc.shearapi.withpillow; import net.neoforged.bus.api.Event; -import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.ModList; import net.neoforged.fml.ModLoader; import net.neoforged.fml.loading.FMLLoader; -import net.neoforged.neoforge.network.configuration.SyncConfig; -import net.neoforged.neoforge.network.event.OnGameConfigurationEvent; -import net.neoforged.neoforge.network.payload.ConfigFilePayload; import net.pillowmc.shearapi.runtime.IModBusEvent; import net.pillowmc.shearapi.withoutpillow.ShearAPIWithoutPillow; public class ShearAPIWithPillow extends ShearAPIWithoutPillow { - public static Class clazz = ShearAPIWithPillow.class; - - @SubscribeEvent - public static void onGameConfigurationEvent(OnGameConfigurationEvent event) { - if (event.getListener().isConnected(ConfigFilePayload.ID)) { - event.register(new SyncConfig(event.getListener())); - } - } @Override public boolean isProduction() { diff --git a/shearapi-withpillow/src/main/resources/fabric.mod.json b/shearapi-withpillow/src/main/resources/fabric.mod.json index ec6c066..8f7e6bc 100644 --- a/shearapi-withpillow/src/main/resources/fabric.mod.json +++ b/shearapi-withpillow/src/main/resources/fabric.mod.json @@ -21,10 +21,6 @@ "fabric-api": "*", "shearapi-runtime": "~${version}" }, - "entrypoints": { - "shearapi-runtime:client_mod_bus_subscriber": ["net.pillowmc.shearapi.withpillow.client.ShearAPIWithPillowClient::clazz"], - "shearapi-runtime:mod_bus_subscriber": ["net.pillowmc.shearapi.withpillow.ShearAPIWithPillow::clazz"] - }, "mixins": [ "shearapi-withpillow.mixins.json" ], From 2fb9af001837a98194c93118077a4fc8bad55480 Mon Sep 17 00:00:00 2001 From: Hei Piao Date: Fri, 2 May 2025 21:26:21 +0800 Subject: [PATCH 5/5] wip: port a little more for shearapi-network --- .../client/ShearAPIFMLStuffClient.java | 67 +++++++++++++++- .../network/configuration/SyncRegistries.java | 2 +- .../payload/FrozenRegistryPayload.java | 0 .../FrozenRegistrySyncCompletedPayload.java | 0 .../FrozenRegistrySyncStartPayload.java | 0 .../shearapi/fmlstuff/ShearAPIFMLStuff.java | 34 ++++++++ .../src/main/resources/fabric.mod.json | 1 + .../handlers/ClientPayloadHandler.java | 65 +-------------- .../network/client/DualStackUtilsClient.java | 28 +++++++ .../network/client/ShearAPINetworkClient.java | 30 ++----- .../network/ConfigurationInitialization.java | 52 +++++------- .../neoforge/network/DualStackUtils.java | 23 +----- .../neoforge/network/PacketDistributor.java | 13 +-- .../SyncTierSortingRegistry.java | 70 ++++++++-------- .../filters/GenericPacketSplitter.java | 3 +- .../VanillaConnectionNetworkFilter.java | 22 +++-- .../handlers/ServerPayloadHandler.java | 58 ++++++-------- .../NetworkComponentNegotiator.java | 8 +- .../payload/TierSortingRegistryPayload.java | 80 +++++++++---------- ...ierSortingRegistrySyncCompletePayload.java | 64 +++++++-------- .../IServerGamePacketListenerExtension.java | 2 +- .../src/main/resources/fabric.mod.json | 4 +- .../neoforge/registries/RegistryManager.java | 6 +- .../registries/ShearAPIRegistries.java | 13 +++ .../shearapi-registries.accesswidener | 3 + .../pillowmc/shearapi/runtime/IRuntime.java | 3 + .../utils/mixin/client/MinecraftMixin.java | 17 +++- .../utils/mixin/client/UtilsMixin.java | 21 +++++ .../shearapi-utils.client.mixin.json | 5 +- .../pillowmc/shearapi/utils/IClientLike.java | 4 +- .../net/pillowmc/shearapi/utils/Utils.java | 4 + .../withoutpillow/ShearAPIWithoutPillow.java | 7 ++ .../withpillow/ShearAPIWithPillow.java | 10 +++ 33 files changed, 416 insertions(+), 303 deletions(-) rename {shearapi-network => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java (97%) rename {shearapi-network => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java (100%) rename {shearapi-network => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java (100%) rename {shearapi-network => shearapi-fmlstuff}/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java (100%) create mode 100644 shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/DualStackUtilsClient.java create mode 100644 shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/UtilsMixin.java diff --git a/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java b/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java index 79b34d6..4af4f38 100644 --- a/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java +++ b/shearapi-fmlstuff/src/client/java/net/pillowmc/shearapi/fmlstuff/client/ShearAPIFMLStuffClient.java @@ -1,20 +1,43 @@ package net.pillowmc.shearapi.fmlstuff.client; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import net.fabricmc.api.ClientModInitializer; import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.config.ConfigTracker; import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent; +import net.neoforged.neoforge.network.handlers.ClientPayloadHandler; +import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext; import net.neoforged.neoforge.network.handling.IPayloadContext; import net.neoforged.neoforge.network.payload.ConfigFilePayload; +import net.neoforged.neoforge.network.payload.FrozenRegistryPayload; +import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; +import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload; import net.neoforged.neoforge.network.registration.IPayloadRegistrar; +import net.pillowmc.shearapi.fmlstuff.ShearAPIFMLStuff; import net.pillowmc.shearapi.runtime.ShearAPIRuntime; import net.pillowmc.shearapi.runtime.ShearAPIVersion; import net.pillowmc.shearapi.withpillow.ShearAPIWithPillow; +import java.util.Map; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; -public class ShearAPIFMLStuffClient { +public class ShearAPIFMLStuffClient implements ClientModInitializer { public static Class clazz = ShearAPIFMLStuffClient.class; + private static final Map synchronizedRegistries = Maps.newConcurrentMap(); + private static final Set toSynchronize = Sets.newConcurrentHashSet(); + + @Override + public void onInitializeClient() { + ShearAPIFMLStuff.clientHandleRegistrySyncCompleted = ShearAPIFMLStuffClient::handleRegistrySyncCompleted; + } + @SubscribeEvent public static void onRegisterPayloadHandlerEvent(RegisterPayloadHandlerEvent event) { if (!(ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow)) { @@ -24,6 +47,14 @@ public static void onRegisterPayloadHandlerEvent(RegisterPayloadHandlerEvent eve .versioned(ShearAPIVersion.getSpec()) .optional(); registrar + .configuration( + FrozenRegistrySyncStartPayload.ID, + FrozenRegistrySyncStartPayload::new, + handlers -> handlers.client(ShearAPIFMLStuffClient::handleRegistrySyncStart)) + .configuration( + FrozenRegistryPayload.ID, + FrozenRegistryPayload::new, + handlers -> handlers.client(ShearAPIFMLStuffClient::handleFrozenRegistry)) .configuration( ConfigFilePayload.ID, ConfigFilePayload::new, @@ -37,4 +68,38 @@ private static void handleConfigFile(ConfigFilePayload payload, IPayloadContext ).ifPresent(mc -> mc.acceptSyncedConfig(payload.contents())); } } + + public static void handleFrozenRegistry(FrozenRegistryPayload payload, ConfigurationPayloadContext context) { + synchronizedRegistries.put(payload.registryName(), payload.snapshot()); + toSynchronize.remove(payload.registryName()); + } + + public static void handleRegistrySyncStart(FrozenRegistrySyncStartPayload payload, ConfigurationPayloadContext context) { + toSynchronize.addAll(payload.toAccess()); + synchronizedRegistries.clear(); + } + + public static void handleRegistrySyncCompleted(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) { + if (!toSynchronize.isEmpty()) { + context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.missing", this.toSynchronize.stream().map(Object::toString).collect(Collectors.joining(", ")))); + return; + } + + context.workHandler().submitAsync(() -> { + //This method normally returns missing entries, but we just accept what the server send us and ignore the rest. + Set> keysUnknownToClient = RegistryManager.applySnapshot(synchronizedRegistries, false, false); + if (!keysUnknownToClient.isEmpty()) { + context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.server-with-unknown-keys", keysUnknownToClient.stream().map(Object::toString).collect(Collectors.joining(", ")))); + return; + } + + toSynchronize.clear(); + synchronizedRegistries.clear(); + }).exceptionally(e -> { + context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.failed", e.getMessage())); + return null; + }).thenAccept(v -> { + context.replyHandler().send(new FrozenRegistrySyncCompletedPayload()); + }); + } } diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java similarity index 97% rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java index 8374471..9a000bc 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java +++ b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/configuration/SyncRegistries.java @@ -24,7 +24,7 @@ @ApiStatus.Internal public record SyncRegistries() implements ICustomConfigurationTask { private static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "sync_registries"); - public static final Type TYPE = new Type(ID); + public static final Type TYPE = new Type(ID.toString()); @Override public void run(Consumer sender) { diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java similarity index 100% rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistryPayload.java diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java similarity index 100% rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncCompletedPayload.java diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java b/shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java similarity index 100% rename from shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java rename to shearapi-fmlstuff/src/main/java/net/neoforged/neoforge/network/payload/FrozenRegistrySyncStartPayload.java diff --git a/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java b/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java index 8346126..6d5b766 100644 --- a/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java +++ b/shearapi-fmlstuff/src/main/java/net/pillowmc/shearapi/fmlstuff/ShearAPIFMLStuff.java @@ -2,18 +2,52 @@ import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.neoforge.network.configuration.SyncConfig; +import net.neoforged.neoforge.network.configuration.SyncRegistries; import net.neoforged.neoforge.network.event.OnGameConfigurationEvent; +import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent; +import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext; +import net.neoforged.neoforge.network.handling.IConfigurationPayloadHandler; import net.neoforged.neoforge.network.payload.ConfigFilePayload; +import net.neoforged.neoforge.network.payload.FrozenRegistryPayload; +import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; +import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload; +import net.neoforged.neoforge.network.registration.IPayloadRegistrar; import net.pillowmc.shearapi.runtime.ShearAPIRuntime; +import net.pillowmc.shearapi.runtime.ShearAPIVersion; import net.pillowmc.shearapi.withpillow.ShearAPIWithPillow; public class ShearAPIFMLStuff { public static Class clazz = ShearAPIFMLStuff.class; + public static IConfigurationPayloadHandler clientHandleRegistrySyncCompleted; @SubscribeEvent public static void onGameConfigurationEvent(OnGameConfigurationEvent event) { + if (event.getListener().isConnected(FrozenRegistrySyncStartPayload.ID) && + event.getListener().isConnected(FrozenRegistryPayload.ID) && + event.getListener().isConnected(FrozenRegistrySyncCompletedPayload.ID)) { + event.register(new SyncRegistries()); + } if (event.getListener().isConnected(ConfigFilePayload.ID) && ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow) { event.register(new SyncConfig(event.getListener())); } } + @SubscribeEvent + public static void onRegisterPayloadHandlerEvent(RegisterPayloadHandlerEvent event) { + if (!(ShearAPIRuntime.getRuntime() instanceof ShearAPIWithPillow)) { + return; + } + final IPayloadRegistrar registrar = event.registrar(ShearAPIRuntime.MOD_ID) + .versioned(ShearAPIVersion.getSpec()) + .optional(); + registrar + .configuration( + FrozenRegistrySyncCompletedPayload.ID, + FrozenRegistrySyncCompletedPayload::new, + handlers -> handlers.client(clientHandleRegistrySyncCompleted) + .server(ShearAPIFMLStuff::handleRegistrySyncCompleted)); + } + + public static void handleRegistrySyncCompleted(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) { + context.taskCompletedHandler().onTaskCompleted(SyncRegistries.TYPE); + } } diff --git a/shearapi-fmlstuff/src/main/resources/fabric.mod.json b/shearapi-fmlstuff/src/main/resources/fabric.mod.json index c9a5604..bc50548 100644 --- a/shearapi-fmlstuff/src/main/resources/fabric.mod.json +++ b/shearapi-fmlstuff/src/main/resources/fabric.mod.json @@ -24,6 +24,7 @@ "shearapi-withpillow": "~${version}" }, "entrypoints": { + "client": ["net.pillowmc.shearapi.fmlstuff.client.ShearAPIFMLStuffClient"], "shearapi-runtime:client_mod_bus_subscriber": ["net.pillowmc.shearapi.fmlstuff.client.ShearAPIFMLStuffClient::clazz"], "shearapi-runtime:mod_bus_subscriber": ["net.pillowmc.shearapi.fmlstuff.ShearAPIFMLStuff::clazz"] }, diff --git a/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java b/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java index 95a7878..f89c7c3 100644 --- a/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java +++ b/shearapi-network/src/client/java/net/neoforged/neoforge/network/handlers/ClientPayloadHandler.java @@ -5,39 +5,21 @@ package net.neoforged.neoforge.network.handlers; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import io.netty.buffer.Unpooled; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.MenuScreens; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.MenuAccess; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.MenuType; -import net.neoforged.neoforge.common.TierSortingRegistry; import net.neoforged.neoforge.common.world.AuxiliaryLightManager; import net.neoforged.neoforge.common.world.LevelChunkAuxiliaryLightManager; -import net.neoforged.neoforge.network.ConfigSync; -import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext; -import net.neoforged.neoforge.network.handling.IPayloadContext; import net.neoforged.neoforge.network.handling.PlayPayloadContext; import net.neoforged.neoforge.network.payload.AdvancedContainerSetDataPayload; import net.neoforged.neoforge.network.payload.AdvancedOpenScreenPayload; import net.neoforged.neoforge.network.payload.AuxiliaryLightDataPayload; -import net.neoforged.neoforge.network.payload.ConfigFilePayload; -import net.neoforged.neoforge.network.payload.FrozenRegistryPayload; -import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; -import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload; -import net.neoforged.neoforge.network.payload.TierSortingRegistryPayload; -import net.neoforged.neoforge.registries.RegistryManager; -import net.neoforged.neoforge.registries.RegistrySnapshot; import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal @@ -48,52 +30,11 @@ public static ClientPayloadHandler getInstance() { return INSTANCE; } - private final Set toSynchronize = Sets.newConcurrentHashSet(); - private final Map synchronizedRegistries = Maps.newConcurrentMap(); - private ClientPayloadHandler() {} - public void handle(FrozenRegistryPayload payload, ConfigurationPayloadContext context) { - synchronizedRegistries.put(payload.registryName(), payload.snapshot()); - toSynchronize.remove(payload.registryName()); - } - - public void handle(FrozenRegistrySyncStartPayload payload, ConfigurationPayloadContext context) { - this.toSynchronize.addAll(payload.toAccess()); - this.synchronizedRegistries.clear(); - } - - public void handle(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) { - if (!this.toSynchronize.isEmpty()) { - context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.missing", this.toSynchronize.stream().map(Object::toString).collect(Collectors.joining(", ")))); - return; - } - - context.workHandler().submitAsync(() -> { - //This method normally returns missing entries, but we just accept what the server send us and ignore the rest. - Set> keysUnknownToClient = RegistryManager.applySnapshot(synchronizedRegistries, false, false); - if (!keysUnknownToClient.isEmpty()) { - context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.server-with-unknown-keys", keysUnknownToClient.stream().map(Object::toString).collect(Collectors.joining(", ")))); - return; - } - - this.toSynchronize.clear(); - this.synchronizedRegistries.clear(); - }).exceptionally(e -> { - context.packetHandler().disconnect(Component.translatable("neoforge.network.registries.sync.failed", e.getMessage())); - return null; - }).thenAccept(v -> { - context.replyHandler().send(new FrozenRegistrySyncCompletedPayload()); - }); - } - - public void handle(ConfigFilePayload payload, IPayloadContext context) { - ConfigSync.INSTANCE.receiveSyncedConfig(payload.contents(), payload.fileName()); - } - - public void handle(TierSortingRegistryPayload payload, IPayloadContext context) { - TierSortingRegistry.handleSync(payload, context); - } +// public void handle(TierSortingRegistryPayload payload, IPayloadContext context) { +// TierSortingRegistry.handleSync(payload, context); +// } public void handle(AdvancedOpenScreenPayload msg, PlayPayloadContext context) { context.workHandler().submitAsync(() -> { diff --git a/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/DualStackUtilsClient.java b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/DualStackUtilsClient.java new file mode 100644 index 0000000..d176779 --- /dev/null +++ b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/DualStackUtilsClient.java @@ -0,0 +1,28 @@ +package net.pillowmc.shearapi.network.client; + +import net.minecraft.client.multiplayer.resolver.ResolvedServerAddress; +import net.minecraft.client.multiplayer.resolver.ServerAddress; +import net.minecraft.client.multiplayer.resolver.ServerNameResolver; +import net.neoforged.neoforge.network.DualStackUtils; + +import java.net.InetSocketAddress; +import java.util.Optional; + +public class DualStackUtilsClient { + + /** + * Resolve the address and see if Java and the OS return an IPv6 or IPv4 one, then let Netty know + * accordingly (it doesn't understand the {@code java.net.preferIPv6Addresses=system} property). + * + * @param hostAddress The address you want to check + * @return true if IPv6, false if IPv4 + */ + public static boolean checkIPv6(final String hostAddress) { + final Optional hostAddr = ServerNameResolver.DEFAULT + .resolveAddress(ServerAddress.parseString(hostAddress)) + .map(ResolvedServerAddress::asInetSocketAddress); + + if (hostAddr.isPresent()) return DualStackUtils.checkIPv6(hostAddr.get().getAddress()); + else return false; + } +} diff --git a/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java index 61304d8..ce3653a 100644 --- a/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java +++ b/shearapi-network/src/client/java/net/pillowmc/shearapi/network/client/ShearAPINetworkClient.java @@ -3,7 +3,6 @@ import net.fabricmc.api.ClientModInitializer; import net.neoforged.neoforge.network.event.RegisterPayloadHandlerEvent; import net.neoforged.neoforge.network.handlers.ClientPayloadHandler; -import net.neoforged.neoforge.network.handlers.ServerPayloadHandler; import net.neoforged.neoforge.network.payload.*; import net.neoforged.neoforge.network.registration.IPayloadRegistrar; import net.pillowmc.shearapi.runtime.ShearAPIRuntime; @@ -17,27 +16,14 @@ public void onInitializeClient() { .versioned(ShearAPIVersion.getSpec()) .optional(); registrar - .common( - TierSortingRegistryPayload.ID, - TierSortingRegistryPayload::new, - handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle)) - .configuration( - FrozenRegistrySyncStartPayload.ID, - FrozenRegistrySyncStartPayload::new, - handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle)) - .configuration( - FrozenRegistryPayload.ID, - FrozenRegistryPayload::new, - handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle)) - .configuration( - FrozenRegistrySyncCompletedPayload.ID, - FrozenRegistrySyncCompletedPayload::new, - handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle) - .server(ServerPayloadHandler.getInstance()::handle)) - .configuration( - TierSortingRegistrySyncCompletePayload.ID, - TierSortingRegistrySyncCompletePayload::new, - handlers -> handlers.server(ServerPayloadHandler.getInstance()::handle)) +// .common( +// TierSortingRegistryPayload.ID, +// TierSortingRegistryPayload::new, +// handlers -> handlers.client(ClientPayloadHandler.getInstance()::handle)) +// .configuration( +// TierSortingRegistrySyncCompletePayload.ID, +// TierSortingRegistrySyncCompletePayload::new, +// handlers -> handlers.server(ServerPayloadHandler.getInstance()::handle)) .play( AdvancedOpenScreenPayload.ID, AdvancedOpenScreenPayload::new, diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java index 5b2a00e..07f2be1 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/ConfigurationInitialization.java @@ -1,31 +1,21 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.network; - -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.neoforge.network.configuration.SyncRegistries; -import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry; -import net.neoforged.neoforge.network.event.OnGameConfigurationEvent; -import net.neoforged.neoforge.network.payload.FrozenRegistryPayload; -import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; -import net.neoforged.neoforge.network.payload.FrozenRegistrySyncStartPayload; -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public class ConfigurationInitialization { - public static Class clazz = ConfigurationInitialization.class; - @SubscribeEvent - private static void configureModdedClient(OnGameConfigurationEvent event) { - if (event.getListener().isConnected(FrozenRegistrySyncStartPayload.ID) && - event.getListener().isConnected(FrozenRegistryPayload.ID) && - event.getListener().isConnected(FrozenRegistrySyncCompletedPayload.ID)) { - event.register(new SyncRegistries()); - } - - //These two can always be registered they detect the listener connection type internally and will skip themselves. - event.register(new SyncTierSortingRegistry(event.getListener())); - } -} +///* +// * Copyright (c) NeoForged and contributors +// * SPDX-License-Identifier: LGPL-2.1-only +// */ +// +//package net.neoforged.neoforge.network; +// +//import net.neoforged.bus.api.SubscribeEvent; +//import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry; +//import net.neoforged.neoforge.network.event.OnGameConfigurationEvent; +//import org.jetbrains.annotations.ApiStatus; +// +//@ApiStatus.Internal +//public class ConfigurationInitialization { +// public static Class clazz = ConfigurationInitialization.class; +// @SubscribeEvent +// private static void configureModdedClient(OnGameConfigurationEvent event) { +// //These two can always be registered they detect the listener connection type internally and will skip themselves. +// event.register(new SyncTierSortingRegistry(event.getListener())); +// } +//} diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java index 40ce896..5f18564 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/DualStackUtils.java @@ -13,13 +13,8 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.UnknownHostException; -import java.util.Optional; import javax.annotation.Nullable; -import net.minecraft.client.multiplayer.resolver.ResolvedServerAddress; -import net.minecraft.client.multiplayer.resolver.ServerAddress; -import net.minecraft.client.multiplayer.resolver.ServerNameResolver; import net.minecraft.util.HttpUtil; -import net.neoforged.neoforge.common.NeoForge; import org.jetbrains.annotations.ApiStatus; import org.slf4j.Logger; @@ -37,22 +32,6 @@ public class DualStackUtils { @ApiStatus.Internal public static void initialise() {} - /** - * Resolve the address and see if Java and the OS return an IPv6 or IPv4 one, then let Netty know - * accordingly (it doesn't understand the {@code java.net.preferIPv6Addresses=system} property). - * - * @param hostAddress The address you want to check - * @return true if IPv6, false if IPv4 - */ - public static boolean checkIPv6(final String hostAddress) { - final Optional hostAddr = ServerNameResolver.DEFAULT - .resolveAddress(ServerAddress.parseString(hostAddress)) - .map(ResolvedServerAddress::asInetSocketAddress); - - if (hostAddr.isPresent()) return checkIPv6(hostAddr.get().getAddress()); - else return false; - } - /** * Checks if an address is an IPv6 one or an IPv4 one, lets Netty know accordingly and returns the result. * @@ -123,7 +102,7 @@ public static InetAddress getLocalAddress() { /** * Used for the "Open to LAN" feature. - * + * * @return The multicast group to use for LAN discovery - IPv6 if available, IPv4 otherwise. */ public static String getMulticastGroup() { diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java index e6d404c..ecb9f8f 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/PacketDistributor.java @@ -12,7 +12,6 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import net.minecraft.client.Minecraft; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketFlow; import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; @@ -27,7 +26,9 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.chunk.LevelChunk; +import net.pillowmc.shearapi.utils.IClientLike; import net.pillowmc.shearapi.utils.ServerUtils; +import net.pillowmc.shearapi.utils.Utils; /** * Means to distribute packets in various ways @@ -111,7 +112,7 @@ public TargetPoint(final ServerPlayer excluded, final double x, final double y, /** * A target point without excluded entity - * + * * @param x X * @param y Y * @param z Z @@ -129,7 +130,7 @@ public TargetPoint(final double x, final double y, final double z, final double /** * Helper to build a TargetPoint without excluded Entity - * + * * @param x X * @param y Y * @param z Z @@ -167,7 +168,7 @@ public void send(CustomPacketPayload... payloads) { for (CustomPacketPayload payload : payloads) { packets.add(new ClientboundCustomPayloadPacket(payload)); } - this.send(new ClientboundBundlePacket(packets)); + this.send(new ClientboundBundlePacket((Iterable>)(Object) packets)); } else if (payloads.length == 1) { this.send(new ClientboundCustomPayloadPacket(payloads[0])); } @@ -197,7 +198,7 @@ public PacketDistributor(Function, Consumer>> fun /** * Apply the supplied value to the specific distributor to generate an instance for sending packets to. - * + * * @param input The input to apply * @return A curried instance */ @@ -229,7 +230,7 @@ private Consumer> playerListAll() { } private Consumer> clientToServer() { - return p -> Objects.requireNonNull(Minecraft.getInstance().getConnection()).send(p); + return p -> Utils.getClient().ifPresent(c -> c.shearAPI$sendPacket(p)); } private Consumer> playerListPointConsumer(final TargetPoint targetPoint) { diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java index d6e8d5f..8a8e03f 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/configuration/SyncTierSortingRegistry.java @@ -1,35 +1,35 @@ -/* - * 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.network.protocol.configuration.ServerConfigurationPacketListener; -import net.minecraft.resources.ResourceLocation; -import net.neoforged.neoforge.common.TierSortingRegistry; -import net.pillowmc.shearapi.runtime.ShearAPIRuntime; -import org.jetbrains.annotations.ApiStatus; - -/** - * Syncs the tier sorting registry to the client - * - * @param listener the listener to indicate the check if it is a vanilla connection - */ -@ApiStatus.Internal -public record SyncTierSortingRegistry(ServerConfigurationPacketListener listener) implements ICustomConfigurationTask { - private static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "sync_tier_sorting"); - public static final Type TYPE = new Type(ID); - - @Override - public void run(Consumer sender) { - TierSortingRegistry.sync(listener(), sender); - } - - @Override - public Type type() { - return TYPE; - } -} +///* +// * 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.network.protocol.configuration.ServerConfigurationPacketListener; +//import net.minecraft.resources.ResourceLocation; +//import net.neoforged.neoforge.common.TierSortingRegistry; +//import net.pillowmc.shearapi.runtime.ShearAPIRuntime; +//import org.jetbrains.annotations.ApiStatus; +// +///** +// * Syncs the tier sorting registry to the client +// * +// * @param listener the listener to indicate the check if it is a vanilla connection +// */ +//@ApiStatus.Internal +//public record SyncTierSortingRegistry(ServerConfigurationPacketListener listener) implements ICustomConfigurationTask { +// private static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "sync_tier_sorting"); +// public static final Type TYPE = new Type(ID.toString()); +// +// @Override +// public void run(Consumer sender) { +// TierSortingRegistry.sync(listener(), sender); +// } +// +// @Override +// public Type type() { +// return TYPE; +// } +//} diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java index b02ef66..17ddcb2 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/GenericPacketSplitter.java @@ -27,7 +27,6 @@ import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; import net.pillowmc.shearapi.runtime.ShearAPIRuntime; import net.neoforged.neoforge.network.connection.ConnectionPhase; import net.neoforged.neoforge.network.connection.ConnectionType; @@ -43,9 +42,9 @@ /** * A generic packet splitter that can be used to split packets that are too large to be sent in one go. */ -@Mod.EventBusSubscriber(modid = ShearAPIRuntime.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) @ApiStatus.Internal public class GenericPacketSplitter extends MessageToMessageEncoder> implements DynamicChannelHandler { + public static Class clazz = GenericPacketSplitter.class; private static final Logger LOGGER = LogManager.getLogger(); private static final int MAX_PACKET_SIZE = CompressionDecoder.MAXIMUM_UNCOMPRESSED_LENGTH; diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java index 2885b07..aa3b5ae 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/filters/VanillaConnectionNetworkFilter.java @@ -9,9 +9,12 @@ import com.mojang.brigadier.tree.RootCommandNode; import com.mojang.logging.LogUtils; import io.netty.channel.ChannelHandler; + +import java.lang.reflect.InvocationTargetException; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.stream.Collectors; import net.minecraft.commands.CommandBuildContext; @@ -33,7 +36,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagNetworkSerialization; import net.neoforged.neoforge.network.connection.ConnectionType; -import net.neoforged.neoforge.registries.RegistryManager; +import net.pillowmc.shearapi.runtime.ShearAPIRuntime; import org.slf4j.Logger; /** @@ -51,7 +54,7 @@ public VanillaConnectionNetworkFilter(ConnectionType connectionType) { ImmutableMap.>, BiConsumer, List>>>builder() .put(handler(ClientboundUpdateAttributesPacket.class, VanillaConnectionNetworkFilter::filterEntityProperties)) .put(handler(ClientboundCommandsPacket.class, VanillaConnectionNetworkFilter::filterCommandList)) - .put(handler(ClientboundUpdateTagsPacket.class, VanillaConnectionNetworkFilter::filterCustomTagTypes)) + .putAll(getFilterCustomTagTypes().stream().toList()) .build()); this.connectionType = connectionType; @@ -95,6 +98,11 @@ private static ClientboundCommandsPacket filterCommandList(ClientboundCommandsPa return new ClientboundCommandsPacket(newRoot); } + private static Optional>, BiConsumer, List>>>> getFilterCustomTagTypes() { + if (!ShearAPIRuntime.getRuntime().isModLoaded("shearapi-registries")) return Optional.empty(); + return Optional.of(handler(ClientboundUpdateTagsPacket.class, VanillaConnectionNetworkFilter::filterCustomTagTypes)); + } + /** * Filters out custom tag types that the vanilla client won't recognize. * It prevents a rare error from logging and reduces the packet size @@ -107,8 +115,12 @@ private static ClientboundUpdateTagsPacket filterCustomTagTypes(ClientboundUpdat } private static boolean isVanillaRegistry(ResourceLocation location) { - // Checks if the registry name is contained within the static view of both BuiltInRegistries and VanillaRegistries - return RegistryManager.getVanillaRegistryKeys().contains(location) - || VanillaRegistries.DATAPACK_REGISTRY_KEYS.stream().anyMatch(k -> k.location().equals(location)); + try { + return (Boolean)Class.forName("net.pillowmc.shearapi.registries.ShearAPIRegistries") + .getMethod("isVanillaRegistry", ResourceLocation.class) + .invoke(null, location); + } catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } } } diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java index ee1d298..572871c 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/handlers/ServerPayloadHandler.java @@ -1,32 +1,26 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.network.handlers; - -import net.neoforged.neoforge.network.configuration.SyncRegistries; -import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry; -import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext; -import net.neoforged.neoforge.network.payload.FrozenRegistrySyncCompletedPayload; -import net.neoforged.neoforge.network.payload.TierSortingRegistrySyncCompletePayload; -import org.jetbrains.annotations.ApiStatus; - -@ApiStatus.Internal -public class ServerPayloadHandler { - private static final ServerPayloadHandler INSTANCE = new ServerPayloadHandler(); - - public static ServerPayloadHandler getInstance() { - return INSTANCE; - } - - private ServerPayloadHandler() {} - - public void handle(FrozenRegistrySyncCompletedPayload payload, ConfigurationPayloadContext context) { - context.taskCompletedHandler().onTaskCompleted(SyncRegistries.TYPE); - } - - public void handle(TierSortingRegistrySyncCompletePayload payload, ConfigurationPayloadContext context) { - context.taskCompletedHandler().onTaskCompleted(SyncTierSortingRegistry.TYPE); - } -} +///* +// * Copyright (c) NeoForged and contributors +// * SPDX-License-Identifier: LGPL-2.1-only +// */ +// +//package net.neoforged.neoforge.network.handlers; +// +//import net.neoforged.neoforge.network.configuration.SyncTierSortingRegistry; +//import net.neoforged.neoforge.network.handling.ConfigurationPayloadContext; +//import net.neoforged.neoforge.network.payload.TierSortingRegistrySyncCompletePayload; +//import org.jetbrains.annotations.ApiStatus; +// +//@ApiStatus.Internal +//public class ServerPayloadHandler { +// private static final ServerPayloadHandler INSTANCE = new ServerPayloadHandler(); +// +// public static ServerPayloadHandler getInstance() { +// return INSTANCE; +// } +// +// private ServerPayloadHandler() {} +// +// public void handle(TierSortingRegistrySyncCompletePayload payload, ConfigurationPayloadContext context) { +// context.taskCompletedHandler().onTaskCompleted(SyncTierSortingRegistry.TYPE); +// } +//} diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java index 15abfda..6ea9ad0 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/negotiation/NetworkComponentNegotiator.java @@ -14,7 +14,7 @@ import java.util.Optional; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.neoforged.fml.ModList; +import net.pillowmc.shearapi.runtime.ShearAPIRuntime; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; @@ -80,7 +80,7 @@ public static NegotiationResult negotiate(List serve final Map failureReasons = new HashMap<>(); client.forEach(c -> { Component channelFailureReason = Component.translatable("neoforge.network.negotiation.failure.missing.client.server"); - String modDisplayName = ModList.get().getModContainerById(c.id().getNamespace()).map(mc -> mc.getModInfo().getDisplayName()).orElse(""); + String modDisplayName = ShearAPIRuntime.getRuntime().getModDisplayName(c.id().getNamespace()).orElse(""); failureReasons.put(c.id(), modDisplayName.isEmpty() ? channelFailureReason : Component.translatable("neoforge.network.negotiation.failure.mod", modDisplayName, channelFailureReason)); }); return new NegotiationResult(List.of(), false, failureReasons); @@ -90,7 +90,7 @@ public static NegotiationResult negotiate(List serve final Map failureReasons = new HashMap<>(); server.forEach(c -> { Component channelFailureReason = Component.translatable("neoforge.network.negotiation.failure.missing.server.client"); - String modDisplayName = ModList.get().getModContainerById(c.id().getNamespace()).map(mc -> mc.getModInfo().getDisplayName()).orElse(""); + String modDisplayName = ShearAPIRuntime.getRuntime().getModDisplayName(c.id().getNamespace()).orElse(""); failureReasons.put(c.id(), modDisplayName.isEmpty() ? channelFailureReason : Component.translatable("neoforge.network.negotiation.failure.mod", modDisplayName, channelFailureReason)); }); return new NegotiationResult(List.of(), false, failureReasons); @@ -101,7 +101,7 @@ public static NegotiationResult negotiate(List serve for (Table.Cell match : matches.cellSet()) { final NegotiableNetworkComponent serverComponent = match.getColumnKey(); final NegotiableNetworkComponent clientComponent = match.getValue(); - final String modDisplayName = ModList.get().getModContainerById(serverComponent.id().getNamespace()).map(mc -> mc.getModInfo().getDisplayName()).orElse(""); + String modDisplayName = ShearAPIRuntime.getRuntime().getModDisplayName(serverComponent.id().getNamespace()).orElse(""); Optional serverToClientComparison = validateComponent(serverComponent, clientComponent, "client"); if (serverToClientComparison.isPresent() && !serverToClientComparison.get().success()) { diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java index da71f81..f1f2c2f 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistryPayload.java @@ -1,40 +1,40 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.network.payload; - -import java.util.List; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.pillowmc.shearapi.runtime.ShearAPIRuntime; -import org.jetbrains.annotations.ApiStatus; - -/** - * The payload for the tier sorting registry packet. - *

- * This payload is used to send the tier order to the client. - *

- * - * @param tiers The tiers in order. - */ -@ApiStatus.Internal -public record TierSortingRegistryPayload(List tiers) implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting"); - - public TierSortingRegistryPayload(FriendlyByteBuf buf) { - this(buf.readList(FriendlyByteBuf::readResourceLocation)); - } - - @Override - public void write(FriendlyByteBuf buf) { - buf.writeCollection(tiers(), FriendlyByteBuf::writeResourceLocation); - } - - @Override - public ResourceLocation id() { - return ID; - } -} +///* +// * Copyright (c) NeoForged and contributors +// * SPDX-License-Identifier: LGPL-2.1-only +// */ +// +//package net.neoforged.neoforge.network.payload; +// +//import java.util.List; +//import net.minecraft.network.FriendlyByteBuf; +//import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +//import net.minecraft.resources.ResourceLocation; +//import net.pillowmc.shearapi.runtime.ShearAPIRuntime; +//import org.jetbrains.annotations.ApiStatus; +// +///** +// * The payload for the tier sorting registry packet. +// *

+// * This payload is used to send the tier order to the client. +// *

+// * +// * @param tiers The tiers in order. +// */ +//@ApiStatus.Internal +//public record TierSortingRegistryPayload(List tiers) implements CustomPacketPayload { +// public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting"); +// +// public TierSortingRegistryPayload(FriendlyByteBuf buf) { +// this(buf.readList(FriendlyByteBuf::readResourceLocation)); +// } +// +// @Override +// public void write(FriendlyByteBuf buf) { +// buf.writeCollection(tiers(), FriendlyByteBuf::writeResourceLocation); +// } +// +// @Override +// public ResourceLocation id() { +// return ID; +// } +//} diff --git a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java index 19fd02c..4d4c81f 100644 --- a/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java +++ b/shearapi-network/src/main/java/net/neoforged/neoforge/network/payload/TierSortingRegistrySyncCompletePayload.java @@ -1,32 +1,32 @@ -/* - * Copyright (c) NeoForged and contributors - * SPDX-License-Identifier: LGPL-2.1-only - */ - -package net.neoforged.neoforge.network.payload; - -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; -import net.pillowmc.shearapi.runtime.ShearAPIRuntime; -import org.jetbrains.annotations.ApiStatus; - -/** - * This payload is sent by the server to the client when the tier sorting registry has been fully synced. - */ -@ApiStatus.Internal -public record TierSortingRegistrySyncCompletePayload() implements CustomPacketPayload { - public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting_registry_sync_complete"); - - public TierSortingRegistrySyncCompletePayload(FriendlyByteBuf buf) { - this(); - } - - @Override - public void write(FriendlyByteBuf buf) {} - - @Override - public ResourceLocation id() { - return ID; - } -} +///* +// * Copyright (c) NeoForged and contributors +// * SPDX-License-Identifier: LGPL-2.1-only +// */ +// +//package net.neoforged.neoforge.network.payload; +// +//import net.minecraft.network.FriendlyByteBuf; +//import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +//import net.minecraft.resources.ResourceLocation; +//import net.pillowmc.shearapi.runtime.ShearAPIRuntime; +//import org.jetbrains.annotations.ApiStatus; +// +///** +// * This payload is sent by the server to the client when the tier sorting registry has been fully synced. +// */ +//@ApiStatus.Internal +//public record TierSortingRegistrySyncCompletePayload() implements CustomPacketPayload { +// public static final ResourceLocation ID = new ResourceLocation(ShearAPIRuntime.MOD_ID, "tier_sorting_registry_sync_complete"); +// +// public TierSortingRegistrySyncCompletePayload(FriendlyByteBuf buf) { +// this(); +// } +// +// @Override +// public void write(FriendlyByteBuf buf) {} +// +// @Override +// public ResourceLocation id() { +// return ID; +// } +//} diff --git a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java index 5582cd1..82478a7 100644 --- a/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java +++ b/shearapi-network/src/main/java/net/pillowmc/shearapi/network/injection/IServerGamePacketListenerExtension.java @@ -45,6 +45,6 @@ default void sendBundled(Iterable payloads) { packets.add(new ClientboundCustomPayloadPacket(payload)); } - self().send(new ClientboundBundlePacket(packets)); + self().send(new ClientboundBundlePacket((List>)(Object) packets)); } } diff --git a/shearapi-network/src/main/resources/fabric.mod.json b/shearapi-network/src/main/resources/fabric.mod.json index 446dd9e..af7b157 100644 --- a/shearapi-network/src/main/resources/fabric.mod.json +++ b/shearapi-network/src/main/resources/fabric.mod.json @@ -25,7 +25,9 @@ "accessWidener": "shearapi-network.accesswidener", "entrypoints": { "client": ["net.pillowmc.shearapi.network.client.ShearAPINetworkClient"], - "shearapi-runtime:mod_bus_subscriber": ["net.neoforged.neoforge.network.ConfigurationInitialization::clazz"] + "shearapi-runtime:mod_bus_subscriber": [ + "net.neoforged.neoforge.network.filters.GenericPacketSplitter::clazz" + ] }, "mixins": ["shearapi-network.mixins.json"], "custom": { diff --git a/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java b/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java index 832070b..32b1eec 100644 --- a/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java +++ b/shearapi-registries/src/main/java/net/neoforged/neoforge/registries/RegistryManager.java @@ -232,9 +232,9 @@ public static void postNewRegistryEvent() { // return list; // } // -// public static Set getVanillaRegistryKeys() { -// return vanillaRegistryKeys; -// } + public static Set getVanillaRegistryKeys() { + return vanillaRegistryKeys; + } public enum SnapshotType { /** diff --git a/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java b/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java index 659d1d2..775633b 100644 --- a/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java +++ b/shearapi-registries/src/main/java/net/pillowmc/shearapi/registries/ShearAPIRegistries.java @@ -2,7 +2,12 @@ import com.chocohead.mm.api.ClassTinkerers; import net.fabricmc.api.ModInitializer; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.data.registries.VanillaRegistries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; import net.minecraft.world.level.levelgen.DebugLevelSource; import net.neoforged.neoforge.registries.GameData; @@ -11,11 +16,13 @@ import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodInsnNode; +import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.StreamSupport; public class ShearAPIRegistries implements ModInitializer { + private static final List>> VANILLA_REGISTRIES_DATAPACK_REGISTRY_KEYS = VanillaRegistries.BUILDER.entries.stream().map(RegistrySetBuilder.RegistryStub::key).toList() @Override public void onInitialize() { RegistryManager.postNewRegistryEvent(); @@ -27,4 +34,10 @@ public static void initValidStatesInDebugLevelSource() { DebugLevelSource.GRID_WIDTH = Mth.ceil(Mth.sqrt(DebugLevelSource.ALL_BLOCKS.size())); DebugLevelSource.GRID_HEIGHT = Mth.ceil((float)DebugLevelSource.ALL_BLOCKS.size() / (float)DebugLevelSource.GRID_WIDTH); } + + public static boolean isVanillaRegistry(ResourceLocation location) { + // Checks if the registry name is contained within the static view of both BuiltInRegistries and VanillaRegistries + return RegistryManager.getVanillaRegistryKeys().contains(location) + || VANILLA_REGISTRIES_DATAPACK_REGISTRY_KEYS.stream().anyMatch(k -> k.location().equals(location)); + } } diff --git a/shearapi-registries/src/main/resources/shearapi-registries.accesswidener b/shearapi-registries/src/main/resources/shearapi-registries.accesswidener index eb018c2..9f2f379 100644 --- a/shearapi-registries/src/main/resources/shearapi-registries.accesswidener +++ b/shearapi-registries/src/main/resources/shearapi-registries.accesswidener @@ -13,3 +13,6 @@ mutable field net/minecraft/world/level/levelgen/DebugLevelSource GRID_HEIGHT I #accessible class net/minecraft/core/RegistrySynchronization$NetworkedRegistryData accessible method net/minecraft/core/RegistrySynchronization$NetworkedRegistryData (Lnet/minecraft/resources/ResourceKey;Lcom/mojang/serialization/Codec;)V accessible method net/minecraft/core/Holder$Reference bindValue (Ljava/lang/Object;)V +accessible field net/minecraft/core/RegistrySetBuilder entries Ljava/util/List; +accessible class net/minecraft/core/RegistrySetBuilder$RegistryStub +accessible field net/minecraft/data/registries/VanillaRegistries BUILDER Lnet/minecraft/core/RegistrySetBuilder; diff --git a/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java b/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java index 215cbe9..aa030de 100644 --- a/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java +++ b/shearapi-runtime/src/main/java/net/pillowmc/shearapi/runtime/IRuntime.java @@ -3,6 +3,8 @@ import net.neoforged.bus.api.Event; import net.neoforged.bus.api.IEventBus; +import java.util.Optional; + public interface IRuntime { boolean isLoadingStateVaild(); boolean isProduction(); @@ -10,4 +12,5 @@ public interface IRuntime { void postModBusEvent(T event); IEventBus getModBus(); boolean isModLoaded(String modid); + Optional getModDisplayName(String modid); } diff --git a/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java index babb386..508f73c 100644 --- a/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java +++ b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/MinecraftMixin.java @@ -2,17 +2,32 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.multiplayer.ClientPacketListener; +import net.minecraft.network.Connection; +import net.minecraft.network.protocol.Packet; import net.minecraft.world.level.Level; import net.pillowmc.shearapi.utils.IClientLike; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; +import java.util.Objects; + @Mixin(Minecraft.class) -public class MinecraftMixin implements IClientLike { +public abstract class MinecraftMixin implements IClientLike { @Shadow public ClientLevel level; + @Shadow + @Nullable + public abstract ClientPacketListener getConnection(); + + @Override + public void shearAPI$sendPacket(Packet packet) { + Objects.requireNonNull(this.getConnection()).send(packet); + } + @Override public Level shearAPI$getClientLevel() { return level; diff --git a/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/UtilsMixin.java b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/UtilsMixin.java new file mode 100644 index 0000000..768276d --- /dev/null +++ b/shearapi-utils/src/client/java/net/pillowmc/shearapi/utils/mixin/client/UtilsMixin.java @@ -0,0 +1,21 @@ +package net.pillowmc.shearapi.utils.mixin.client; + +import net.minecraft.client.Minecraft; +import net.pillowmc.shearapi.utils.IClientLike; +import net.pillowmc.shearapi.utils.Utils; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.util.Optional; + +@Mixin(value = Utils.class, remap = false) +public class UtilsMixin { + /** + * @author heipiao233 + * @reason Get client. + */ + @Overwrite + public static Optional getClient() { + return Optional.of((IClientLike) Minecraft.getInstance()); + } +} diff --git a/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json b/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json index 448e531..c33c70a 100644 --- a/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json +++ b/shearapi-utils/src/client/resources/shearapi-utils.client.mixin.json @@ -7,5 +7,8 @@ ], "injectors": { "defaultRequire": 1 - } + }, + "mixins": [ + "client.UtilsMixin" + ] } diff --git a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java index a892ade..a24e4d9 100644 --- a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java +++ b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/IClientLike.java @@ -1,12 +1,14 @@ package net.pillowmc.shearapi.utils; +import net.minecraft.network.protocol.Packet; import net.minecraft.server.TickTask; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.level.Level; public interface IClientLike { Level shearAPI$getClientLevel(); + void shearAPI$sendPacket(Packet packet); default BlockableEventLoop intoBlockableEventLoop() { - return (BlockableEventLoop)(Object) this; + return (BlockableEventLoop) this; } } diff --git a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java index 2eaee39..8fd0ec1 100644 --- a/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java +++ b/shearapi-utils/src/main/java/net/pillowmc/shearapi/utils/Utils.java @@ -10,4 +10,8 @@ public enum Utils {; public static Optional> getItemHolder(Item item) { return BuiltInRegistries.ITEM.getResourceKey(item).flatMap(BuiltInRegistries.ITEM::getHolder); } + + public static Optional getClient() { + return Optional.empty(); + } } diff --git a/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java b/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java index 013d570..262d68f 100644 --- a/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java +++ b/shearapi-withoutpillow/src/main/java/net/pillowmc/shearapi/withoutpillow/ShearAPIWithoutPillow.java @@ -7,6 +7,8 @@ import net.pillowmc.shearapi.runtime.IModBusEvent; import net.pillowmc.shearapi.runtime.IRuntime; +import java.util.Optional; + public class ShearAPIWithoutPillow implements IRuntime { private final IEventBus MODBUS = BusBuilder.builder().markerType(IModBusEvent.class).build(); @@ -39,4 +41,9 @@ public void postModBusEvent(T event) { public boolean isModLoaded(String modid) { return FabricLoader.getInstance().isModLoaded(modid); } + + @Override + public Optional getModDisplayName(String modid) { + return FabricLoader.getInstance().getModContainer(modid).map(m -> m.getMetadata().getName()); + } } diff --git a/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java b/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java index 0676729..f1caaca 100644 --- a/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java +++ b/shearapi-withpillow/src/main/java/net/pillowmc/shearapi/withpillow/ShearAPIWithPillow.java @@ -1,5 +1,6 @@ package net.pillowmc.shearapi.withpillow; +import net.fabricmc.loader.api.FabricLoader; import net.neoforged.bus.api.Event; import net.neoforged.fml.ModList; import net.neoforged.fml.ModLoader; @@ -7,6 +8,8 @@ import net.pillowmc.shearapi.runtime.IModBusEvent; import net.pillowmc.shearapi.withoutpillow.ShearAPIWithoutPillow; +import java.util.Optional; + public class ShearAPIWithPillow extends ShearAPIWithoutPillow { @Override @@ -39,4 +42,11 @@ public void postModBusEvent(T event) { public boolean isModLoaded(String modid) { return ModList.get().isLoaded(modid); } + + + @Override + public Optional getModDisplayName(String modid) { + return super.getModDisplayName(modid) + .or(() -> ModList.get().getModContainerById(modid).map(m -> m.getModInfo().getDisplayName())); + } }