fix: Some items not being saved in /firm stoarge
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
package moe.nea.firmament.features.inventory.storageoverlay
|
||||
|
||||
import io.ktor.util.decodeBase64Bytes
|
||||
@@ -19,47 +17,59 @@ import net.minecraft.nbt.NbtIo
|
||||
import net.minecraft.nbt.NbtList
|
||||
import net.minecraft.nbt.NbtOps
|
||||
import net.minecraft.nbt.NbtSizeTracker
|
||||
import net.minecraft.registry.RegistryOps
|
||||
import moe.nea.firmament.util.ErrorUtil
|
||||
import moe.nea.firmament.util.MC
|
||||
import moe.nea.firmament.util.mc.TolerantRegistriesOps
|
||||
|
||||
@Serializable(with = VirtualInventory.Serializer::class)
|
||||
data class VirtualInventory(
|
||||
val stacks: List<ItemStack>
|
||||
val stacks: List<ItemStack>
|
||||
) {
|
||||
val rows = stacks.size / 9
|
||||
val rows = stacks.size / 9
|
||||
|
||||
init {
|
||||
assert(stacks.size % 9 == 0)
|
||||
assert(stacks.size / 9 in 1..5)
|
||||
}
|
||||
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)
|
||||
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 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())
|
||||
val ops = getOps()
|
||||
return VirtualInventory(items.map {
|
||||
it as NbtCompound
|
||||
if (it.isEmpty) ItemStack.EMPTY
|
||||
else ErrorUtil.catch("Could not deserialize item") {
|
||||
ItemStack.CODEC.parse(ops, it).orThrow
|
||||
}.or { 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())
|
||||
}
|
||||
}
|
||||
fun getOps() = TolerantRegistriesOps(NbtOps.INSTANCE, MC.currentOrDefaultRegistries)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: VirtualInventory) {
|
||||
val list = NbtList()
|
||||
val ops = getOps()
|
||||
value.stacks.forEach {
|
||||
if (it.isEmpty) list.add(NbtCompound())
|
||||
else list.add(ErrorUtil.catch("Could not serialize item") {
|
||||
ItemStack.CODEC.encode(it,
|
||||
ops,
|
||||
NbtCompound()).orThrow
|
||||
}
|
||||
.or { NbtCompound() })
|
||||
}
|
||||
val baos = ByteArrayOutputStream()
|
||||
NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos)
|
||||
encoder.encodeString(baos.toByteArray().encodeBase64())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
src/main/kotlin/util/mc/TolerantRegistriesOps.kt
Normal file
29
src/main/kotlin/util/mc/TolerantRegistriesOps.kt
Normal file
@@ -0,0 +1,29 @@
|
||||
package moe.nea.firmament.util.mc
|
||||
|
||||
import com.mojang.serialization.DynamicOps
|
||||
import java.util.Optional
|
||||
import net.minecraft.registry.Registry
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryOps
|
||||
import net.minecraft.registry.RegistryWrapper
|
||||
import net.minecraft.registry.entry.RegistryEntryOwner
|
||||
|
||||
class TolerantRegistriesOps<T>(
|
||||
delegate: DynamicOps<T>,
|
||||
registryInfoGetter: RegistryInfoGetter
|
||||
) : RegistryOps<T>(delegate, registryInfoGetter) {
|
||||
constructor(delegate: DynamicOps<T>, registry: RegistryWrapper.WrapperLookup) :
|
||||
this(delegate, CachedRegistryInfoGetter(registry))
|
||||
|
||||
class TolerantOwner<E> : RegistryEntryOwner<E> {
|
||||
override fun ownerEquals(other: RegistryEntryOwner<E>?): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
override fun <E : Any?> getOwner(registryRef: RegistryKey<out Registry<out E>>?): Optional<RegistryEntryOwner<E>> {
|
||||
return super.getOwner(registryRef).map {
|
||||
TolerantOwner()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user