/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.google.gson.JsonElement * com.mojang.datafixers.kinds.App * com.mojang.datafixers.kinds.Applicative * com.mojang.datafixers.util.Either * com.mojang.datafixers.util.Pair * com.mojang.serialization.Codec * com.mojang.serialization.DataResult * com.mojang.serialization.DynamicOps * com.mojang.serialization.JsonOps * com.mojang.serialization.MapCodec * com.mojang.serialization.MapDecoder * com.mojang.serialization.MapEncoder * com.mojang.serialization.MapLike * com.mojang.serialization.RecordBuilder * com.mojang.serialization.codecs.RecordCodecBuilder * io.netty.buffer.ByteBuf */ package net.minecraft.network.chat; import com.google.gson.JsonElement; import com.mojang.datafixers.kinds.App; import com.mojang.datafixers.kinds.Applicative; import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapDecoder; import com.mojang.serialization.MapEncoder; import com.mojang.serialization.MapLike; import com.mojang.serialization.RecordBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.netty.buffer.ByteBuf; import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.function.Function; import java.util.stream.Stream; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.ComponentContents; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.contents.KeybindContents; import net.minecraft.network.chat.contents.NbtContents; import net.minecraft.network.chat.contents.ObjectContents; import net.minecraft.network.chat.contents.PlainTextContents; import net.minecraft.network.chat.contents.ScoreContents; import net.minecraft.network.chat.contents.SelectorContents; import net.minecraft.network.chat.contents.TranslatableContents; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.RegistryOps; import net.minecraft.util.ExtraCodecs; import net.minecraft.util.GsonHelper; public class ComponentSerialization { public static final Codec CODEC = Codec.recursive((String)"Component", ComponentSerialization::createCodec); public static final StreamCodec STREAM_CODEC = ByteBufCodecs.fromCodecWithRegistries(CODEC); public static final StreamCodec> OPTIONAL_STREAM_CODEC = STREAM_CODEC.apply(ByteBufCodecs::optional); public static final StreamCodec TRUSTED_STREAM_CODEC = ByteBufCodecs.fromCodecWithRegistriesTrusted(CODEC); public static final StreamCodec> TRUSTED_OPTIONAL_STREAM_CODEC = TRUSTED_STREAM_CODEC.apply(ByteBufCodecs::optional); public static final StreamCodec TRUSTED_CONTEXT_FREE_STREAM_CODEC = ByteBufCodecs.fromCodecTrusted(CODEC); public static Codec flatRestrictedCodec(final int maxFlatSize) { return new Codec(){ public DataResult> decode(DynamicOps ops, T input) { return CODEC.decode(ops, input).flatMap(pair -> { if (this.isTooLarge(ops, (Component)pair.getFirst())) { return DataResult.error(() -> "Component was too large: greater than max size " + maxFlatSize); } return DataResult.success((Object)pair); }); } public DataResult encode(Component input, DynamicOps ops, T prefix) { return CODEC.encodeStart(ops, (Object)input); } private boolean isTooLarge(DynamicOps ops, Component input) { DataResult json = CODEC.encodeStart(1.asJsonOps(ops), (Object)input); return json.isSuccess() && GsonHelper.encodesLongerThan((JsonElement)json.getOrThrow(), maxFlatSize); } private static DynamicOps asJsonOps(DynamicOps ops) { if (ops instanceof RegistryOps) { RegistryOps registryOps = (RegistryOps)ops; return registryOps.withParent(JsonOps.INSTANCE); } return JsonOps.INSTANCE; } }; } private static MutableComponent createFromList(List list) { MutableComponent result = list.get(0).copy(); for (int i = 1; i < list.size(); ++i) { result.append(list.get(i)); } return result; } public static MapCodec createLegacyComponentMatcher(ExtraCodecs.LateBoundIdMapper> types, Function> codecGetter, String typeFieldName) { FuzzyCodec compactCodec = new FuzzyCodec(types.values(), codecGetter); MapCodec discriminatorCodec = types.codec((Codec)Codec.STRING).dispatchMap(typeFieldName, codecGetter, c -> c); StrictEither contentsCodec = new StrictEither(typeFieldName, discriminatorCodec, compactCodec); return ExtraCodecs.orCompressed(contentsCodec, discriminatorCodec); } private static Codec createCodec(Codec topSerializer) { ExtraCodecs.LateBoundIdMapper contentTypes = new ExtraCodecs.LateBoundIdMapper(); ComponentSerialization.bootstrap(contentTypes); MapCodec compressedContentsCodec = ComponentSerialization.createLegacyComponentMatcher(contentTypes, ComponentContents::codec, "type"); Codec fullCodec = RecordCodecBuilder.create(i -> i.group((App)compressedContentsCodec.forGetter(Component::getContents), (App)ExtraCodecs.nonEmptyList(topSerializer.listOf()).optionalFieldOf("extra", List.of()).forGetter(Component::getSiblings), (App)Style.Serializer.MAP_CODEC.forGetter(Component::getStyle)).apply((Applicative)i, MutableComponent::new)); return Codec.either((Codec)Codec.either((Codec)Codec.STRING, ExtraCodecs.nonEmptyList(topSerializer.listOf())), (Codec)fullCodec).xmap(specialOrComponent -> (Component)specialOrComponent.map(special -> (Component)special.map(Component::literal, ComponentSerialization::createFromList), c -> c), component -> { String text = component.tryCollapseToString(); return text != null ? Either.left((Object)Either.left((Object)text)) : Either.right((Object)component); }); } private static void bootstrap(ExtraCodecs.LateBoundIdMapper> contentTypes) { contentTypes.put("text", PlainTextContents.MAP_CODEC); contentTypes.put("translatable", TranslatableContents.MAP_CODEC); contentTypes.put("keybind", KeybindContents.MAP_CODEC); contentTypes.put("score", ScoreContents.MAP_CODEC); contentTypes.put("selector", SelectorContents.MAP_CODEC); contentTypes.put("nbt", NbtContents.MAP_CODEC); contentTypes.put("object", ObjectContents.MAP_CODEC); } private static class FuzzyCodec extends MapCodec { private final Collection> codecs; private final Function> encoderGetter; public FuzzyCodec(Collection> codecs, Function> encoderGetter) { this.codecs = codecs; this.encoderGetter = encoderGetter; } public DataResult decode(DynamicOps ops, MapLike input) { for (MapDecoder mapDecoder : this.codecs) { DataResult result = mapDecoder.decode(ops, input); if (!result.result().isPresent()) continue; return result; } return DataResult.error(() -> "No matching codec found"); } public RecordBuilder encode(T input, DynamicOps ops, RecordBuilder prefix) { MapEncoder encoder = this.encoderGetter.apply(input); return encoder.encode(input, ops, prefix); } public Stream keys(DynamicOps ops) { return this.codecs.stream().flatMap(c -> c.keys(ops)).distinct(); } public String toString() { return "FuzzyCodec[" + String.valueOf(this.codecs) + "]"; } } private static class StrictEither extends MapCodec { private final String typeFieldName; private final MapCodec typed; private final MapCodec fuzzy; public StrictEither(String typeFieldName, MapCodec typed, MapCodec fuzzy) { this.typeFieldName = typeFieldName; this.typed = typed; this.fuzzy = fuzzy; } public DataResult decode(DynamicOps ops, MapLike input) { if (input.get(this.typeFieldName) != null) { return this.typed.decode(ops, input); } return this.fuzzy.decode(ops, input); } public RecordBuilder encode(T input, DynamicOps ops, RecordBuilder prefix) { return this.fuzzy.encode(input, ops, prefix); } public Stream keys(DynamicOps ops) { return Stream.concat(this.typed.keys(ops), this.fuzzy.keys(ops)).distinct(); } } }