package net.minecraft.core; import com.mojang.serialization.DynamicOps; import io.netty.buffer.ByteBuf; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; import java.util.stream.Collectors; import java.util.stream.Stream; import net.minecraft.nbt.Tag; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.RegistryDataLoader; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.RegistryLayer; import net.minecraft.server.packs.repository.KnownPack; public class RegistrySynchronization { private static final Set>> NETWORKABLE_REGISTRIES = (Set>>)RegistryDataLoader.SYNCHRONIZED_REGISTRIES .stream() .map(RegistryDataLoader.RegistryData::key) .collect(Collectors.toUnmodifiableSet()); public static void packRegistries( DynamicOps ops, RegistryAccess registryAccess, Set packs, BiConsumer>, List> packetSender ) { RegistryDataLoader.SYNCHRONIZED_REGISTRIES.forEach(registryData -> packRegistry(ops, registryData, registryAccess, packs, packetSender)); } private static void packRegistry( DynamicOps ops, RegistryDataLoader.RegistryData registryData, RegistryAccess registryAccess, Set packs, BiConsumer>, List> packetSender ) { registryAccess.lookup(registryData.key()) .ifPresent( registry -> { List list = new ArrayList(registry.size()); registry.listElements() .forEach( reference -> { boolean bl = registry.registrationInfo(reference.key()).flatMap(RegistrationInfo::knownPackInfo).filter(packs::contains).isPresent(); Optional optional; if (bl) { optional = Optional.empty(); } else { Tag tag = registryData.elementCodec() .encodeStart(ops, (T)reference.value()) .getOrThrow(string -> new IllegalArgumentException("Failed to serialize " + reference.key() + ": " + string)); optional = Optional.of(tag); } list.add(new RegistrySynchronization.PackedRegistryEntry(reference.key().location(), optional)); } ); packetSender.accept(registry.key(), list); } ); } private static Stream> ownedNetworkableRegistries(RegistryAccess registryAccess) { return registryAccess.registries().filter(registryEntry -> isNetworkable(registryEntry.key())); } public static Stream> networkedRegistries(LayeredRegistryAccess registryAccess) { return ownedNetworkableRegistries(registryAccess.getAccessFrom(RegistryLayer.WORLDGEN)); } public static Stream> networkSafeRegistries(LayeredRegistryAccess registryAccess) { Stream> stream = registryAccess.getLayer(RegistryLayer.STATIC).registries(); Stream> stream2 = networkedRegistries(registryAccess); return Stream.concat(stream2, stream); } public static boolean isNetworkable(ResourceKey> registryKey) { return NETWORKABLE_REGISTRIES.contains(registryKey); } public record PackedRegistryEntry(ResourceLocation id, Optional data) { public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ResourceLocation.STREAM_CODEC, RegistrySynchronization.PackedRegistryEntry::id, ByteBufCodecs.TAG.apply(ByteBufCodecs::optional), RegistrySynchronization.PackedRegistryEntry::data, RegistrySynchronization.PackedRegistryEntry::new ); } }