fix: Some items not being saved in /firm stoarge

This commit is contained in:
Linnea Gräf
2024-12-23 23:53:27 +01:00
parent 656958937f
commit 39d35afb70
4 changed files with 95 additions and 36 deletions

View File

@@ -0,0 +1,18 @@
package moe.nea.firmament.mixins;
import moe.nea.firmament.util.mc.TolerantRegistriesOps;
import net.minecraft.registry.entry.RegistryEntryOwner;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(RegistryEntryOwner.class)
public interface TolerateFirmamentTolerateRegistryOwners<T> {
@Inject(method = "ownerEquals", at = @At("HEAD"), cancellable = true)
private void equalTolerantRegistryOwners(RegistryEntryOwner<T> other, CallbackInfoReturnable<Boolean> cir) {
if (other instanceof TolerantRegistriesOps.TolerantOwner<?>) {
cir.setReturnValue(true);
}
}
}

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.features.inventory.storageoverlay package moe.nea.firmament.features.inventory.storageoverlay
import io.ktor.util.decodeBase64Bytes import io.ktor.util.decodeBase64Bytes
@@ -19,6 +17,10 @@ import net.minecraft.nbt.NbtIo
import net.minecraft.nbt.NbtList import net.minecraft.nbt.NbtList
import net.minecraft.nbt.NbtOps import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.NbtSizeTracker 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) @Serializable(with = VirtualInventory.Serializer::class)
data class VirtualInventory( data class VirtualInventory(
@@ -41,21 +43,29 @@ data class VirtualInventory(
val s = decoder.decodeString() val s = decoder.decodeString()
val n = NbtIo.readCompressed(ByteArrayInputStream(s.decodeBase64Bytes()), NbtSizeTracker.of(100_000_000)) val n = NbtIo.readCompressed(ByteArrayInputStream(s.decodeBase64Bytes()), NbtSizeTracker.of(100_000_000))
val items = n.getList(INVENTORY, NbtCompound.COMPOUND_TYPE.toInt()) val items = n.getList(INVENTORY, NbtCompound.COMPOUND_TYPE.toInt())
val ops = getOps()
return VirtualInventory(items.map { return VirtualInventory(items.map {
it as NbtCompound it as NbtCompound
if (it.isEmpty) ItemStack.EMPTY if (it.isEmpty) ItemStack.EMPTY
else runCatching { else ErrorUtil.catch("Could not deserialize item") {
ItemStack.CODEC.parse(NbtOps.INSTANCE, it).orThrow ItemStack.CODEC.parse(ops, it).orThrow
}.getOrElse { ItemStack.EMPTY } }.or { ItemStack.EMPTY }
}) })
} }
fun getOps() = TolerantRegistriesOps(NbtOps.INSTANCE, MC.currentOrDefaultRegistries)
override fun serialize(encoder: Encoder, value: VirtualInventory) { override fun serialize(encoder: Encoder, value: VirtualInventory) {
val list = NbtList() val list = NbtList()
val ops = getOps()
value.stacks.forEach { value.stacks.forEach {
if (it.isEmpty) list.add(NbtCompound()) if (it.isEmpty) list.add(NbtCompound())
else list.add(runCatching { ItemStack.CODEC.encode(it, NbtOps.INSTANCE, NbtCompound()).orThrow } else list.add(ErrorUtil.catch("Could not serialize item") {
.getOrElse { NbtCompound() }) ItemStack.CODEC.encode(it,
ops,
NbtCompound()).orThrow
}
.or { NbtCompound() })
} }
val baos = ByteArrayOutputStream() val baos = ByteArrayOutputStream()
NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos) NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos)

View 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()
}
}
}

View File

@@ -4,6 +4,8 @@ accessible class net/minecraft/client/render/RenderLayer$MultiPhaseParameters
accessible class net/minecraft/client/font/TextRenderer$Drawer accessible class net/minecraft/client/font/TextRenderer$Drawer
accessible field net/minecraft/client/gui/hud/InGameHud SCOREBOARD_ENTRY_COMPARATOR Ljava/util/Comparator; accessible field net/minecraft/client/gui/hud/InGameHud SCOREBOARD_ENTRY_COMPARATOR Ljava/util/Comparator;
accessible field net/minecraft/client/network/ClientPlayNetworkHandler combinedDynamicRegistries Lnet/minecraft/registry/DynamicRegistryManager$Immutable; accessible field net/minecraft/client/network/ClientPlayNetworkHandler combinedDynamicRegistries Lnet/minecraft/registry/DynamicRegistryManager$Immutable;
accessible method net/minecraft/registry/RegistryOps <init> (Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/registry/RegistryOps$RegistryInfoGetter;)V
accessible class net/minecraft/registry/RegistryOps$CachedRegistryInfoGetter
accessible field net/minecraft/client/render/item/HeldItemRenderer itemRenderer Lnet/minecraft/client/render/item/ItemRenderer; accessible field net/minecraft/client/render/item/HeldItemRenderer itemRenderer Lnet/minecraft/client/render/item/ItemRenderer;
accessible field net/minecraft/client/render/item/ItemModels missingModelSupplier Ljava/util/function/Supplier; accessible field net/minecraft/client/render/item/ItemModels missingModelSupplier Ljava/util/function/Supplier;