diff --git a/src/main/java/one/oth3r/sit/utl/Utl.java b/src/main/java/one/oth3r/sit/utl/Utl.java index 6176b78..b015cb7 100644 --- a/src/main/java/one/oth3r/sit/utl/Utl.java +++ b/src/main/java/one/oth3r/sit/utl/Utl.java @@ -35,6 +35,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; @@ -351,10 +353,19 @@ public class Utl { /** * the LenientTypeAdapter, doesn't throw anything when reading a weird JSON entry, good for human entered JSONs */ + @SuppressWarnings("unchecked") public static class LenientTypeAdapterFactory implements TypeAdapterFactory { public TypeAdapter create(Gson gson, TypeToken type) { final TypeAdapter delegate = gson.getDelegateAdapter(this, type); + // Check if the type is a List, then run the custom list type adapter + if (List.class.isAssignableFrom(type.getRawType())) { + Type elementType = ((ParameterizedType) type.getType()).getActualTypeArguments()[0]; + TypeAdapter elementAdapter = gson.getAdapter(TypeToken.get(elementType)); + // the custom adapter + return (TypeAdapter) new RemoveNullListTypeAdapter<>(elementAdapter); + } + return new TypeAdapter<>() { // normal writer public void write(JsonWriter out, T value) throws IOException { @@ -375,6 +386,45 @@ public class Utl { } } + /** + * type adapter that doesnt allow null / bad entries + */ + private static class RemoveNullListTypeAdapter extends TypeAdapter> { + private final TypeAdapter elementAdapter; + + RemoveNullListTypeAdapter(TypeAdapter elementAdapter) { + this.elementAdapter = elementAdapter; + } + + @Override + public void write(JsonWriter out, List value) throws IOException { + out.beginArray(); + for (E element : value) { + elementAdapter.write(out, element); + } + out.endArray(); + } + + @Override + public List read(JsonReader in) throws IOException { + List list = new ArrayList<>(); + in.beginArray(); + while (in.hasNext()) { + try { + E element = elementAdapter.read(in); + // skip null entry + if (element == null) continue; + list.add(element); + } catch (Exception e) { + // skip invalid entry + in.skipValue(); + } + } + in.endArray(); + return list; + } + } + public static BlockPos getBlockPosPlayerIsLookingAt(ServerWorld world, PlayerEntity player, double range) { // pos, adjusted to player eye level Vec3d rayStart = player.getPos().add(0, player.getEyeHeight(player.getPose()), 0);