Fix network compatibility with Fabric during configuration phase (#3417)
Some checks failed
Release / release (push) Has been cancelled

This commit is contained in:
Sara Freimer 2026-08-19 05:36:12 -05:00 committed by GitHub
parent fab5865df5
commit e973c1d1bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 22 deletions

View file

@ -55,7 +55,7 @@
@Override
public boolean hasInfiniteMaterials() {
return true;
@@ -206,6 +_,59 @@
@@ -206,6 +_,61 @@
public void onDisconnect(DisconnectionDetails reason) {
super.onDisconnect(reason);
this.minecraft.clearDownloadedResourcePacks();
@ -65,6 +65,8 @@
+ public void handleCustomPayload(net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket packet) {
+ // Handle the initial registration payload by responding with the client's set of supported channels.
+ if (!this.initializedConnection && packet.payload() instanceof net.neoforged.neoforge.network.payload.MinecraftRegisterPayload) {
+ // Handle the registration packet before we respond, so that implementations like fabric that only send it once, don't have the values ignored
+ super.handleCustomPayload(packet);
+ net.neoforged.neoforge.client.network.registration.ClientNetworkRegistry.sendInitialListeningChannels(this);
+ return;
+ }

View file

@ -10,7 +10,6 @@ import com.mojang.logging.LogUtils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.minecraft.network.ConnectionProtocol;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.PacketFlow;
@ -255,6 +254,16 @@ public final class ClientNetworkRegistry extends NetworkRegistry {
NetworkFilters.injectIfNecessary(listener.getConnection());
sendInitialListeningChannels(listener);
}
/// Invoked by the client when it receives a [MinecraftRegisterPayload] during negotiation in the configuration phase.
/// This will respond to the server with the client's set of builtin and optional channels to indicate it supports the common protocol.
///
/// Invoked on the network thread.
///
/// @param listener The listener which received the brand payload.
public static void sendInitialListeningChannels(ClientConfigurationPacketListener listener) {
ImmutableSet.Builder<Identifier> nowListeningOn = ImmutableSet.builder();
nowListeningOn.addAll(getInitialListeningChannels(listener.flow()));
PAYLOAD_REGISTRATIONS.get(ConnectionProtocol.CONFIGURATION).entrySet().stream()
@ -264,19 +273,6 @@ public final class ClientNetworkRegistry extends NetworkRegistry {
listener.send(new MinecraftRegisterPayload(nowListeningOn.build()));
}
/**
* Invoked by the client when it receives a {@link MinecraftRegisterPayload} during negotiation in the configuration phase.
* This will respond to the server with the client's set of builtin channels to indicate it supports the common protocol.
* <p>
* Invoked on the network thread.
*
* @param listener The listener which received the brand payload.
*/
public static void sendInitialListeningChannels(ClientConfigurationPacketListener listener) {
Set<Identifier> nowListeningOn = ImmutableSet.copyOf(getInitialListeningChannels(listener.flow()));
listener.send(new MinecraftRegisterPayload(nowListeningOn));
}
/**
* Used in place of {@link Thread#dumpStack()} as that logs to {@link System#err}.
*/

View file

@ -429,11 +429,11 @@ public class NetworkRegistry {
return;
}
if (hasChannel(listener, customPayloadPacket.payload().type().id())) {
if (hasChannel(listener, id)) {
return;
}
throw new UnsupportedOperationException("Payload %s may not be sent to the client!".formatted(customPayloadPacket.payload().type().id()));
throw new UnsupportedOperationException("Payload %s may not be sent to the client!".formatted(id));
}
}
@ -451,11 +451,11 @@ public class NetworkRegistry {
return;
}
if (hasChannel(listener, customPayloadPacket.payload().type().id())) {
if (hasChannel(listener, id)) {
return;
}
throw new UnsupportedOperationException("Payload %s may not be sent to the server!".formatted(customPayloadPacket.payload().type().id()));
throw new UnsupportedOperationException("Payload %s may not be sent to the server!".formatted(id));
}
}
@ -541,10 +541,10 @@ public class NetworkRegistry {
return;
}
NetworkChannel channel = payloadSetup.getChannel(ConnectionProtocol.PLAY, customPayloadPacket.payload().type().id());
NetworkChannel channel = payloadSetup.getChannel(ConnectionProtocol.PLAY, id);
if (channel == null) {
LOGGER.trace("Somebody tried to send: {} to a client which cannot accept it. Not sending packet.", customPayloadPacket.payload().type().id());
LOGGER.trace("Somebody tried to send: {} to a client which cannot accept it. Not sending packet.", id);
return;
}
@ -612,7 +612,7 @@ public class NetworkRegistry {
nowForgottenChannels.add(MinecraftRegisterPayload.ID);
nowForgottenChannels.add(MinecraftUnregisterPayload.ID);
PAYLOAD_REGISTRATIONS.get(ConnectionProtocol.PLAY).entrySet().stream()
.filter(registration -> registration.getValue().flow().isEmpty() || registration.getValue().flow().get() == PacketFlow.SERVERBOUND)
.filter(registration -> registration.getValue().matchesFlow(PacketFlow.SERVERBOUND))
.filter(registration -> registration.getValue().optional())
.forEach(registration -> nowForgottenChannels.add(registration.getKey()));
return nowForgottenChannels.build();