From 278ca4cc947711c12b6f5599df3a176f728191f2 Mon Sep 17 00:00:00 2001 From: Dragon-Seeker Date: Mon, 11 Nov 2024 17:05:55 -0600 Subject: [PATCH] Fix issues with incorrectly reading optional fields for NBT --- .../format/nbt/IdentityHolder.java | 19 +++++++++++++++++++ .../format/nbt/NbtDeserializer.java | 11 ++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/main/java/io/wispforest/owo/serialization/format/nbt/IdentityHolder.java diff --git a/src/main/java/io/wispforest/owo/serialization/format/nbt/IdentityHolder.java b/src/main/java/io/wispforest/owo/serialization/format/nbt/IdentityHolder.java new file mode 100644 index 00000000..b7cec897 --- /dev/null +++ b/src/main/java/io/wispforest/owo/serialization/format/nbt/IdentityHolder.java @@ -0,0 +1,19 @@ +package io.wispforest.owo.serialization.format.nbt; + +record IdentityHolder(T t) { + @Override + public boolean equals(Object obj) { + if (obj == null || obj.getClass() != this.getClass()) return false; + return this.t == ((IdentityHolder) obj).t; + } + + @Override + public int hashCode() { + return System.identityHashCode(this.t); + } + + @Override + public String toString() { + return "IdentityHolder[t=" + t + ']'; + } +} diff --git a/src/main/java/io/wispforest/owo/serialization/format/nbt/NbtDeserializer.java b/src/main/java/io/wispforest/owo/serialization/format/nbt/NbtDeserializer.java index b8b49b7c..c1eefb6c 100644 --- a/src/main/java/io/wispforest/owo/serialization/format/nbt/NbtDeserializer.java +++ b/src/main/java/io/wispforest/owo/serialization/format/nbt/NbtDeserializer.java @@ -87,8 +87,15 @@ public byte[] readBytes(SerializationContext ctx) { return this.getAs(this.getValue(), NbtByteArray.class).getByteArray(); } + private final Set> encodedOptionals = Collections.newSetFromMap(new WeakHashMap<>()); + @Override public Optional readOptional(SerializationContext ctx, Endec endec) { + var value = this.getValue(); + if (this.encodedOptionals.contains(new IdentityHolder<>(value))) { + return Optional.of(endec.decode(ctx, this)); + } + var struct = this.struct(); return struct.field("present", ctx, Endec.BOOLEAN) ? Optional.of(struct.field("value", ctx, endec)) @@ -239,8 +246,10 @@ public Struct(NbtCompound compound) { return defaultValueFactory.get(); } + var element = this.compound.get(name); + if (defaultValueFactory != null) NbtDeserializer.this.encodedOptionals.add(new IdentityHolder<>(element)); return NbtDeserializer.this.frame( - () -> this.compound.get(name), + () -> element, () -> endec.decode(ctx, NbtDeserializer.this) ); }