From c1fe13e609a3df47fdaf465a34bbabff9c01d2e8 Mon Sep 17 00:00:00 2001 From: glisco Date: Sun, 28 Jul 2024 22:41:58 +0200 Subject: [PATCH] [endec] add CodecUtils.toEndecWithRegistries for making a combined codec/packetcodec endec for registrybuf packetcodecs --- gradle.properties | 2 +- .../owo/serialization/CodecUtils.java | 26 +++++++++++ .../endec/DefaultedListEndec.java | 43 +++++++++++++++++++ .../serialization/endec/MinecraftEndecs.java | 2 +- .../io/wispforest/uwu/FabledBananasClass.java | 4 +- src/testmod/java/io/wispforest/uwu/Uwu.java | 15 ++++--- 6 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 src/main/java/io/wispforest/owo/serialization/endec/DefaultedListEndec.java diff --git a/gradle.properties b/gradle.properties index ae0a9280..1049e403 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ minecraft_version=1.21 yarn_mappings=1.21+build.2 loader_version=0.15.11 # Mod Properties -mod_version=0.12.10 +mod_version=0.12.11 maven_group=io.wispforest archives_base_name=owo-lib # Dependencies diff --git a/src/main/java/io/wispforest/owo/serialization/CodecUtils.java b/src/main/java/io/wispforest/owo/serialization/CodecUtils.java index 7c9e56ad..db09f898 100644 --- a/src/main/java/io/wispforest/owo/serialization/CodecUtils.java +++ b/src/main/java/io/wispforest/owo/serialization/CodecUtils.java @@ -99,6 +99,32 @@ public static Endec toEndec(Codec codec, PacketCodec packe ); } + public static Endec toEndecWithRegistries(Codec codec, PacketCodec packetCodec) { + return Endec.of( + (ctx, serializer, value) -> { + if (serializer instanceof ByteBufSerializer) { + var buffer = new RegistryByteBuf(PacketByteBufs.create(), ctx.requireAttributeValue(RegistriesAttribute.REGISTRIES).registryManager()); + packetCodec.encode(buffer, value); + + MinecraftEndecs.PACKET_BYTE_BUF.encode(ctx, serializer, buffer); + return; + } + + var ops = RegistryOps.of(EdmOps.withContext(ctx), ctx.requireAttributeValue(RegistriesAttribute.REGISTRIES).infoGetter()); + EdmEndec.INSTANCE.encode(ctx, serializer, codec.encodeStart(ops, value).getOrThrow(IllegalStateException::new)); + }, + (ctx, deserializer) -> { + if (deserializer instanceof ByteBufDeserializer) { + var buffer = MinecraftEndecs.PACKET_BYTE_BUF.decode(ctx, deserializer); + return packetCodec.decode(new RegistryByteBuf(buffer, ctx.requireAttributeValue(RegistriesAttribute.REGISTRIES).registryManager())); + } + + var ops = RegistryOps.of(EdmOps.withContext(ctx), ctx.requireAttributeValue(RegistriesAttribute.REGISTRIES).infoGetter()); + return codec.parse(ops, EdmEndec.INSTANCE.decode(ctx, deserializer)).getOrThrow(IllegalStateException::new); + } + ); + } + /** * Create an endec which serializes an instance of {@link Either}, using {@code first} * for the left and {@code second} for the right variant diff --git a/src/main/java/io/wispforest/owo/serialization/endec/DefaultedListEndec.java b/src/main/java/io/wispforest/owo/serialization/endec/DefaultedListEndec.java new file mode 100644 index 00000000..00325abb --- /dev/null +++ b/src/main/java/io/wispforest/owo/serialization/endec/DefaultedListEndec.java @@ -0,0 +1,43 @@ +package io.wispforest.owo.serialization.endec; + +import io.wispforest.endec.Endec; +import io.wispforest.endec.impl.StructEndecBuilder; +import net.minecraft.util.collection.DefaultedList; + +import java.util.ArrayList; +import java.util.Objects; +import java.util.function.Predicate; + +public final class DefaultedListEndec { + + private DefaultedListEndec() {} + + public static Endec> forSize(Endec elementEndec, T defaultValue, int size) { + return forSize(elementEndec, defaultValue, element -> Objects.equals(defaultValue, element), size); + } + + public static Endec> forSize(Endec elementEndec, T defaultValue, Predicate skipWhen, int size) { + var entryEndec = StructEndecBuilder.of( + elementEndec.fieldOf("element", s -> s.element), + Endec.VAR_INT.fieldOf("idx", s -> s.idx), + Entry::new + ); + + return entryEndec.listOf().xmap( + entries -> { + var list = DefaultedList.ofSize(size, defaultValue); + entries.forEach(entry -> list.set(entry.idx, entry.element)); + return list; + }, elements -> { + var entries = new ArrayList>(); + for (int i = 0; i < elements.size(); i++) { + if (skipWhen.test(elements.get(i))) continue; + entries.add(new Entry<>(elements.get(i), i)); + } + return entries; + } + ); + } + + private record Entry(T element, int idx) {} +} \ No newline at end of file diff --git a/src/main/java/io/wispforest/owo/serialization/endec/MinecraftEndecs.java b/src/main/java/io/wispforest/owo/serialization/endec/MinecraftEndecs.java index 5649f50d..96df755f 100644 --- a/src/main/java/io/wispforest/owo/serialization/endec/MinecraftEndecs.java +++ b/src/main/java/io/wispforest/owo/serialization/endec/MinecraftEndecs.java @@ -47,7 +47,7 @@ private MinecraftEndecs() {} }); public static final Endec IDENTIFIER = Endec.STRING.xmap(Identifier::of, Identifier::toString); - public static final Endec ITEM_STACK = CodecUtils.toEndec(ItemStack.OPTIONAL_CODEC); + public static final Endec ITEM_STACK = CodecUtils.toEndecWithRegistries(ItemStack.OPTIONAL_CODEC, ItemStack.OPTIONAL_PACKET_CODEC); public static final Endec TEXT = CodecUtils.toEndec(TextCodecs.CODEC, TextCodecs.PACKET_CODEC); public static final Endec VEC3I = vectorEndec("Vec3i", Endec.INT, Vec3i::new, Vec3i::getX, Vec3i::getY, Vec3i::getZ); diff --git a/src/testmod/java/io/wispforest/uwu/FabledBananasClass.java b/src/testmod/java/io/wispforest/uwu/FabledBananasClass.java index 05c392c5..40b6b520 100644 --- a/src/testmod/java/io/wispforest/uwu/FabledBananasClass.java +++ b/src/testmod/java/io/wispforest/uwu/FabledBananasClass.java @@ -5,8 +5,8 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.wispforest.endec.Endec; -import io.wispforest.endec.format.json.GsonDeserializer; -import io.wispforest.endec.format.json.GsonSerializer; +import io.wispforest.endec.format.gson.GsonDeserializer; +import io.wispforest.endec.format.gson.GsonSerializer; import io.wispforest.endec.impl.StructEndecBuilder; import io.wispforest.owo.serialization.endec.MinecraftEndecs; import net.minecraft.item.Item; diff --git a/src/testmod/java/io/wispforest/uwu/Uwu.java b/src/testmod/java/io/wispforest/uwu/Uwu.java index 1babc181..c5d28765 100644 --- a/src/testmod/java/io/wispforest/uwu/Uwu.java +++ b/src/testmod/java/io/wispforest/uwu/Uwu.java @@ -9,9 +9,9 @@ import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.logging.LogUtils; import io.netty.buffer.Unpooled; -import io.wispforest.endec.format.json.GsonDeserializer; -import io.wispforest.endec.format.json.GsonEndec; -import io.wispforest.endec.format.json.GsonSerializer; +import io.wispforest.endec.format.gson.GsonDeserializer; +import io.wispforest.endec.format.gson.GsonEndec; +import io.wispforest.endec.format.gson.GsonSerializer; import io.wispforest.endec.impl.StructEndecBuilder; import io.wispforest.owo.Owo; import io.wispforest.owo.config.ConfigSynchronizer; @@ -30,6 +30,7 @@ import io.wispforest.endec.Endec; import io.wispforest.endec.format.bytebuf.ByteBufSerializer; import io.wispforest.owo.serialization.CodecUtils; +import io.wispforest.owo.serialization.RegistriesAttribute; import io.wispforest.owo.serialization.endec.MinecraftEndecs; import io.wispforest.owo.serialization.format.nbt.NbtDeserializer; import io.wispforest.owo.serialization.format.nbt.NbtEndec; @@ -345,7 +346,7 @@ public void onInitialize() { JsonElement stackJsonData; try { - stackJsonData = MinecraftEndecs.ITEM_STACK.encodeFully(GsonSerializer::of, handStack); + stackJsonData = MinecraftEndecs.ITEM_STACK.encodeFully(SerializationContext.attributes(RegistriesAttribute.of(context.getSource().getWorld().getRegistryManager())), GsonSerializer::of, handStack); } catch (Exception exception){ LOGGER.info(exception.getMessage()); LOGGER.info((Arrays.toString(exception.getStackTrace()))); @@ -358,7 +359,7 @@ public void onInitialize() { LOGGER.info("---"); try { - handStack = MinecraftEndecs.ITEM_STACK.decodeFully(GsonDeserializer::of, stackJsonData); + handStack = MinecraftEndecs.ITEM_STACK.decodeFully(SerializationContext.attributes(RegistriesAttribute.of(context.getSource().getWorld().getRegistryManager())), GsonDeserializer::of, stackJsonData); } catch (Exception exception){ LOGGER.info(exception.getMessage()); LOGGER.info((Arrays.toString(exception.getStackTrace()))); @@ -467,9 +468,9 @@ public void onInitialize() { try { iterations("Endec", (buf) -> { ItemStack stack = source.getPlayer().getStackInHand(Hand.MAIN_HAND); - buf.write(MinecraftEndecs.ITEM_STACK, stack); + buf.write(SerializationContext.attributes(RegistriesAttribute.of(context.getSource().getWorld().getRegistryManager())), MinecraftEndecs.ITEM_STACK, stack); - var stackFromByte = buf.read(MinecraftEndecs.ITEM_STACK); + var stackFromByte = buf.read(SerializationContext.attributes(RegistriesAttribute.of(context.getSource().getWorld().getRegistryManager())), MinecraftEndecs.ITEM_STACK); }); } catch (Exception exception){ LOGGER.info(exception.getMessage());