Skip to content

Commit

Permalink
Update NBT format for proper optional flattening
Browse files Browse the repository at this point in the history
  • Loading branch information
Dragon-Seeker committed Oct 25, 2024
1 parent edf6f59 commit 1653358
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 41 deletions.
8 changes: 4 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ dependencies {
modCompileOnly("com.terraformersmc:modmenu:${project.modmenu_version}")
modLocalRuntime("com.terraformersmc:modmenu:${project.modmenu_version}")

include api("io.wispforest:endec:0.1.5")
include api("io.wispforest.endec:netty:0.1.2")
include api("io.wispforest.endec:gson:0.1.3")
include api("io.wispforest.endec:jankson:0.1.3")
include api("io.wispforest:endec:0.1.9")
include api("io.wispforest.endec:netty:0.1.5")
include api("io.wispforest.endec:gson:0.1.6")
include api("io.wispforest.endec:jankson:0.1.6")

include api("blue.endless:jankson:${project.jankson_version}")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Supplier;

public class NbtDeserializer extends RecursiveDeserializer<NbtElement> implements SelfDescribedDeserializer<NbtElement> {

Expand Down Expand Up @@ -88,14 +89,10 @@ public byte[] readBytes(SerializationContext ctx) {

@Override
public <V> Optional<V> readOptional(SerializationContext ctx, Endec<V> endec) {
if (this.isReadingStructField()) {
return Optional.of(endec.decode(ctx, this));
} else {
var struct = this.struct();
return struct.field("present", ctx, Endec.BOOLEAN)
? Optional.of(struct.field("value", ctx, endec))
: Optional.empty();
}
var struct = this.struct();
return struct.field("present", ctx, Endec.BOOLEAN)
? Optional.of(struct.field("value", ctx, endec))
: Optional.empty();
}

// ---
Expand Down Expand Up @@ -183,8 +180,7 @@ public boolean hasNext() {
public V next() {
return NbtDeserializer.this.frame(
this.elements::next,
() -> this.valueEndec.decode(this.ctx, NbtDeserializer.this),
false
() -> this.valueEndec.decode(this.ctx, NbtDeserializer.this)
);
}
}
Expand Down Expand Up @@ -221,8 +217,7 @@ public java.util.Map.Entry<String, V> next() {
var key = this.keys.next();
return NbtDeserializer.this.frame(
() -> this.compound.get(key),
() -> java.util.Map.entry(key, this.valueEndec.decode(this.ctx, NbtDeserializer.this)),
false
() -> java.util.Map.entry(key, this.valueEndec.decode(this.ctx, NbtDeserializer.this))
);
}
}
Expand All @@ -236,25 +231,17 @@ public Struct(NbtCompound compound) {
}

@Override
public <F> @Nullable F field(String name, SerializationContext ctx, Endec<F> endec) {
public <F> @Nullable F field(String name, SerializationContext ctx, Endec<F> endec, @Nullable Supplier<F> defaultValueFactory) {
if (!this.compound.contains(name)) {
throw new IllegalStateException("Field '" + name + "' was missing from serialized data, but no default value was provided");
}

return NbtDeserializer.this.frame(
() -> this.compound.get(name),
() -> endec.decode(ctx, NbtDeserializer.this),
true
);
}
if (defaultValueFactory == null) {
throw new IllegalStateException("Field '" + name + "' was missing from serialized data, but no default value was provided");
}

@Override
public <F> @Nullable F field(String name, SerializationContext ctx, Endec<F> endec, @Nullable F defaultValue) {
if (!this.compound.contains(name)) return defaultValue;
return defaultValueFactory.get();
}
return NbtDeserializer.this.frame(
() -> this.compound.get(name),
() -> endec.decode(ctx, NbtDeserializer.this),
true
() -> endec.decode(ctx, NbtDeserializer.this)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,14 @@
import net.minecraft.nbt.*;
import net.minecraft.network.encoding.VarInts;
import net.minecraft.network.encoding.VarLongs;
import org.apache.commons.lang3.mutable.MutableObject;
import org.spongepowered.asm.mixin.Mutable;

import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.WeakHashMap;

public class NbtSerializer extends RecursiveSerializer<NbtElement> implements SelfDescribedSerializer<NbtElement> {

Expand Down Expand Up @@ -95,16 +101,25 @@ public void writeBytes(SerializationContext ctx, byte[] bytes) {
this.consume(new NbtByteArray(bytes));
}

private final Set<NbtElement> encodedOptionals = Collections.newSetFromMap(new WeakHashMap<>());

@Override
public <V> void writeOptional(SerializationContext ctx, Endec<V> endec, Optional<V> optional) {
if (this.isWritingStructField()) {
optional.ifPresent(v -> endec.encode(ctx, this, v));
} else {
MutableObject<NbtElement> frameData = new MutableObject<>();

this.frame(encoded -> {
try (var struct = this.struct()) {
struct.field("present", ctx, Endec.BOOLEAN, optional.isPresent());
optional.ifPresent(value -> struct.field("value", ctx, endec, value));
}
}

var compound = encoded.require("optional representation");

encodedOptionals.add(compound);
frameData.setValue(compound);
});

this.consume(frameData.getValue());
}

// ---
Expand Down Expand Up @@ -152,17 +167,26 @@ public void entry(String key, V value) {
NbtSerializer.this.frame(encoded -> {
this.valueEndec.encode(this.ctx, NbtSerializer.this, value);
this.result.put(key, encoded.require("map value"));
}, false);
});
}

@Override
public <F> Struct field(String name, SerializationContext ctx, Endec<F> endec, F value) {
public <F> Struct field(String name, SerializationContext ctx, Endec<F> endec, F value, boolean mayOmit) {
NbtSerializer.this.frame(encoded -> {
endec.encode(ctx, NbtSerializer.this, value);
if (encoded.wasEncoded()) {
this.result.put(name, encoded.get());

var element = encoded.require("struct field");

if (mayOmit && NbtSerializer.this.encodedOptionals.contains(element)) {
var nbtCompound = (NbtCompound) element;

if(!nbtCompound.getBoolean("present")) return;

element = nbtCompound.get("value");
}
}, true);

this.result.put(name, element);
});

return this;
}
Expand Down Expand Up @@ -199,7 +223,7 @@ public void element(V element) {
NbtSerializer.this.frame(encoded -> {
this.valueEndec.encode(this.ctx, NbtSerializer.this, element);
this.result.add(encoded.require("sequence element"));
}, false);
});
}

@Override
Expand Down

0 comments on commit 1653358

Please sign in to comment.