package net.minecraft.core.component; import com.google.common.collect.Sets; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectMaps; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.Map.Entry; import java.util.function.Predicate; import javax.annotation.Nullable; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Unit; public final class DataComponentPatch { public static final DataComponentPatch EMPTY = new DataComponentPatch(Reference2ObjectMaps.emptyMap()); public static final Codec CODEC = Codec.dispatchedMap(DataComponentPatch.PatchKey.CODEC, DataComponentPatch.PatchKey::valueCodec) .xmap(p_330428_ -> { if (p_330428_.isEmpty()) { return EMPTY; } else { Reference2ObjectMap, Optional> reference2objectmap = new Reference2ObjectArrayMap<>(p_330428_.size()); for (Entry entry : p_330428_.entrySet()) { DataComponentPatch.PatchKey datacomponentpatch$patchkey = entry.getKey(); if (datacomponentpatch$patchkey.removed()) { reference2objectmap.put(datacomponentpatch$patchkey.type(), Optional.empty()); } else { reference2objectmap.put(datacomponentpatch$patchkey.type(), Optional.of(entry.getValue())); } } return new DataComponentPatch(reference2objectmap); } }, p_335950_ -> { Reference2ObjectMap reference2objectmap = new Reference2ObjectArrayMap<>(p_335950_.map.size()); for (Entry, Optional> entry : Reference2ObjectMaps.fastIterable(p_335950_.map)) { DataComponentType datacomponenttype = entry.getKey(); if (!datacomponenttype.isTransient()) { Optional optional = entry.getValue(); if (optional.isPresent()) { reference2objectmap.put(new DataComponentPatch.PatchKey(datacomponenttype, false), optional.get()); } else { reference2objectmap.put(new DataComponentPatch.PatchKey(datacomponenttype, true), Unit.INSTANCE); } } } return (Reference2ObjectMap)reference2objectmap; }); public static final StreamCodec STREAM_CODEC = createStreamCodec(new DataComponentPatch.CodecGetter() { @Override public StreamCodec apply(DataComponentType p_397940_) { return p_397940_.streamCodec().cast(); } }); public static final StreamCodec DELIMITED_STREAM_CODEC = createStreamCodec(new DataComponentPatch.CodecGetter() { @Override public StreamCodec apply(DataComponentType p_392185_) { StreamCodec streamcodec = p_392185_.streamCodec().cast(); return streamcodec.apply(ByteBufCodecs.lengthPrefixed(Integer.MAX_VALUE)); } }); private static final String REMOVED_PREFIX = "!"; final Reference2ObjectMap, Optional> map; private static StreamCodec createStreamCodec(final DataComponentPatch.CodecGetter p_395003_) { return new StreamCodec() { public DataComponentPatch decode(RegistryFriendlyByteBuf p_394008_) { int i = p_394008_.readVarInt(); int j = p_394008_.readVarInt(); if (i == 0 && j == 0) { return DataComponentPatch.EMPTY; } else { int k = i + j; Reference2ObjectMap, Optional> reference2objectmap = new Reference2ObjectArrayMap<>(Math.min(k, 65536)); for (int l = 0; l < i; l++) { DataComponentType datacomponenttype = DataComponentType.STREAM_CODEC.decode(p_394008_); Object object = p_395003_.apply(datacomponenttype).decode(p_394008_); reference2objectmap.put(datacomponenttype, Optional.of(object)); } for (int i1 = 0; i1 < j; i1++) { DataComponentType datacomponenttype1 = DataComponentType.STREAM_CODEC.decode(p_394008_); reference2objectmap.put(datacomponenttype1, Optional.empty()); } return new DataComponentPatch(reference2objectmap); } } public void encode(RegistryFriendlyByteBuf p_393727_, DataComponentPatch p_394312_) { if (p_394312_.isEmpty()) { p_393727_.writeVarInt(0); p_393727_.writeVarInt(0); } else { int i = 0; int j = 0; for (it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry, Optional> entry : Reference2ObjectMaps.fastIterable( p_394312_.map )) { if (entry.getValue().isPresent()) { i++; } else { j++; } } p_393727_.writeVarInt(i); p_393727_.writeVarInt(j); for (it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry, Optional> entry1 : Reference2ObjectMaps.fastIterable( p_394312_.map )) { Optional optional = entry1.getValue(); if (optional.isPresent()) { DataComponentType datacomponenttype = entry1.getKey(); DataComponentType.STREAM_CODEC.encode(p_393727_, datacomponenttype); this.encodeComponent(p_393727_, datacomponenttype, optional.get()); } } for (it.unimi.dsi.fastutil.objects.Reference2ObjectMap.Entry, Optional> entry2 : Reference2ObjectMaps.fastIterable( p_394312_.map )) { if (entry2.getValue().isEmpty()) { DataComponentType datacomponenttype1 = entry2.getKey(); DataComponentType.STREAM_CODEC.encode(p_393727_, datacomponenttype1); } } } } private void encodeComponent(RegistryFriendlyByteBuf p_391817_, DataComponentType p_392724_, Object p_397568_) { p_395003_.apply(p_392724_).encode(p_391817_, (T)p_397568_); } }; } DataComponentPatch(Reference2ObjectMap, Optional> p_329783_) { this.map = p_329783_; } public static DataComponentPatch.Builder builder() { return new DataComponentPatch.Builder(); } @Nullable public Optional get(DataComponentType p_330742_) { return (Optional)this.map.get(p_330742_); } public Set, Optional>> entrySet() { return this.map.entrySet(); } public int size() { return this.map.size(); } public DataComponentPatch forget(Predicate> p_333810_) { if (this.isEmpty()) { return EMPTY; } else { Reference2ObjectMap, Optional> reference2objectmap = new Reference2ObjectArrayMap<>(this.map); reference2objectmap.keySet().removeIf(p_333810_); return reference2objectmap.isEmpty() ? EMPTY : new DataComponentPatch(reference2objectmap); } } public boolean isEmpty() { return this.map.isEmpty(); } public DataComponentPatch.SplitResult split() { if (this.isEmpty()) { return DataComponentPatch.SplitResult.EMPTY; } else { DataComponentMap.Builder datacomponentmap$builder = DataComponentMap.builder(); Set> set = Sets.newIdentityHashSet(); this.map.forEach((p_336136_, p_328765_) -> { if (p_328765_.isPresent()) { datacomponentmap$builder.setUnchecked((DataComponentType)p_336136_, p_328765_.get()); } else { set.add((DataComponentType)p_336136_); } }); return new DataComponentPatch.SplitResult(datacomponentmap$builder.build(), set); } } @Override public boolean equals(Object p_334345_) { return this == p_334345_ ? true : p_334345_ instanceof DataComponentPatch datacomponentpatch && this.map.equals(datacomponentpatch.map); } @Override public int hashCode() { return this.map.hashCode(); } @Override public String toString() { return toString(this.map); } static String toString(Reference2ObjectMap, Optional> p_335670_) { StringBuilder stringbuilder = new StringBuilder(); stringbuilder.append('{'); boolean flag = true; for (Entry, Optional> entry : Reference2ObjectMaps.fastIterable(p_335670_)) { if (flag) { flag = false; } else { stringbuilder.append(", "); } Optional optional = entry.getValue(); if (optional.isPresent()) { stringbuilder.append(entry.getKey()); stringbuilder.append("=>"); stringbuilder.append(optional.get()); } else { stringbuilder.append("!"); stringbuilder.append(entry.getKey()); } } stringbuilder.append('}'); return stringbuilder.toString(); } public static class Builder { private final Reference2ObjectMap, Optional> map = new Reference2ObjectArrayMap<>(); Builder() { } public DataComponentPatch.Builder set(DataComponentType p_329935_, T p_331578_) { this.map.put(p_329935_, Optional.of(p_331578_)); return this; } public DataComponentPatch.Builder remove(DataComponentType p_329018_) { this.map.put(p_329018_, Optional.empty()); return this; } public DataComponentPatch.Builder set(TypedDataComponent p_331095_) { return this.set(p_331095_.type(), p_331095_.value()); } public DataComponentPatch build() { return this.map.isEmpty() ? DataComponentPatch.EMPTY : new DataComponentPatch(this.map); } } @FunctionalInterface interface CodecGetter { StreamCodec apply(DataComponentType p_393254_); } record PatchKey(DataComponentType type, boolean removed) { public static final Codec CODEC = Codec.STRING .flatXmap( p_330758_ -> { boolean flag = p_330758_.startsWith("!"); if (flag) { p_330758_ = p_330758_.substring("!".length()); } ResourceLocation resourcelocation = ResourceLocation.tryParse(p_330758_); DataComponentType datacomponenttype = BuiltInRegistries.DATA_COMPONENT_TYPE.getValue(resourcelocation); if (datacomponenttype == null) { return DataResult.error(() -> "No component with type: '" + resourcelocation + "'"); } else { return datacomponenttype.isTransient() ? DataResult.error(() -> "'" + resourcelocation + "' is not a persistent component") : DataResult.success(new DataComponentPatch.PatchKey(datacomponenttype, flag)); } }, p_329482_ -> { DataComponentType datacomponenttype = p_329482_.type(); ResourceLocation resourcelocation = BuiltInRegistries.DATA_COMPONENT_TYPE.getKey(datacomponenttype); return resourcelocation == null ? DataResult.error(() -> "Unregistered component: " + datacomponenttype) : DataResult.success(p_329482_.removed() ? "!" + resourcelocation : resourcelocation.toString()); } ); public Codec valueCodec() { return this.removed ? Codec.EMPTY.codec() : this.type.codecOrThrow(); } } public record SplitResult(DataComponentMap added, Set> removed) { public static final DataComponentPatch.SplitResult EMPTY = new DataComponentPatch.SplitResult(DataComponentMap.EMPTY, Set.of()); } }