diff --git a/src/main/java/net/minestom/server/tag/Serializers.java b/src/main/java/net/minestom/server/tag/Serializers.java index 11c03f40a..4f22e5e99 100644 --- a/src/main/java/net/minestom/server/tag/Serializers.java +++ b/src/main/java/net/minestom/server/tag/Serializers.java @@ -12,26 +12,26 @@ import java.util.function.Function; * Basic serializers for {@link Tag tags}. */ final class Serializers { - static final Entry PATH = new Entry<>(TagHandlerImpl::fromCompound, TagHandlerImpl::asCompound); + static final Entry PATH = new Entry<>(NBTCompound.class, TagHandlerImpl::fromCompound, TagHandlerImpl::asCompound); - static final Entry BYTE = new Entry<>(NBTByte::getValue, NBT::Byte); - static final Entry BOOLEAN = new Entry<>(NBTByte::asBoolean, NBT::Boolean); - static final Entry SHORT = new Entry<>(NBTShort::getValue, NBT::Short); - static final Entry INT = new Entry<>(NBTInt::getValue, NBT::Int); - static final Entry LONG = new Entry<>(NBTLong::getValue, NBT::Long); - static final Entry FLOAT = new Entry<>(NBTFloat::getValue, NBT::Float); - static final Entry DOUBLE = new Entry<>(NBTDouble::getValue, NBT::Double); - static final Entry STRING = new Entry<>(NBTString::getValue, NBT::String); - static final Entry NBT_ENTRY = new Entry<>(Function.identity(), Function.identity()); + static final Entry BYTE = new Entry<>(NBTByte.class, NBTByte::getValue, NBT::Byte); + static final Entry BOOLEAN = new Entry<>(NBTByte.class, NBTByte::asBoolean, NBT::Boolean); + static final Entry SHORT = new Entry<>(NBTShort.class, NBTShort::getValue, NBT::Short); + static final Entry INT = new Entry<>(NBTInt.class, NBTInt::getValue, NBT::Int); + static final Entry LONG = new Entry<>(NBTLong.class, NBTLong::getValue, NBT::Long); + static final Entry FLOAT = new Entry<>(NBTFloat.class, NBTFloat::getValue, NBT::Float); + static final Entry DOUBLE = new Entry<>(NBTDouble.class, NBTDouble::getValue, NBT::Double); + static final Entry STRING = new Entry<>(NBTString.class, NBTString::getValue, NBT::String); + static final Entry NBT_ENTRY = new Entry<>(NBT.class, Function.identity(), Function.identity()); - static final Entry UUID = new Entry<>(intArray -> Utils.intArrayToUuid(intArray.getValue().copyArray()), + static final Entry UUID = new Entry<>(NBTIntArray.class, intArray -> Utils.intArrayToUuid(intArray.getValue().copyArray()), uuid -> NBT.IntArray(Utils.uuidToIntArray(uuid))); - static final Entry ITEM = new Entry<>(ItemStack::fromItemNBT, ItemStack::toItemNBT); - static final Entry COMPONENT = new Entry<>(input -> GsonComponentSerializer.gson().deserialize(input.getValue()), + static final Entry ITEM = new Entry<>(NBTCompound.class, ItemStack::fromItemNBT, ItemStack::toItemNBT); + static final Entry COMPONENT = new Entry<>(NBTString.class, input -> GsonComponentSerializer.gson().deserialize(input.getValue()), component -> NBT.String(GsonComponentSerializer.gson().serialize(component))); static Entry fromTagSerializer(TagSerializer serializer) { - return new Serializers.Entry<>( + return new Serializers.Entry<>(NBTCompound.class, (NBTCompound compound) -> { if (compound.isEmpty()) return null; return serializer.read(TagHandler.fromCompound(compound)); @@ -44,6 +44,13 @@ final class Serializers { }); } - record Entry(Function read, Function write) { + record Entry(Class nbtType, Function reader, Function writer) { + T read(N nbt) { + return reader.apply(nbt); + } + + N write(T value) { + return writer.apply(value); + } } } diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index ab3b72c5d..ddb98ba4e 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -62,7 +62,7 @@ public class Tag { } static Tag tag(@NotNull String key, @NotNull Serializers.Entry entry) { - return new Tag<>(INDEX_MAP.get(key), key, entry.read(), (Serializers.Entry) entry, + return new Tag<>(INDEX_MAP.get(key), key, entry.reader(), (Serializers.Entry) entry, null, null, null, 0); } @@ -98,13 +98,13 @@ public class Tag { public Tag map(@NotNull Function readMap, @NotNull Function writeMap) { var entry = this.entry; - final Function readFunction = entry.read().andThen(t -> { + final Function readFunction = entry.reader().andThen(t -> { if (t == null) return null; return readMap.apply(t); }); - final Function writeFunction = writeMap.andThen(entry.write()); + final Function writeFunction = writeMap.andThen(entry.writer()); return new Tag<>(index, key, readMap, - new Serializers.Entry<>(readFunction, writeFunction), + new Serializers.Entry<>(entry.nbtType(), readFunction, writeFunction), // Default value () -> { T defaultValue = createDefault(); @@ -118,9 +118,10 @@ public class Tag { @Contract(value = "-> new", pure = true) public Tag> list() { var entry = this.entry; - var readFunction = entry.read(); - var writeFunction = entry.write(); - var listEntry = new Serializers.Entry, NBT>( + var readFunction = entry.reader(); + var writeFunction = entry.writer(); + var listEntry = new Serializers.Entry, NBTList>( + NBTList.class, read -> { var list = (NBTList) read; final int size = list.getSize(); @@ -161,7 +162,8 @@ public class Tag { } return shallowCopy ? List.copyOf(ts) : List.of(array); } : List::copyOf; - return new Tag<>(index, key, readComparator, listEntry, null, path, co, listScope + 1); + return new Tag<>(index, key, readComparator, Serializers.Entry.class.cast(listEntry), + null, path, co, listScope + 1); } @ApiStatus.Experimental @@ -184,7 +186,7 @@ public class Tag { final NBT readable = isView() ? nbt.toCompound() : nbt.get(key); final T result; try { - if (readable == null || (result = entry.read().apply(readable)) == null) + if (readable == null || (result = entry.read(readable)) == null) return createDefault(); return result; } catch (ClassCastException e) { @@ -194,7 +196,7 @@ public class Tag { public void write(@NotNull MutableNBTCompound nbtCompound, @Nullable T value) { if (value != null) { - final NBT nbt = entry.write().apply(value); + final NBT nbt = entry.write(value); if (isView()) nbtCompound.copyFrom((NBTCompoundLike) nbt); else nbtCompound.set(key, nbt); } else { diff --git a/src/main/java/net/minestom/server/tag/TagHandlerImpl.java b/src/main/java/net/minestom/server/tag/TagHandlerImpl.java index 0aaf2f960..a555885b4 100644 --- a/src/main/java/net/minestom/server/tag/TagHandlerImpl.java +++ b/src/main/java/net/minestom/server/tag/TagHandlerImpl.java @@ -186,11 +186,9 @@ final class TagHandlerImpl implements TagHandler { } // Value must be parsed from nbt if the tag is different final NBT nbt = entry.updatedNbt(); - try { - return tag.entry.read().apply(nbt); - } catch (ClassCastException e) { - return tag.createDefault(); - } + final Serializers.Entry serializerEntry = tag.entry; + return serializerEntry.nbtType().isAssignableFrom(nbt.getClass()) ? + serializerEntry.read(nbt) : tag.createDefault(); } private static Int2ObjectOpenHashMap> traversePath(Tag.PathEntry[] paths, @@ -256,7 +254,7 @@ final class TagHandlerImpl implements TagHandler { @Override public NBT updatedNbt() { NBT nbt = this.nbt; - if (nbt == null) this.nbt = nbt = tag.entry.write().apply(value); + if (nbt == null) this.nbt = nbt = tag.entry.write(value); return nbt; } }