mirror of
https://github.com/FabricMC/fabric.git
synced 2025-02-17 04:01:46 -05:00
Prevent vanilla clients from joining servers that require modded registry entries. (#4169)
* Prevent vanilla clients from joining servers that require modded registry entries. (#3992)
* Prevent vanilla clients from joining servers that require modded registry entries
(cherry picked from commit 8759e7555a
)
* Add related namespaces
---------
Co-authored-by: Patbox <39821509+Patbox@users.noreply.github.com>
This commit is contained in:
parent
625ef35355
commit
56ec7ac6d8
2 changed files with 60 additions and 6 deletions
|
@ -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,
|
||||
|
|
|
@ -58,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;
|
||||
|
||||
|
@ -65,7 +66,6 @@ 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");
|
||||
|
||||
|
@ -80,11 +80,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<Identifier, Object2IntMap<Identifier>> map = RegistrySyncManager.createAndPopulateRegistryMap();
|
||||
|
||||
if (map == null) {
|
||||
|
@ -92,9 +87,49 @@ public final class RegistrySyncManager {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!ServerConfigurationNetworking.canSend(handler, DIRECT_PACKET_HANDLER.getPacketId())) {
|
||||
// Disconnect incompatible clients
|
||||
Text message = getIncompatibleClientText(ServerNetworkingImpl.getAddon(handler).getClientBrand(), map);
|
||||
handler.disconnect(message);
|
||||
return;
|
||||
}
|
||||
|
||||
handler.addTask(new SyncConfigurationTask(handler, map));
|
||||
}
|
||||
|
||||
private static Text getIncompatibleClientText(@Nullable String brand, Map<Identifier, Object2IntMap<Identifier>> map) {
|
||||
String brandText = switch (brand) {
|
||||
case "fabric" -> "Fabric API";
|
||||
case null, default -> "Fabric Loader and Fabric API";
|
||||
};
|
||||
|
||||
final int toDisplay = 4;
|
||||
|
||||
List<String> namespaces = map.values().stream()
|
||||
.map(Object2IntMap::keySet)
|
||||
.flatMap(Set::stream)
|
||||
.map(Identifier::getNamespace)
|
||||
.filter(s -> !s.equals(Identifier.DEFAULT_NAMESPACE))
|
||||
.distinct()
|
||||
.sorted()
|
||||
.toList();
|
||||
|
||||
MutableText text = Text.literal("The following registry entry namespaces may be related:\n\n");
|
||||
|
||||
for (int i = 0; i < Math.min(namespaces.size(), toDisplay); i++) {
|
||||
text = text.append(Text.literal(namespaces.get(i)).formatted(Formatting.YELLOW));
|
||||
text = text.append(ScreenTexts.LINE_BREAK);
|
||||
}
|
||||
|
||||
if (namespaces.size() > toDisplay) {
|
||||
text = text.append(Text.literal("And %d more...".formatted(namespaces.size() - toDisplay)));
|
||||
}
|
||||
|
||||
return Text.literal("This server requires ").append(Text.literal(brandText).formatted(Formatting.GREEN)).append(" installed on your client!")
|
||||
.append(ScreenTexts.LINE_BREAK).append(text)
|
||||
.append(ScreenTexts.LINE_BREAK).append(ScreenTexts.LINE_BREAK).append(Text.literal("Contact the server's administrator for more information!").formatted(Formatting.GOLD));
|
||||
}
|
||||
|
||||
public record SyncConfigurationTask(
|
||||
ServerConfigurationNetworkHandler handler,
|
||||
Map<Identifier, Object2IntMap<Identifier>> map
|
||||
|
|
Loading…
Reference in a new issue