diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java index 597fe13fc..aeabd3ff6 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/codec/MinecraftTypes.java @@ -43,6 +43,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.GlobalPos; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataTypes; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.PaintingVariant; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.SnifferState; @@ -55,6 +56,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponent; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents; import org.geysermc.mcprotocollib.protocol.data.game.item.component.HolderSet; import org.geysermc.mcprotocollib.protocol.data.game.level.LightUpdateData; @@ -448,13 +450,13 @@ public static DataComponents readDataComponentPatch(ByteBuf buf) { Map, DataComponent> dataComponents = new HashMap<>(); for (int k = 0; k < nonNullComponents; k++) { - DataComponentType dataComponentType = DataComponentType.from(MinecraftTypes.readVarInt(buf)); + DataComponentType dataComponentType = DataComponentTypes.from(MinecraftTypes.readVarInt(buf)); DataComponent dataComponent = dataComponentType.readDataComponent(buf); dataComponents.put(dataComponentType, dataComponent); } for (int k = 0; k < nullComponents; k++) { - DataComponentType dataComponentType = DataComponentType.from(MinecraftTypes.readVarInt(buf)); + DataComponentType dataComponentType = DataComponentTypes.from(MinecraftTypes.readVarInt(buf)); DataComponent dataComponent = dataComponentType.readNullDataComponent(); dataComponents.put(dataComponentType, dataComponent); } @@ -503,7 +505,7 @@ public static ItemStack readTradeItemStack(ByteBuf buf) { Map, DataComponent> dataComponents = new HashMap<>(); for (int i = 0; i < componentsLength; i++) { - DataComponentType dataComponentType = DataComponentType.from(MinecraftTypes.readVarInt(buf)); + DataComponentType dataComponentType = DataComponentTypes.from(MinecraftTypes.readVarInt(buf)); DataComponent dataComponent = dataComponentType.readDataComponent(buf); dataComponents.put(dataComponentType, dataComponent); } @@ -714,11 +716,11 @@ public static void writeMetadata(ByteBuf buf, EntityMetadata metadata) { public static MetadataType readMetadataType(ByteBuf buf) { int id = MinecraftTypes.readVarInt(buf); - if (id >= MetadataType.size()) { - throw new IllegalArgumentException("Received id " + id + " for MetadataType when the maximum was " + MetadataType.size() + "!"); + if (id >= MetadataTypes.size()) { + throw new IllegalArgumentException("Received id " + id + " for MetadataType when the maximum was " + MetadataTypes.size() + "!"); } - return MetadataType.from(id); + return MetadataTypes.from(id); } public static void writeMetadataType(ByteBuf buf, MetadataType type) { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/BooleanMetadataType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/BooleanMetadataType.java index df7fdfcef..37d5e9bf3 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/BooleanMetadataType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/BooleanMetadataType.java @@ -8,8 +8,8 @@ public class BooleanMetadataType extends MetadataType { private final BooleanWriter primitiveWriter; private final BooleanEntityMetadataFactory primitiveFactory; - protected BooleanMetadataType(BooleanReader reader, BooleanWriter writer, BooleanEntityMetadataFactory metadataFactory) { - super(reader, writer, metadataFactory); + protected BooleanMetadataType(int id, BooleanReader reader, BooleanWriter writer, BooleanEntityMetadataFactory metadataFactory) { + super(id, reader, writer, metadataFactory); this.primitiveReader = reader; this.primitiveWriter = writer; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/ByteMetadataType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/ByteMetadataType.java index 6d05b6e85..0168e35b3 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/ByteMetadataType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/ByteMetadataType.java @@ -8,8 +8,8 @@ public class ByteMetadataType extends MetadataType { private final ByteWriter primitiveWriter; private final ByteEntityMetadataFactory primitiveFactory; - protected ByteMetadataType(ByteReader reader, ByteWriter writer, ByteEntityMetadataFactory metadataFactory) { - super(reader, writer, metadataFactory); + protected ByteMetadataType(int id, ByteReader reader, ByteWriter writer, ByteEntityMetadataFactory metadataFactory) { + super(id, reader, writer, metadataFactory); this.primitiveReader = reader; this.primitiveWriter = writer; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/FloatMetadataType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/FloatMetadataType.java index 8f5a14316..7f633d363 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/FloatMetadataType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/FloatMetadataType.java @@ -8,8 +8,8 @@ public class FloatMetadataType extends MetadataType { private final FloatWriter primitiveWriter; private final FloatEntityMetadataFactory primitiveFactory; - protected FloatMetadataType(FloatReader reader, FloatWriter writer, FloatEntityMetadataFactory metadataFactory) { - super(reader, writer, metadataFactory); + protected FloatMetadataType(int id, FloatReader reader, FloatWriter writer, FloatEntityMetadataFactory metadataFactory) { + super(id, reader, writer, metadataFactory); this.primitiveReader = reader; this.primitiveWriter = writer; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/IntMetadataType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/IntMetadataType.java index ce0dafb17..78ca6b637 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/IntMetadataType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/IntMetadataType.java @@ -8,8 +8,8 @@ public class IntMetadataType extends MetadataType { private final IntWriter primitiveWriter; private final IntEntityMetadataFactory primitiveFactory; - protected IntMetadataType(IntReader reader, IntWriter writer, IntEntityMetadataFactory metadataFactory) { - super(reader, writer, metadataFactory); + protected IntMetadataType(int id, IntReader reader, IntWriter writer, IntEntityMetadataFactory metadataFactory) { + super(id, reader, writer, metadataFactory); this.primitiveReader = reader; this.primitiveWriter = writer; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/LongMetadataType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/LongMetadataType.java index fde55138a..f403a0cf7 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/LongMetadataType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/LongMetadataType.java @@ -8,8 +8,8 @@ public class LongMetadataType extends MetadataType { private final LongWriter primitiveWriter; private final LongEntityMetadataFactory primitiveFactory; - protected LongMetadataType(LongReader reader, LongWriter writer, LongEntityMetadataFactory metadataFactory) { - super(reader, writer, metadataFactory); + protected LongMetadataType(int id, LongReader reader, LongWriter writer, LongEntityMetadataFactory metadataFactory) { + super(id, reader, writer, metadataFactory); this.primitiveReader = reader; this.primitiveWriter = writer; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataType.java index ec27a2339..6440583e9 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataType.java @@ -2,76 +2,19 @@ import io.netty.buffer.ByteBuf; import lombok.Getter; -import net.kyori.adventure.text.Component; -import org.cloudburstmc.math.vector.Vector3f; -import org.cloudburstmc.math.vector.Vector3i; -import org.cloudburstmc.math.vector.Vector4f; -import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; -import org.geysermc.mcprotocollib.protocol.data.game.Holder; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.LongEntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; -import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; @Getter public class MetadataType { - private static final List> VALUES = new ArrayList<>(); - - public static final ByteMetadataType BYTE = new ByteMetadataType(ByteBuf::readByte, ByteBuf::writeByte, ByteEntityMetadata::new); - public static final IntMetadataType INT = new IntMetadataType(MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new); - public static final LongMetadataType LONG = new LongMetadataType(MinecraftTypes::readVarLong, MinecraftTypes::writeVarLong, LongEntityMetadata::new); - public static final FloatMetadataType FLOAT = new FloatMetadataType(ByteBuf::readFloat, ByteBuf::writeFloat, FloatEntityMetadata::new); - public static final MetadataType STRING = new MetadataType<>(MinecraftTypes::readString, MinecraftTypes::writeString, ObjectEntityMetadata::new); - public static final MetadataType CHAT = new MetadataType<>(MinecraftTypes::readComponent, MinecraftTypes::writeComponent, ObjectEntityMetadata::new); - public static final MetadataType> OPTIONAL_CHAT = new MetadataType<>(optionalReader(MinecraftTypes::readComponent), optionalWriter(MinecraftTypes::writeComponent), ObjectEntityMetadata::new); - public static final MetadataType ITEM = new MetadataType<>(MinecraftTypes::readOptionalItemStack, MinecraftTypes::writeOptionalItemStack, ObjectEntityMetadata::new); - public static final BooleanMetadataType BOOLEAN = new BooleanMetadataType(ByteBuf::readBoolean, ByteBuf::writeBoolean, BooleanEntityMetadata::new); - public static final MetadataType ROTATION = new MetadataType<>(MinecraftTypes::readRotation, MinecraftTypes::writeRotation, ObjectEntityMetadata::new); - public static final MetadataType POSITION = new MetadataType<>(MinecraftTypes::readPosition, MinecraftTypes::writePosition, ObjectEntityMetadata::new); - public static final MetadataType> OPTIONAL_POSITION = new MetadataType<>(optionalReader(MinecraftTypes::readPosition), optionalWriter(MinecraftTypes::writePosition), ObjectEntityMetadata::new); - public static final MetadataType DIRECTION = new MetadataType<>(MinecraftTypes::readDirection, MinecraftTypes::writeDirection, ObjectEntityMetadata::new); - public static final MetadataType> OPTIONAL_UUID = new MetadataType<>(optionalReader(MinecraftTypes::readUUID), optionalWriter(MinecraftTypes::writeUUID), ObjectEntityMetadata::new); - public static final IntMetadataType BLOCK_STATE = new IntMetadataType(MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new); - public static final IntMetadataType OPTIONAL_BLOCK_STATE = new IntMetadataType(MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new); - public static final MetadataType NBT_TAG = new MetadataType<>(MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectEntityMetadata::new); - public static final MetadataType PARTICLE = new MetadataType<>(MinecraftTypes::readParticle, MinecraftTypes::writeParticle, ObjectEntityMetadata::new); - public static final MetadataType> PARTICLES = new MetadataType<>(listReader(MinecraftTypes::readParticle), listWriter(MinecraftTypes::writeParticle), ObjectEntityMetadata::new); - public static final MetadataType VILLAGER_DATA = new MetadataType<>(MinecraftTypes::readVillagerData, MinecraftTypes::writeVillagerData, ObjectEntityMetadata::new); - public static final OptionalIntMetadataType OPTIONAL_VARINT = new OptionalIntMetadataType(ObjectEntityMetadata::new); - public static final MetadataType POSE = new MetadataType<>(MinecraftTypes::readPose, MinecraftTypes::writePose, ObjectEntityMetadata::new); - public static final IntMetadataType CAT_VARIANT = new IntMetadataType(MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new); - public static final MetadataType> WOLF_VARIANT = new MetadataType<>(MinecraftTypes::readWolfVariant, MinecraftTypes::writeWolfVariant, ObjectEntityMetadata::new); - public static final IntMetadataType FROG_VARIANT = new IntMetadataType(MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new); - public static final MetadataType> OPTIONAL_GLOBAL_POS = new MetadataType<>(optionalReader(MinecraftTypes::readGlobalPos), optionalWriter(MinecraftTypes::writeGlobalPos), ObjectEntityMetadata::new); - public static final MetadataType> PAINTING_VARIANT = new MetadataType<>(MinecraftTypes::readPaintingVariant, MinecraftTypes::writePaintingVariant, ObjectEntityMetadata::new); - public static final MetadataType SNIFFER_STATE = new MetadataType<>(MinecraftTypes::readSnifferState, MinecraftTypes::writeSnifferState, ObjectEntityMetadata::new); - public static final MetadataType ARMADILLO_STATE = new MetadataType<>(MinecraftTypes::readArmadilloState, MinecraftTypes::writeArmadilloState, ObjectEntityMetadata::new); - public static final MetadataType VECTOR3 = new MetadataType<>(MinecraftTypes::readRotation, MinecraftTypes::writeRotation, ObjectEntityMetadata::new); - public static final MetadataType QUATERNION = new MetadataType<>(MinecraftTypes::readQuaternion, MinecraftTypes::writeQuaternion, ObjectEntityMetadata::new); - protected final int id; protected final Reader reader; protected final Writer writer; protected final EntityMetadataFactory metadataFactory; - protected MetadataType(Reader reader, Writer writer, EntityMetadataFactory metadataFactory) { - this.id = VALUES.size(); + protected MetadataType(int id, Reader reader, Writer writer, EntityMetadataFactory metadataFactory) { + this.id = id; this.reader = reader; this.writer = writer; this.metadataFactory = metadataFactory; - - VALUES.add(this); } public EntityMetadata> readMetadata(ByteBuf input, int id) { @@ -106,76 +49,4 @@ public interface BasicWriter extends Writer { public interface EntityMetadataFactory { EntityMetadata> create(int id, MetadataType type, V value); } - - private static BasicReader> optionalReader(BasicReader reader) { - return input -> { - if (!input.readBoolean()) { - return Optional.empty(); - } - - return Optional.of(reader.read(input)); - }; - } - - private static Reader> optionalReader(Reader reader) { - return (input) -> { - if (!input.readBoolean()) { - return Optional.empty(); - } - - return Optional.of(reader.read(input)); - }; - } - - private static BasicWriter> optionalWriter(BasicWriter writer) { - return (output, value) -> { - output.writeBoolean(value.isPresent()); - value.ifPresent(t -> writer.write(output, t)); - }; - } - - private static Writer> optionalWriter(Writer writer) { - return (output, value) -> { - output.writeBoolean(value.isPresent()); - value.ifPresent(t -> writer.write(output, t)); - }; - } - - private static Reader> listReader(Reader reader) { - return (input) -> { - List ret = new ArrayList<>(); - int size = MinecraftTypes.readVarInt(input); - for (int i = 0; i < size; i++) { - ret.add(reader.read(input)); - } - - return ret; - }; - } - - private static Writer> listWriter(Writer writer) { - return (output, value) -> { - MinecraftTypes.writeVarInt(output, value.size()); - for (T object : value) { - writer.write(output, object); - } - }; - } - - public static MetadataType read(ByteBuf in) { - int id = MinecraftTypes.readVarInt(in); - if (id >= VALUES.size()) { - throw new IllegalArgumentException("Received id " + id + " for MetadataType when the maximum was " + VALUES.size() + "!"); - } - - return VALUES.get(id); - } - - public static MetadataType from(int id) { - return VALUES.get(id); - } - - public static int size() { - return VALUES.size(); - } } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataTypes.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataTypes.java new file mode 100644 index 000000000..487f04554 --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/MetadataTypes.java @@ -0,0 +1,141 @@ +package org.geysermc.mcprotocollib.protocol.data.game.entity.metadata; + +import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.Int2ObjectFunction; +import lombok.Getter; +import net.kyori.adventure.text.Component; +import org.cloudburstmc.math.vector.Vector3f; +import org.cloudburstmc.math.vector.Vector3i; +import org.cloudburstmc.math.vector.Vector4f; +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.LongEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Getter +public class MetadataTypes { + private static final List> VALUES = new ArrayList<>(); + + public static final ByteMetadataType BYTE = register(id -> new ByteMetadataType(id, ByteBuf::readByte, ByteBuf::writeByte, ByteEntityMetadata::new)); + public static final IntMetadataType INT = register(id -> new IntMetadataType(id, MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new)); + public static final LongMetadataType LONG = register(id -> new LongMetadataType(id, MinecraftTypes::readVarLong, MinecraftTypes::writeVarLong, LongEntityMetadata::new)); + public static final FloatMetadataType FLOAT = register(id -> new FloatMetadataType(id, ByteBuf::readFloat, ByteBuf::writeFloat, FloatEntityMetadata::new)); + public static final MetadataType STRING = register(id -> new MetadataType<>(id, MinecraftTypes::readString, MinecraftTypes::writeString, ObjectEntityMetadata::new)); + public static final MetadataType CHAT = register(id -> new MetadataType<>(id, MinecraftTypes::readComponent, MinecraftTypes::writeComponent, ObjectEntityMetadata::new)); + public static final MetadataType> OPTIONAL_CHAT = register(id -> new MetadataType<>(id, optionalReader(MinecraftTypes::readComponent), optionalWriter(MinecraftTypes::writeComponent), ObjectEntityMetadata::new)); + public static final MetadataType ITEM = register(id -> new MetadataType<>(id, MinecraftTypes::readOptionalItemStack, MinecraftTypes::writeOptionalItemStack, ObjectEntityMetadata::new)); + public static final BooleanMetadataType BOOLEAN = register(id -> new BooleanMetadataType(id, ByteBuf::readBoolean, ByteBuf::writeBoolean, BooleanEntityMetadata::new)); + public static final MetadataType ROTATION = register(id -> new MetadataType<>(id, MinecraftTypes::readRotation, MinecraftTypes::writeRotation, ObjectEntityMetadata::new)); + public static final MetadataType POSITION = register(id -> new MetadataType<>(id, MinecraftTypes::readPosition, MinecraftTypes::writePosition, ObjectEntityMetadata::new)); + public static final MetadataType> OPTIONAL_POSITION = register(id -> new MetadataType<>(id, optionalReader(MinecraftTypes::readPosition), optionalWriter(MinecraftTypes::writePosition), ObjectEntityMetadata::new)); + public static final MetadataType DIRECTION = register(id -> new MetadataType<>(id, MinecraftTypes::readDirection, MinecraftTypes::writeDirection, ObjectEntityMetadata::new)); + public static final MetadataType> OPTIONAL_UUID = register(id -> new MetadataType<>(id, optionalReader(MinecraftTypes::readUUID), optionalWriter(MinecraftTypes::writeUUID), ObjectEntityMetadata::new)); + public static final IntMetadataType BLOCK_STATE = register(id -> new IntMetadataType(id, MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new)); + public static final IntMetadataType OPTIONAL_BLOCK_STATE = register(id -> new IntMetadataType(id, MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new)); + public static final MetadataType NBT_TAG = register(id -> new MetadataType<>(id, MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectEntityMetadata::new)); + public static final MetadataType PARTICLE = register(id -> new MetadataType<>(id, MinecraftTypes::readParticle, MinecraftTypes::writeParticle, ObjectEntityMetadata::new)); + public static final MetadataType> PARTICLES = register(id -> new MetadataType<>(id, listReader(MinecraftTypes::readParticle), listWriter(MinecraftTypes::writeParticle), ObjectEntityMetadata::new)); + public static final MetadataType VILLAGER_DATA = register(id -> new MetadataType<>(id, MinecraftTypes::readVillagerData, MinecraftTypes::writeVillagerData, ObjectEntityMetadata::new)); + public static final OptionalIntMetadataType OPTIONAL_VARINT = register(id -> new OptionalIntMetadataType(id, ObjectEntityMetadata::new)); + public static final MetadataType POSE = register(id -> new MetadataType<>(id, MinecraftTypes::readPose, MinecraftTypes::writePose, ObjectEntityMetadata::new)); + public static final IntMetadataType CAT_VARIANT = register(id -> new IntMetadataType(id, MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new)); + public static final MetadataType> WOLF_VARIANT = register(id -> new MetadataType<>(id, MinecraftTypes::readWolfVariant, MinecraftTypes::writeWolfVariant, ObjectEntityMetadata::new)); + public static final IntMetadataType FROG_VARIANT = register(id -> new IntMetadataType(id, MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntEntityMetadata::new)); + public static final MetadataType> OPTIONAL_GLOBAL_POS = register(id -> new MetadataType<>(id, optionalReader(MinecraftTypes::readGlobalPos), optionalWriter(MinecraftTypes::writeGlobalPos), ObjectEntityMetadata::new)); + public static final MetadataType> PAINTING_VARIANT = register(id -> new MetadataType<>(id, MinecraftTypes::readPaintingVariant, MinecraftTypes::writePaintingVariant, ObjectEntityMetadata::new)); + public static final MetadataType SNIFFER_STATE = register(id -> new MetadataType<>(id, MinecraftTypes::readSnifferState, MinecraftTypes::writeSnifferState, ObjectEntityMetadata::new)); + public static final MetadataType ARMADILLO_STATE = register(id -> new MetadataType<>(id, MinecraftTypes::readArmadilloState, MinecraftTypes::writeArmadilloState, ObjectEntityMetadata::new)); + public static final MetadataType VECTOR3 = register(id -> new MetadataType<>(id, MinecraftTypes::readRotation, MinecraftTypes::writeRotation, ObjectEntityMetadata::new)); + public static final MetadataType QUATERNION =register(id -> new MetadataType<>(id, MinecraftTypes::readQuaternion, MinecraftTypes::writeQuaternion, ObjectEntityMetadata::new)); + + public static > T register(Int2ObjectFunction factory) { + T value = factory.apply(VALUES.size()); + VALUES.add(value); + return value; + } + + private static MetadataType.BasicReader> optionalReader(MetadataType.BasicReader reader) { + return input -> { + if (!input.readBoolean()) { + return Optional.empty(); + } + + return Optional.of(reader.read(input)); + }; + } + + private static MetadataType.Reader> optionalReader(MetadataType.Reader reader) { + return (input) -> { + if (!input.readBoolean()) { + return Optional.empty(); + } + + return Optional.of(reader.read(input)); + }; + } + + private static MetadataType.BasicWriter> optionalWriter(MetadataType.BasicWriter writer) { + return (output, value) -> { + output.writeBoolean(value.isPresent()); + value.ifPresent(t -> writer.write(output, t)); + }; + } + + private static MetadataType.Writer> optionalWriter(MetadataType.Writer writer) { + return (output, value) -> { + output.writeBoolean(value.isPresent()); + value.ifPresent(t -> writer.write(output, t)); + }; + } + + private static MetadataType.Reader> listReader(MetadataType.Reader reader) { + return (input) -> { + List ret = new ArrayList<>(); + int size = MinecraftTypes.readVarInt(input); + for (int i = 0; i < size; i++) { + ret.add(reader.read(input)); + } + + return ret; + }; + } + + private static MetadataType.Writer> listWriter(MetadataType.Writer writer) { + return (output, value) -> { + MinecraftTypes.writeVarInt(output, value.size()); + for (T object : value) { + writer.write(output, object); + } + }; + } + + public static MetadataType read(ByteBuf in) { + int id = MinecraftTypes.readVarInt(in); + if (id >= VALUES.size()) { + throw new IllegalArgumentException("Received id " + id + " for MetadataType when the maximum was " + VALUES.size() + "!"); + } + + return VALUES.get(id); + } + + public static MetadataType from(int id) { + return VALUES.get(id); + } + + public static int size() { + return VALUES.size(); + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/OptionalIntMetadataType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/OptionalIntMetadataType.java index 30a15c1c7..ffeba40b3 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/OptionalIntMetadataType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/entity/metadata/OptionalIntMetadataType.java @@ -6,8 +6,8 @@ import java.util.OptionalInt; public class OptionalIntMetadataType extends MetadataType { - protected OptionalIntMetadataType(EntityMetadataFactory metadataFactory) { - super(OptionalIntReader.INSTANCE, OptionalIntWriter.INSTANCE, metadataFactory); + protected OptionalIntMetadataType(int id, EntityMetadataFactory metadataFactory) { + super(id, OptionalIntReader.INSTANCE, OptionalIntWriter.INSTANCE, metadataFactory); } public static class OptionalIntReader implements Reader { diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BooleanComponentType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BooleanComponentType.java index bb75679fe..b1ff231c7 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BooleanComponentType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/BooleanComponentType.java @@ -1,6 +1,7 @@ package org.geysermc.mcprotocollib.protocol.data.game.item.component; import io.netty.buffer.ByteBuf; +import net.kyori.adventure.key.KeyPattern; import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.BooleanDataComponent; public class BooleanComponentType extends DataComponentType { @@ -8,8 +9,8 @@ public class BooleanComponentType extends DataComponentType { protected final BooleanWriter primitiveWriter; protected final BooleanDataComponentFactory primitiveFactory; - protected BooleanComponentType(String key, BooleanReader reader, BooleanWriter writer, BooleanDataComponentFactory metadataFactory) { - super(key, reader, writer, metadataFactory); + protected BooleanComponentType(int id, @KeyPattern String key, BooleanReader reader, BooleanWriter writer, BooleanDataComponentFactory metadataFactory) { + super(id, key, reader, writer, metadataFactory); this.primitiveReader = reader; this.primitiveWriter = writer; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentType.java index fedcabb40..b0a603efe 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentType.java @@ -3,107 +3,22 @@ import io.netty.buffer.ByteBuf; import lombok.Getter; import net.kyori.adventure.key.Key; -import net.kyori.adventure.text.Component; -import org.cloudburstmc.nbt.NbtList; -import org.cloudburstmc.nbt.NbtMap; -import org.geysermc.mcprotocollib.auth.GameProfile; -import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; -import org.geysermc.mcprotocollib.protocol.data.game.Holder; -import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.BooleanDataComponent; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.IntDataComponent; -import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.ObjectDataComponent; - -import java.util.ArrayList; -import java.util.List; +import net.kyori.adventure.key.KeyPattern; @Getter public class DataComponentType { - private static final List> VALUES = new ArrayList<>(); - - public static final DataComponentType CUSTOM_DATA = new DataComponentType<>("custom_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final IntComponentType MAX_STACK_SIZE = new IntComponentType("max_stack_size", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final IntComponentType MAX_DAMAGE = new IntComponentType("max_damage", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final IntComponentType DAMAGE = new IntComponentType("damage", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType UNBREAKABLE = new DataComponentType<>("unbreakable", ItemTypes::readUnbreakable, ItemTypes::writeUnbreakable, ObjectDataComponent::new); - public static final DataComponentType CUSTOM_NAME = new DataComponentType<>("custom_name", MinecraftTypes::readComponent, MinecraftTypes::writeComponent, ObjectDataComponent::new); - public static final DataComponentType ITEM_NAME = new DataComponentType<>("item_name", MinecraftTypes::readComponent, MinecraftTypes::writeComponent, ObjectDataComponent::new); - public static final DataComponentType ITEM_MODEL = new DataComponentType<>("item_model", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new); - public static final DataComponentType> LORE = new DataComponentType<>("lore", listReader(MinecraftTypes::readComponent), listWriter(MinecraftTypes::writeComponent), ObjectDataComponent::new); - public static final IntComponentType RARITY = new IntComponentType("rarity", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType ENCHANTMENTS = new DataComponentType<>("enchantments", ItemTypes::readItemEnchantments, ItemTypes::writeItemEnchantments, ObjectDataComponent::new); - public static final DataComponentType CAN_PLACE_ON = new DataComponentType<>("can_place_on", ItemTypes::readAdventureModePredicate, ItemTypes::writeAdventureModePredicate, ObjectDataComponent::new); - public static final DataComponentType CAN_BREAK = new DataComponentType<>("can_break", ItemTypes::readAdventureModePredicate, ItemTypes::writeAdventureModePredicate, ObjectDataComponent::new); - public static final DataComponentType ATTRIBUTE_MODIFIERS = new DataComponentType<>("attribute_modifiers", ItemTypes::readItemAttributeModifiers, ItemTypes::writeItemAttributeModifiers, ObjectDataComponent::new); - public static final DataComponentType CUSTOM_MODEL_DATA = new DataComponentType<>("custom_model_data", ItemTypes::readCustomModelData, ItemTypes::writeCustomModelData, ObjectDataComponent::new); - public static final DataComponentType HIDE_ADDITIONAL_TOOLTIP = new DataComponentType<>("hide_additional_tooltip", unitReader(), unitWriter(), ObjectDataComponent::new); - public static final DataComponentType HIDE_TOOLTIP = new DataComponentType<>("hide_tooltip", unitReader(), unitWriter(), ObjectDataComponent::new); - public static final IntComponentType REPAIR_COST = new IntComponentType("repair_cost", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType CREATIVE_SLOT_LOCK = new DataComponentType<>("creative_slot_lock", unitReader(), unitWriter(), ObjectDataComponent::new); - public static final BooleanComponentType ENCHANTMENT_GLINT_OVERRIDE = new BooleanComponentType("enchantment_glint_override", ByteBuf::readBoolean, ByteBuf::writeBoolean, BooleanDataComponent::new); - public static final DataComponentType INTANGIBLE_PROJECTILE = new DataComponentType<>("intangible_projectile", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final DataComponentType FOOD = new DataComponentType<>("food", ItemTypes::readFoodProperties, ItemTypes::writeFoodProperties, ObjectDataComponent::new); - public static final DataComponentType CONSUMABLE = new DataComponentType<>("consumable", ItemTypes::readConsumable, ItemTypes::writeConsumable, ObjectDataComponent::new); - public static final DataComponentType USE_REMAINDER = new DataComponentType<>("use_remainder", MinecraftTypes::readItemStack, MinecraftTypes::writeItemStack, ObjectDataComponent::new); - public static final DataComponentType USE_COOLDOWN = new DataComponentType<>("use_cooldown", ItemTypes::readUseCooldown, ItemTypes::writeUseCooldown, ObjectDataComponent::new); - public static final DataComponentType DAMAGE_RESISTANT = new DataComponentType<>("damage_resistant", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new); - public static final DataComponentType TOOL = new DataComponentType<>("tool", ItemTypes::readToolData, ItemTypes::writeToolData, ObjectDataComponent::new); - public static final IntComponentType ENCHANTABLE = new IntComponentType("enchantable", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType EQUIPPABLE = new DataComponentType<>("equippable", ItemTypes::readEquippable, ItemTypes::writeEquippable, ObjectDataComponent::new); - public static final DataComponentType REPAIRABLE = new DataComponentType<>("repairable", MinecraftTypes::readHolderSet, MinecraftTypes::writeHolderSet, ObjectDataComponent::new); - public static final DataComponentType GLIDER = new DataComponentType<>("glider", unitReader(), unitWriter(), ObjectDataComponent::new); - public static final DataComponentType TOOLTIP_STYLE = new DataComponentType<>("tooltip_style", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new); - public static final DataComponentType> DEATH_PROTECTION = new DataComponentType<>("death_protection", listReader(ItemTypes::readConsumeEffect), listWriter(ItemTypes::writeConsumeEffect), ObjectDataComponent::new); - public static final DataComponentType STORED_ENCHANTMENTS = new DataComponentType<>("stored_enchantments", ItemTypes::readItemEnchantments, ItemTypes::writeItemEnchantments, ObjectDataComponent::new); - public static final DataComponentType DYED_COLOR = new DataComponentType<>("dyed_color", ItemTypes::readDyedItemColor, ItemTypes::writeDyedItemColor, ObjectDataComponent::new); - public static final IntComponentType MAP_COLOR = new IntComponentType("map_color", ByteBuf::readInt, ByteBuf::writeInt, IntDataComponent::new); - public static final IntComponentType MAP_ID = new IntComponentType("map_id", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType MAP_DECORATIONS = new DataComponentType<>("map_decorations", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final IntComponentType MAP_POST_PROCESSING = new IntComponentType("map_post_processing", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType> CHARGED_PROJECTILES = new DataComponentType<>("charged_projectiles", listReader(MinecraftTypes::readItemStack), listWriter(MinecraftTypes::writeItemStack), ObjectDataComponent::new); - public static final DataComponentType> BUNDLE_CONTENTS = new DataComponentType<>("bundle_contents", listReader(MinecraftTypes::readItemStack), listWriter(MinecraftTypes::writeItemStack), ObjectDataComponent::new); - public static final DataComponentType POTION_CONTENTS = new DataComponentType<>("potion_contents", ItemTypes::readPotionContents, ItemTypes::writePotionContents, ObjectDataComponent::new); - public static final DataComponentType> SUSPICIOUS_STEW_EFFECTS = new DataComponentType<>("suspicious_stew_effects", listReader(ItemTypes::readStewEffect), listWriter(ItemTypes::writeStewEffect), ObjectDataComponent::new); - public static final DataComponentType WRITABLE_BOOK_CONTENT = new DataComponentType<>("writable_book_content", ItemTypes::readWritableBookContent, ItemTypes::writeWritableBookContent, ObjectDataComponent::new); - public static final DataComponentType WRITTEN_BOOK_CONTENT = new DataComponentType<>("written_book_content", ItemTypes::readWrittenBookContent, ItemTypes::writeWrittenBookContent, ObjectDataComponent::new); - public static final DataComponentType TRIM = new DataComponentType<>("trim", ItemTypes::readArmorTrim, ItemTypes::writeArmorTrim, ObjectDataComponent::new); - public static final DataComponentType DEBUG_STICK_STATE = new DataComponentType<>("debug_stick_state", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final DataComponentType ENTITY_DATA = new DataComponentType<>("entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final DataComponentType BUCKET_ENTITY_DATA = new DataComponentType<>("bucket_entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final DataComponentType BLOCK_ENTITY_DATA = new DataComponentType<>("block_entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final DataComponentType> INSTRUMENT = new DataComponentType<>("instrument", ItemTypes::readInstrument, ItemTypes::writeInstrument, ObjectDataComponent::new); - public static final IntComponentType OMINOUS_BOTTLE_AMPLIFIER = new IntComponentType("ominous_bottle_amplifier", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType JUKEBOX_PLAYABLE = new DataComponentType<>("jukebox_playable", ItemTypes::readJukeboxPlayable, ItemTypes::writeJukeboxPlayable, ObjectDataComponent::new); - public static final DataComponentType> RECIPES = new DataComponentType<>("recipes", ItemTypes::readRecipes, ItemTypes::writeRecipes, ObjectDataComponent::new); - public static final DataComponentType LODESTONE_TRACKER = new DataComponentType<>("lodestone_tracker", ItemTypes::readLodestoneTarget, ItemTypes::writeLodestoneTarget, ObjectDataComponent::new); - public static final DataComponentType FIREWORK_EXPLOSION = new DataComponentType<>("firework_explosion", ItemTypes::readFireworkExplosion, ItemTypes::writeFireworkExplosion, ObjectDataComponent::new); - public static final DataComponentType FIREWORKS = new DataComponentType<>("fireworks", ItemTypes::readFireworks, ItemTypes::writeFireworks, ObjectDataComponent::new); - public static final DataComponentType PROFILE = new DataComponentType<>("profile", ItemTypes::readResolvableProfile, ItemTypes::writeResolvableProfile, ObjectDataComponent::new); - public static final DataComponentType NOTE_BLOCK_SOUND = new DataComponentType<>("note_block_sound", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new); - public static final DataComponentType> BANNER_PATTERNS = new DataComponentType<>("banner_patterns", listReader(ItemTypes::readBannerPatternLayer), listWriter(ItemTypes::writeBannerPatternLayer), ObjectDataComponent::new); - public static final IntComponentType BASE_COLOR = new IntComponentType("base_color", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new); - public static final DataComponentType> POT_DECORATIONS = new DataComponentType<>("pot_decorations", listReader(MinecraftTypes::readVarInt), listWriter(MinecraftTypes::writeVarInt), ObjectDataComponent::new); - public static final DataComponentType> CONTAINER = new DataComponentType<>("container", listReader(MinecraftTypes::readOptionalItemStack), listWriter(MinecraftTypes::writeOptionalItemStack), ObjectDataComponent::new); - public static final DataComponentType BLOCK_STATE = new DataComponentType<>("block_state", ItemTypes::readBlockStateProperties, ItemTypes::writeBlockStateProperties, ObjectDataComponent::new); - public static final DataComponentType> BEES = new DataComponentType<>("bees", listReader(ItemTypes::readBeehiveOccupant), listWriter(ItemTypes::writeBeehiveOccupant), ObjectDataComponent::new); - public static final DataComponentType LOCK = new DataComponentType<>("lock", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - public static final DataComponentType CONTAINER_LOOT = new DataComponentType<>("container_loot", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new); - protected final int id; protected final Key key; protected final Reader reader; protected final Writer writer; protected final DataComponentFactory dataComponentFactory; - protected DataComponentType(String key, Reader reader, Writer writer, DataComponentFactory dataComponentFactory) { - this.id = VALUES.size(); - //noinspection PatternValidation + protected DataComponentType(int id, @KeyPattern String key, Reader reader, Writer writer, DataComponentFactory dataComponentFactory) { + this.id = id; this.key = Key.key(key); this.reader = reader; this.writer = writer; this.dataComponentFactory = dataComponentFactory; - - VALUES.add(this); } public DataComponent> readDataComponent(ByteBuf input) { @@ -143,53 +58,6 @@ public interface DataComponentFactory { DataComponent> create(DataComponentType type, V value); } - private static Reader> listReader(Reader reader) { - return (input) -> { - List ret = new ArrayList<>(); - int size = MinecraftTypes.readVarInt(input); - for (int i = 0; i < size; i++) { - ret.add(reader.read(input)); - } - - return ret; - }; - } - - private static Writer> listWriter(Writer writer) { - return (output, value) -> { - MinecraftTypes.writeVarInt(output, value.size()); - for (T object : value) { - writer.write(output, object); - } - }; - } - - private static Reader unitReader() { - return (input) -> Unit.INSTANCE; - } - - private static Writer unitWriter() { - return (output, value) -> { - }; - } - - public static DataComponentType read(ByteBuf in) { - int id = MinecraftTypes.readVarInt(in); - if (id >= VALUES.size()) { - throw new IllegalArgumentException("Received id " + id + " for DataComponentType when the maximum was " + VALUES.size() + "!"); - } - - return VALUES.get(id); - } - - public static DataComponentType from(int id) { - return VALUES.get(id); - } - - public static int size() { - return VALUES.size(); - } - @Override public String toString() { return "DataComponentType(id=" + id + " , key=" + key.asString() + ")"; diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java new file mode 100644 index 000000000..b2af15c6d --- /dev/null +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponentTypes.java @@ -0,0 +1,145 @@ +package org.geysermc.mcprotocollib.protocol.data.game.item.component; + +import io.netty.buffer.ByteBuf; +import it.unimi.dsi.fastutil.ints.Int2ObjectFunction; +import lombok.Getter; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; +import org.cloudburstmc.nbt.NbtList; +import org.cloudburstmc.nbt.NbtMap; +import org.geysermc.mcprotocollib.auth.GameProfile; +import org.geysermc.mcprotocollib.protocol.codec.MinecraftTypes; +import org.geysermc.mcprotocollib.protocol.data.game.Holder; +import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.BooleanDataComponent; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.IntDataComponent; +import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.ObjectDataComponent; + +import java.util.ArrayList; +import java.util.List; + +@Getter +public class DataComponentTypes { + private static final List> VALUES = new ArrayList<>(); + + public static final DataComponentType CUSTOM_DATA = register(id -> new DataComponentType<>(id, "custom_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final IntComponentType MAX_STACK_SIZE = register(id -> new IntComponentType(id, "max_stack_size", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final IntComponentType MAX_DAMAGE = register(id -> new IntComponentType(id, "max_damage", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final IntComponentType DAMAGE = register(id -> new IntComponentType(id, "damage", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType UNBREAKABLE = register(id -> new DataComponentType<>(id, "unbreakable", ItemTypes::readUnbreakable, ItemTypes::writeUnbreakable, ObjectDataComponent::new)); + public static final DataComponentType CUSTOM_NAME = register(id -> new DataComponentType<>(id, "custom_name", MinecraftTypes::readComponent, MinecraftTypes::writeComponent, ObjectDataComponent::new)); + public static final DataComponentType ITEM_NAME = register(id -> new DataComponentType<>(id, "item_name", MinecraftTypes::readComponent, MinecraftTypes::writeComponent, ObjectDataComponent::new)); + public static final DataComponentType ITEM_MODEL = register(id -> new DataComponentType<>(id, "item_model", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new)); + public static final DataComponentType> LORE = register(id -> new DataComponentType<>(id, "lore", listReader(MinecraftTypes::readComponent), listWriter(MinecraftTypes::writeComponent), ObjectDataComponent::new)); + public static final IntComponentType RARITY = register(id -> new IntComponentType(id, "rarity", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType ENCHANTMENTS = register(id -> new DataComponentType<>(id, "enchantments", ItemTypes::readItemEnchantments, ItemTypes::writeItemEnchantments, ObjectDataComponent::new)); + public static final DataComponentType CAN_PLACE_ON = register(id -> new DataComponentType<>(id, "can_place_on", ItemTypes::readAdventureModePredicate, ItemTypes::writeAdventureModePredicate, ObjectDataComponent::new)); + public static final DataComponentType CAN_BREAK = register(id -> new DataComponentType<>(id, "can_break", ItemTypes::readAdventureModePredicate, ItemTypes::writeAdventureModePredicate, ObjectDataComponent::new)); + public static final DataComponentType ATTRIBUTE_MODIFIERS = register(id -> new DataComponentType<>(id, "attribute_modifiers", ItemTypes::readItemAttributeModifiers, ItemTypes::writeItemAttributeModifiers, ObjectDataComponent::new)); + public static final DataComponentType CUSTOM_MODEL_DATA = register(id -> new DataComponentType<>(id, "custom_model_data", ItemTypes::readCustomModelData, ItemTypes::writeCustomModelData, ObjectDataComponent::new)); + public static final DataComponentType HIDE_ADDITIONAL_TOOLTIP = register(id -> new DataComponentType<>(id, "hide_additional_tooltip", unitReader(), unitWriter(), ObjectDataComponent::new)); + public static final DataComponentType HIDE_TOOLTIP = register(id -> new DataComponentType<>(id, "hide_tooltip", unitReader(), unitWriter(), ObjectDataComponent::new)); + public static final IntComponentType REPAIR_COST = register(id -> new IntComponentType(id, "repair_cost", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType CREATIVE_SLOT_LOCK = register(id -> new DataComponentType<>(id, "creative_slot_lock", unitReader(), unitWriter(), ObjectDataComponent::new)); + public static final BooleanComponentType ENCHANTMENT_GLINT_OVERRIDE = register(id -> new BooleanComponentType(id, "enchantment_glint_override", ByteBuf::readBoolean, ByteBuf::writeBoolean, BooleanDataComponent::new)); + public static final DataComponentType INTANGIBLE_PROJECTILE = register(id -> new DataComponentType<>(id, "intangible_projectile", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType FOOD = register(id -> new DataComponentType<>(id, "food", ItemTypes::readFoodProperties, ItemTypes::writeFoodProperties, ObjectDataComponent::new)); + public static final DataComponentType CONSUMABLE = register(id -> new DataComponentType<>(id, "consumable", ItemTypes::readConsumable, ItemTypes::writeConsumable, ObjectDataComponent::new)); + public static final DataComponentType USE_REMAINDER = register(id -> new DataComponentType<>(id, "use_remainder", MinecraftTypes::readItemStack, MinecraftTypes::writeItemStack, ObjectDataComponent::new)); + public static final DataComponentType USE_COOLDOWN = register(id -> new DataComponentType<>(id, "use_cooldown", ItemTypes::readUseCooldown, ItemTypes::writeUseCooldown, ObjectDataComponent::new)); + public static final DataComponentType DAMAGE_RESISTANT = register(id -> new DataComponentType<>(id, "damage_resistant", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new)); + public static final DataComponentType TOOL = register(id -> new DataComponentType<>(id, "tool", ItemTypes::readToolData, ItemTypes::writeToolData, ObjectDataComponent::new)); + public static final IntComponentType ENCHANTABLE = register(id -> new IntComponentType(id, "enchantable", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType EQUIPPABLE = register(id -> new DataComponentType<>(id, "equippable", ItemTypes::readEquippable, ItemTypes::writeEquippable, ObjectDataComponent::new)); + public static final DataComponentType REPAIRABLE = register(id -> new DataComponentType<>(id, "repairable", MinecraftTypes::readHolderSet, MinecraftTypes::writeHolderSet, ObjectDataComponent::new)); + public static final DataComponentType GLIDER = register(id -> new DataComponentType<>(id, "glider", unitReader(), unitWriter(), ObjectDataComponent::new)); + public static final DataComponentType TOOLTIP_STYLE = register(id -> new DataComponentType<>(id, "tooltip_style", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new)); + public static final DataComponentType> DEATH_PROTECTION = register(id -> new DataComponentType<>(id, "death_protection", listReader(ItemTypes::readConsumeEffect), listWriter(ItemTypes::writeConsumeEffect), ObjectDataComponent::new)); + public static final DataComponentType STORED_ENCHANTMENTS = register(id -> new DataComponentType<>(id, "stored_enchantments", ItemTypes::readItemEnchantments, ItemTypes::writeItemEnchantments, ObjectDataComponent::new)); + public static final DataComponentType DYED_COLOR = register(id -> new DataComponentType<>(id, "dyed_color", ItemTypes::readDyedItemColor, ItemTypes::writeDyedItemColor, ObjectDataComponent::new)); + public static final IntComponentType MAP_COLOR = register(id -> new IntComponentType(id, "map_color", ByteBuf::readInt, ByteBuf::writeInt, IntDataComponent::new)); + public static final IntComponentType MAP_ID = register(id -> new IntComponentType(id, "map_id", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType MAP_DECORATIONS = register(id -> new DataComponentType<>(id, "map_decorations", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final IntComponentType MAP_POST_PROCESSING = register(id -> new IntComponentType(id, "map_post_processing", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType> CHARGED_PROJECTILES = register(id -> new DataComponentType<>(id, "charged_projectiles", listReader(MinecraftTypes::readItemStack), listWriter(MinecraftTypes::writeItemStack), ObjectDataComponent::new)); + public static final DataComponentType> BUNDLE_CONTENTS = register(id -> new DataComponentType<>(id, "bundle_contents", listReader(MinecraftTypes::readItemStack), listWriter(MinecraftTypes::writeItemStack), ObjectDataComponent::new)); + public static final DataComponentType POTION_CONTENTS = register(id -> new DataComponentType<>(id, "potion_contents", ItemTypes::readPotionContents, ItemTypes::writePotionContents, ObjectDataComponent::new)); + public static final DataComponentType> SUSPICIOUS_STEW_EFFECTS = register(id -> new DataComponentType<>(id, "suspicious_stew_effects", listReader(ItemTypes::readStewEffect), listWriter(ItemTypes::writeStewEffect), ObjectDataComponent::new)); + public static final DataComponentType WRITABLE_BOOK_CONTENT = register(id -> new DataComponentType<>(id, "writable_book_content", ItemTypes::readWritableBookContent, ItemTypes::writeWritableBookContent, ObjectDataComponent::new)); + public static final DataComponentType WRITTEN_BOOK_CONTENT = register(id -> new DataComponentType<>(id, "written_book_content", ItemTypes::readWrittenBookContent, ItemTypes::writeWrittenBookContent, ObjectDataComponent::new)); + public static final DataComponentType TRIM = register(id -> new DataComponentType<>(id, "trim", ItemTypes::readArmorTrim, ItemTypes::writeArmorTrim, ObjectDataComponent::new)); + public static final DataComponentType DEBUG_STICK_STATE = register(id -> new DataComponentType<>(id, "debug_stick_state", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType ENTITY_DATA = register(id -> new DataComponentType<>(id, "entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType BUCKET_ENTITY_DATA = register(id -> new DataComponentType<>(id, "bucket_entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType BLOCK_ENTITY_DATA = register(id -> new DataComponentType<>(id, "block_entity_data", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType> INSTRUMENT = register(id -> new DataComponentType<>(id, "instrument", ItemTypes::readInstrument, ItemTypes::writeInstrument, ObjectDataComponent::new)); + public static final IntComponentType OMINOUS_BOTTLE_AMPLIFIER = register(id -> new IntComponentType(id, "ominous_bottle_amplifier", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType JUKEBOX_PLAYABLE = register(id -> new DataComponentType<>(id, "jukebox_playable", ItemTypes::readJukeboxPlayable, ItemTypes::writeJukeboxPlayable, ObjectDataComponent::new)); + public static final DataComponentType> RECIPES = register(id -> new DataComponentType<>(id, "recipes", ItemTypes::readRecipes, ItemTypes::writeRecipes, ObjectDataComponent::new)); + public static final DataComponentType LODESTONE_TRACKER = register(id -> new DataComponentType<>(id, "lodestone_tracker", ItemTypes::readLodestoneTarget, ItemTypes::writeLodestoneTarget, ObjectDataComponent::new)); + public static final DataComponentType FIREWORK_EXPLOSION = register(id -> new DataComponentType<>(id, "firework_explosion", ItemTypes::readFireworkExplosion, ItemTypes::writeFireworkExplosion, ObjectDataComponent::new)); + public static final DataComponentType FIREWORKS = register(id -> new DataComponentType<>(id, "fireworks", ItemTypes::readFireworks, ItemTypes::writeFireworks, ObjectDataComponent::new)); + public static final DataComponentType PROFILE = register(id -> new DataComponentType<>(id, "profile", ItemTypes::readResolvableProfile, ItemTypes::writeResolvableProfile, ObjectDataComponent::new)); + public static final DataComponentType NOTE_BLOCK_SOUND = register(id -> new DataComponentType<>(id, "note_block_sound", MinecraftTypes::readResourceLocation, MinecraftTypes::writeResourceLocation, ObjectDataComponent::new)); + public static final DataComponentType> BANNER_PATTERNS = register(id -> new DataComponentType<>(id, "banner_patterns", listReader(ItemTypes::readBannerPatternLayer), listWriter(ItemTypes::writeBannerPatternLayer), ObjectDataComponent::new)); + public static final IntComponentType BASE_COLOR = register(id -> new IntComponentType(id, "base_color", MinecraftTypes::readVarInt, MinecraftTypes::writeVarInt, IntDataComponent::new)); + public static final DataComponentType> POT_DECORATIONS = register(id -> new DataComponentType<>(id, "pot_decorations", listReader(MinecraftTypes::readVarInt), listWriter(MinecraftTypes::writeVarInt), ObjectDataComponent::new)); + public static final DataComponentType> CONTAINER = register(id -> new DataComponentType<>(id, "container", listReader(MinecraftTypes::readOptionalItemStack), listWriter(MinecraftTypes::writeOptionalItemStack), ObjectDataComponent::new)); + public static final DataComponentType BLOCK_STATE = register(id -> new DataComponentType<>(id, "block_state", ItemTypes::readBlockStateProperties, ItemTypes::writeBlockStateProperties, ObjectDataComponent::new)); + public static final DataComponentType> BEES = register(id -> new DataComponentType<>(id, "bees", listReader(ItemTypes::readBeehiveOccupant), listWriter(ItemTypes::writeBeehiveOccupant), ObjectDataComponent::new)); + public static final DataComponentType LOCK = register(id -> new DataComponentType<>(id, "lock", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + public static final DataComponentType CONTAINER_LOOT = register(id -> new DataComponentType<>(id, "container_loot", MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectDataComponent::new)); + + public static > T register(Int2ObjectFunction factory) { + T value = factory.apply(VALUES.size()); + VALUES.add(value); + return value; + } + + private static DataComponentType.Reader> listReader(DataComponentType.Reader reader) { + return (input) -> { + List ret = new ArrayList<>(); + int size = MinecraftTypes.readVarInt(input); + for (int i = 0; i < size; i++) { + ret.add(reader.read(input)); + } + + return ret; + }; + } + + private static DataComponentType.Writer> listWriter(DataComponentType.Writer writer) { + return (output, value) -> { + MinecraftTypes.writeVarInt(output, value.size()); + for (T object : value) { + writer.write(output, object); + } + }; + } + + private static DataComponentType.Reader unitReader() { + return (input) -> Unit.INSTANCE; + } + + private static DataComponentType.Writer unitWriter() { + return (output, value) -> { + }; + } + + public static DataComponentType read(ByteBuf in) { + int id = MinecraftTypes.readVarInt(in); + if (id >= VALUES.size()) { + throw new IllegalArgumentException("Received id " + id + " for DataComponentType when the maximum was " + VALUES.size() + "!"); + } + + return VALUES.get(id); + } + + public static DataComponentType from(int id) { + return VALUES.get(id); + } + + public static int size() { + return VALUES.size(); + } +} diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponents.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponents.java index d29501e97..5fba63e13 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponents.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/DataComponents.java @@ -14,8 +14,9 @@ public class DataComponents { private final Map, DataComponent> dataComponents; @Nullable + @SuppressWarnings("unchecked") public T get(DataComponentType type) { - DataComponent component = dataComponents.get(type); + DataComponent component = dataComponents.get(type); return component == null ? null : (T) component.getValue(); } diff --git a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/IntComponentType.java b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/IntComponentType.java index f2aa5f554..54b5a177c 100644 --- a/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/IntComponentType.java +++ b/protocol/src/main/java/org/geysermc/mcprotocollib/protocol/data/game/item/component/IntComponentType.java @@ -1,6 +1,7 @@ package org.geysermc.mcprotocollib.protocol.data.game.item.component; import io.netty.buffer.ByteBuf; +import net.kyori.adventure.key.KeyPattern; import org.geysermc.mcprotocollib.protocol.data.game.item.component.type.IntDataComponent; public class IntComponentType extends DataComponentType { @@ -8,8 +9,8 @@ public class IntComponentType extends DataComponentType { protected final IntWriter primitiveWriter; protected final IntDataComponentFactory primitiveFactory; - protected IntComponentType(String key, IntReader reader, IntWriter writer, IntDataComponentFactory metadataFactory) { - super(key, reader, writer, metadataFactory); + protected IntComponentType(int id, @KeyPattern String key, IntReader reader, IntWriter writer, IntDataComponentFactory metadataFactory) { + super(id, key, reader, writer, metadataFactory); this.primitiveReader = reader; this.primitiveWriter = writer; diff --git a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetEntityDataPacketTest.java b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetEntityDataPacketTest.java index f11e1225a..4e6062561 100644 --- a/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetEntityDataPacketTest.java +++ b/protocol/src/test/java/org/geysermc/mcprotocollib/protocol/packet/ingame/clientbound/level/ClientboundSetEntityDataPacketTest.java @@ -2,7 +2,7 @@ import org.cloudburstmc.math.vector.Vector3i; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata; -import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataTypes; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata; @@ -23,23 +23,23 @@ public void setup() { this.setPackets( new ClientboundSetEntityDataPacket(0, new EntityMetadata[0]), new ClientboundSetEntityDataPacket(20, new EntityMetadata[]{ - new ObjectEntityMetadata<>(1, MetadataType.STRING, "Hello!") + new ObjectEntityMetadata<>(1, MetadataTypes.STRING, "Hello!") }), new ClientboundSetEntityDataPacket(2, new EntityMetadata[]{ - new BooleanEntityMetadata(0, MetadataType.BOOLEAN, true), - new ByteEntityMetadata(4, MetadataType.BYTE, (byte) 45), - new IntEntityMetadata(2, MetadataType.INT, 555), - new FloatEntityMetadata(3, MetadataType.FLOAT, 3.0f), - new LongEntityMetadata(8, MetadataType.LONG, 123456789L), - new ObjectEntityMetadata<>(5, MetadataType.POSITION, Vector3i.from(0, 1, 0)), - new ObjectEntityMetadata<>(2, MetadataType.BLOCK_STATE, 60), - new ObjectEntityMetadata<>(6, MetadataType.DIRECTION, Direction.EAST), - new ObjectEntityMetadata<>(7, MetadataType.OPTIONAL_VARINT, OptionalInt.of(1038)) + new BooleanEntityMetadata(0, MetadataTypes.BOOLEAN, true), + new ByteEntityMetadata(4, MetadataTypes.BYTE, (byte) 45), + new IntEntityMetadata(2, MetadataTypes.INT, 555), + new FloatEntityMetadata(3, MetadataTypes.FLOAT, 3.0f), + new LongEntityMetadata(8, MetadataTypes.LONG, 123456789L), + new ObjectEntityMetadata<>(5, MetadataTypes.POSITION, Vector3i.from(0, 1, 0)), + new ObjectEntityMetadata<>(2, MetadataTypes.BLOCK_STATE, 60), + new ObjectEntityMetadata<>(6, MetadataTypes.DIRECTION, Direction.EAST), + new ObjectEntityMetadata<>(7, MetadataTypes.OPTIONAL_VARINT, OptionalInt.of(1038)) }), new ClientboundSetEntityDataPacket(700, new EntityMetadata[]{ // Boxed variation test - new ObjectEntityMetadata<>(0, MetadataType.INT, 0), - new ObjectEntityMetadata<>(1, MetadataType.FLOAT, 1.0f) + new ObjectEntityMetadata<>(0, MetadataTypes.INT, 0), + new ObjectEntityMetadata<>(1, MetadataTypes.FLOAT, 1.0f) }) ); }