aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt')
-rw-r--r--src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt b/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt
new file mode 100644
index 0000000..e07df8a
--- /dev/null
+++ b/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt
@@ -0,0 +1,65 @@
+
+
+package moe.nea.firmament.features.inventory.storageoverlay
+
+import io.ktor.util.decodeBase64Bytes
+import io.ktor.util.encodeBase64
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import net.minecraft.item.ItemStack
+import net.minecraft.nbt.NbtCompound
+import net.minecraft.nbt.NbtIo
+import net.minecraft.nbt.NbtList
+import net.minecraft.nbt.NbtOps
+import net.minecraft.nbt.NbtSizeTracker
+
+@Serializable(with = VirtualInventory.Serializer::class)
+data class VirtualInventory(
+ val stacks: List<ItemStack>
+) {
+ val rows = stacks.size / 9
+
+ init {
+ assert(stacks.size % 9 == 0)
+ assert(stacks.size / 9 in 1..5)
+ }
+
+
+ object Serializer : KSerializer<VirtualInventory> {
+ const val INVENTORY = "INVENTORY"
+ override val descriptor: SerialDescriptor
+ get() = PrimitiveSerialDescriptor("VirtualInventory", PrimitiveKind.STRING)
+
+ override fun deserialize(decoder: Decoder): VirtualInventory {
+ val s = decoder.decodeString()
+ val n = NbtIo.readCompressed(ByteArrayInputStream(s.decodeBase64Bytes()), NbtSizeTracker.of(100_000_000))
+ val items = n.getList(INVENTORY, NbtCompound.COMPOUND_TYPE.toInt())
+ return VirtualInventory(items.map {
+ it as NbtCompound
+ if (it.isEmpty) ItemStack.EMPTY
+ else runCatching {
+ ItemStack.CODEC.parse(NbtOps.INSTANCE, it).orThrow
+ }.getOrElse { ItemStack.EMPTY }
+ })
+ }
+
+ override fun serialize(encoder: Encoder, value: VirtualInventory) {
+ val list = NbtList()
+ value.stacks.forEach {
+ if (it.isEmpty) list.add(NbtCompound())
+ else list.add(runCatching { ItemStack.CODEC.encode(it, NbtOps.INSTANCE, NbtCompound()).orThrow }
+ .getOrElse { NbtCompound() })
+ }
+ val baos = ByteArrayOutputStream()
+ NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos)
+ encoder.encodeString(baos.toByteArray().encodeBase64())
+ }
+ }
+}