package net.minecraft.network.protocol.common.custom; import io.netty.buffer.ByteBuf; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.codec.StreamDecoder; import net.minecraft.network.codec.StreamMemberEncoder; import net.minecraft.resources.ResourceLocation; public interface CustomPacketPayload { CustomPacketPayload.Type type(); static StreamCodec codec(StreamMemberEncoder encoder, StreamDecoder decoder) { return StreamCodec.ofMember(encoder, decoder); } static CustomPacketPayload.Type createType(String id) { return new CustomPacketPayload.Type<>(ResourceLocation.withDefaultNamespace(id)); } static StreamCodec codec( CustomPacketPayload.FallbackProvider fallbackProvider, List> typeAndCodecs ) { final Map> map = (Map>)typeAndCodecs.stream() .collect(Collectors.toUnmodifiableMap(typeAndCodec -> typeAndCodec.type().id(), CustomPacketPayload.TypeAndCodec::codec)); return new StreamCodec() { private StreamCodec findCodec(ResourceLocation resourceLocation) { StreamCodec streamCodec = (StreamCodec)map.get(resourceLocation); return streamCodec != null ? streamCodec : fallbackProvider.create(resourceLocation); } private void writeCap(B buffer, CustomPacketPayload.Type type, CustomPacketPayload payload) { buffer.writeResourceLocation(type.id()); StreamCodec streamCodec = this.findCodec(type.id); streamCodec.encode(buffer, (T)payload); } public void encode(B buffer, CustomPacketPayload value) { this.writeCap(buffer, value.type(), value); } public CustomPacketPayload decode(B buffer) { ResourceLocation resourceLocation = buffer.readResourceLocation(); return (CustomPacketPayload)this.findCodec(resourceLocation).decode(buffer); } }; } public interface FallbackProvider { StreamCodec create(ResourceLocation resourceLocation); } public record Type(ResourceLocation id) { } public record TypeAndCodec(CustomPacketPayload.Type type, StreamCodec codec) { } }