From 8759e7555a93fb6f3bdcebc0e788eff194289098 Mon Sep 17 00:00:00 2001 From: Patbox <39821509+Patbox@users.noreply.github.com> Date: Sun, 4 Aug 2024 15:10:27 +0200 Subject: [PATCH] Prevent vanilla clients from joining servers that require modded registry entries. (#3992) * Prevent vanilla clients from joining servers that require modded registry entries --- .../ServerConfigurationNetworkAddon.java | 19 ++++++++++++ .../registry/sync/RegistrySyncManager.java | 29 +++++++++++++------ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java index c70e7dbdc..e3179cba0 100644 --- a/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java +++ b/fabric-networking-api-v1/src/main/java/net/fabricmc/fabric/impl/networking/server/ServerConfigurationNetworkAddon.java @@ -20,8 +20,11 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import org.jetbrains.annotations.Nullable; + import net.minecraft.network.NetworkPhase; import net.minecraft.network.PacketCallbacks; +import net.minecraft.network.packet.BrandCustomPayload; import net.minecraft.network.packet.CustomPayload; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.s2c.common.CommonPingS2CPacket; @@ -44,6 +47,8 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw private final MinecraftServer server; private final ServerConfigurationNetworking.Context context; private RegisterState registerState = RegisterState.NOT_SENT; + @Nullable + private String clientBrand = null; public ServerConfigurationNetworkAddon(ServerConfigurationNetworkHandler handler, MinecraftServer server) { super(ServerNetworkingImpl.CONFIGURATION, ((ServerCommonNetworkHandlerAccessor) handler).getConnection(), "ServerConfigurationNetworkAddon for " + handler.getDebugProfile().getName()); @@ -55,6 +60,16 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw this.registerPendingChannels((ChannelInfoHolder) this.connection, NetworkPhase.CONFIGURATION); } + @Override + public boolean handle(CustomPayload payload) { + if (payload instanceof BrandCustomPayload brandCustomPayload) { + clientBrand = brandCustomPayload.brand(); + return false; + } + + return super.handle(payload); + } + @Override protected void invokeInitEvent() { } @@ -169,6 +184,10 @@ public final class ServerConfigurationNetworkAddon extends AbstractChanneledNetw handler.send(packet, callback); } + public @Nullable String getClientBrand() { + return clientBrand; + } + private enum RegisterState { NOT_SENT, SENT, diff --git a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/RegistrySyncManager.java b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/RegistrySyncManager.java index cbc6e2ced..37f8e964a 100644 --- a/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/RegistrySyncManager.java +++ b/fabric-registry-sync-v0/src/main/java/net/fabricmc/fabric/impl/registry/sync/RegistrySyncManager.java @@ -41,7 +41,6 @@ import org.jetbrains.annotations.VisibleForTesting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.minecraft.nbt.NbtCompound; import net.minecraft.network.packet.Packet; import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; @@ -59,6 +58,7 @@ import net.minecraft.util.thread.ThreadExecutor; import net.fabricmc.fabric.api.event.registry.RegistryAttribute; import net.fabricmc.fabric.api.event.registry.RegistryAttributeHolder; import net.fabricmc.fabric.api.networking.v1.ServerConfigurationNetworking; +import net.fabricmc.fabric.impl.networking.server.ServerNetworkingImpl; import net.fabricmc.fabric.impl.registry.sync.packet.DirectRegistryPacketHandler; import net.fabricmc.fabric.impl.registry.sync.packet.RegistryPacketHandler; @@ -66,9 +66,14 @@ public final class RegistrySyncManager { public static final boolean DEBUG = Boolean.getBoolean("fabric.registry.debug"); public static final DirectRegistryPacketHandler DIRECT_PACKET_HANDLER = new DirectRegistryPacketHandler(); - private static final Logger LOGGER = LoggerFactory.getLogger("FabricRegistrySync"); private static final boolean DEBUG_WRITE_REGISTRY_DATA = Boolean.getBoolean("fabric.registry.debug.writeContentsAsCsv"); + private static final Text INCOMPATIBLE_FABRIC_CLIENT_TEXT = Text.literal("This server requires ").append(Text.literal("Fabric API").formatted(Formatting.GREEN)) + .append(" installed on your client!").formatted(Formatting.YELLOW) + .append(Text.literal("\nContact server's administrator for more information!").formatted(Formatting.GOLD)); + private static final Text INCOMPATIBLE_VANILLA_CLIENT_TEXT = Text.literal("This server requires ").append(Text.literal("Fabric Loader and Fabric API").formatted(Formatting.GREEN)) + .append(" installed on your client!").formatted(Formatting.YELLOW) + .append(Text.literal("\nContact server's administrator for more information!").formatted(Formatting.GOLD)); //Set to true after vanilla's bootstrap has completed public static boolean postBootstrap = false; @@ -81,11 +86,6 @@ public final class RegistrySyncManager { return; } - if (!ServerConfigurationNetworking.canSend(handler, DIRECT_PACKET_HANDLER.getPacketId())) { - // Don't send if the client cannot receive - return; - } - final Map> map = RegistrySyncManager.createAndPopulateRegistryMap(); if (map == null) { @@ -93,6 +93,17 @@ public final class RegistrySyncManager { return; } + if (!ServerConfigurationNetworking.canSend(handler, DIRECT_PACKET_HANDLER.getPacketId())) { + // Disconnect incompatible clients + Text message = switch (ServerNetworkingImpl.getAddon(handler).getClientBrand()) { + case "fabric" -> INCOMPATIBLE_FABRIC_CLIENT_TEXT; + case null, default -> INCOMPATIBLE_VANILLA_CLIENT_TEXT; + }; + + handler.disconnect(message); + return; + } + handler.addTask(new SyncConfigurationTask(handler, map)); } @@ -148,9 +159,9 @@ public final class RegistrySyncManager { } /** - * Creates a {@link NbtCompound} used to sync the registry ids. + * Creates a {@link Map} used to sync the registry ids. * - * @return a {@link NbtCompound} to sync, null when empty + * @return a {@link Map} to sync, null when empty */ @Nullable public static Map> createAndPopulateRegistryMap() {