Skip to content

Commit

Permalink
Split up MetadataType into MetadataTypes & DataComponents too (#883)
Browse files Browse the repository at this point in the history
* Split up MetadataType into MetadataTypes

This is mainly to avoid thread deadlocking issues that may occur from a parent class early initializing child classes. The other reason is that this is cleaner and makes the code for MetadataTypes more readable. It also simplifies the initialization of metadatatypes by adding id as a constructor.

* Update some datacomponents code

* Also split DataComponents into DataComponents class

* Remove not needed diff
  • Loading branch information
AlexProgrammerDE authored Feb 18, 2025
1 parent 0e21212 commit 04834f2
Show file tree
Hide file tree
Showing 15 changed files with 332 additions and 302 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -448,13 +450,13 @@ public static DataComponents readDataComponentPatch(ByteBuf buf) {

Map<DataComponentType<?>, 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);
}
Expand Down Expand Up @@ -503,7 +505,7 @@ public static ItemStack readTradeItemStack(ByteBuf buf) {

Map<DataComponentType<?>, 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);
}
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public class BooleanMetadataType extends MetadataType<Boolean> {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public class ByteMetadataType extends MetadataType<Byte> {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public class FloatMetadataType extends MetadataType<Float> {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public class IntMetadataType extends MetadataType<Integer> {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public class LongMetadataType extends MetadataType<Long> {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
private static final List<MetadataType<?>> 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> STRING = new MetadataType<>(MinecraftTypes::readString, MinecraftTypes::writeString, ObjectEntityMetadata::new);
public static final MetadataType<Component> CHAT = new MetadataType<>(MinecraftTypes::readComponent, MinecraftTypes::writeComponent, ObjectEntityMetadata::new);
public static final MetadataType<Optional<Component>> OPTIONAL_CHAT = new MetadataType<>(optionalReader(MinecraftTypes::readComponent), optionalWriter(MinecraftTypes::writeComponent), ObjectEntityMetadata::new);
public static final MetadataType<ItemStack> 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<Vector3f> ROTATION = new MetadataType<>(MinecraftTypes::readRotation, MinecraftTypes::writeRotation, ObjectEntityMetadata::new);
public static final MetadataType<Vector3i> POSITION = new MetadataType<>(MinecraftTypes::readPosition, MinecraftTypes::writePosition, ObjectEntityMetadata::new);
public static final MetadataType<Optional<Vector3i>> OPTIONAL_POSITION = new MetadataType<>(optionalReader(MinecraftTypes::readPosition), optionalWriter(MinecraftTypes::writePosition), ObjectEntityMetadata::new);
public static final MetadataType<Direction> DIRECTION = new MetadataType<>(MinecraftTypes::readDirection, MinecraftTypes::writeDirection, ObjectEntityMetadata::new);
public static final MetadataType<Optional<UUID>> 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<NbtMap> NBT_TAG = new MetadataType<>(MinecraftTypes::readCompoundTag, MinecraftTypes::writeAnyTag, ObjectEntityMetadata::new);
public static final MetadataType<Particle> PARTICLE = new MetadataType<>(MinecraftTypes::readParticle, MinecraftTypes::writeParticle, ObjectEntityMetadata::new);
public static final MetadataType<List<Particle>> PARTICLES = new MetadataType<>(listReader(MinecraftTypes::readParticle), listWriter(MinecraftTypes::writeParticle), ObjectEntityMetadata::new);
public static final MetadataType<VillagerData> 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> 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<Holder<WolfVariant>> 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<GlobalPos>> OPTIONAL_GLOBAL_POS = new MetadataType<>(optionalReader(MinecraftTypes::readGlobalPos), optionalWriter(MinecraftTypes::writeGlobalPos), ObjectEntityMetadata::new);
public static final MetadataType<Holder<PaintingVariant>> PAINTING_VARIANT = new MetadataType<>(MinecraftTypes::readPaintingVariant, MinecraftTypes::writePaintingVariant, ObjectEntityMetadata::new);
public static final MetadataType<SnifferState> SNIFFER_STATE = new MetadataType<>(MinecraftTypes::readSnifferState, MinecraftTypes::writeSnifferState, ObjectEntityMetadata::new);
public static final MetadataType<ArmadilloState> ARMADILLO_STATE = new MetadataType<>(MinecraftTypes::readArmadilloState, MinecraftTypes::writeArmadilloState, ObjectEntityMetadata::new);
public static final MetadataType<Vector3f> VECTOR3 = new MetadataType<>(MinecraftTypes::readRotation, MinecraftTypes::writeRotation, ObjectEntityMetadata::new);
public static final MetadataType<Vector4f> QUATERNION = new MetadataType<>(MinecraftTypes::readQuaternion, MinecraftTypes::writeQuaternion, ObjectEntityMetadata::new);

protected final int id;
protected final Reader<T> reader;
protected final Writer<T> writer;
protected final EntityMetadataFactory<T> metadataFactory;

protected MetadataType(Reader<T> reader, Writer<T> writer, EntityMetadataFactory<T> metadataFactory) {
this.id = VALUES.size();
protected MetadataType(int id, Reader<T> reader, Writer<T> writer, EntityMetadataFactory<T> metadataFactory) {
this.id = id;
this.reader = reader;
this.writer = writer;
this.metadataFactory = metadataFactory;

VALUES.add(this);
}

public EntityMetadata<T, ? extends MetadataType<T>> readMetadata(ByteBuf input, int id) {
Expand Down Expand Up @@ -106,76 +49,4 @@ public interface BasicWriter<V> extends Writer<V> {
public interface EntityMetadataFactory<V> {
EntityMetadata<V, ? extends MetadataType<V>> create(int id, MetadataType<V> type, V value);
}

private static <T> BasicReader<Optional<T>> optionalReader(BasicReader<T> reader) {
return input -> {
if (!input.readBoolean()) {
return Optional.empty();
}

return Optional.of(reader.read(input));
};
}

private static <T> Reader<Optional<T>> optionalReader(Reader<T> reader) {
return (input) -> {
if (!input.readBoolean()) {
return Optional.empty();
}

return Optional.of(reader.read(input));
};
}

private static <T> BasicWriter<Optional<T>> optionalWriter(BasicWriter<T> writer) {
return (output, value) -> {
output.writeBoolean(value.isPresent());
value.ifPresent(t -> writer.write(output, t));
};
}

private static <T> Writer<Optional<T>> optionalWriter(Writer<T> writer) {
return (output, value) -> {
output.writeBoolean(value.isPresent());
value.ifPresent(t -> writer.write(output, t));
};
}

private static <T> Reader<List<T>> listReader(Reader<T> reader) {
return (input) -> {
List<T> ret = new ArrayList<>();
int size = MinecraftTypes.readVarInt(input);
for (int i = 0; i < size; i++) {
ret.add(reader.read(input));
}

return ret;
};
}

private static <T> Writer<List<T>> listWriter(Writer<T> 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();
}
}
Loading

0 comments on commit 04834f2

Please sign in to comment.