LibrarianLib

LibrarianLib

18M Downloads

SaveInPlace fails to not load anything

Bluexin opened this issue · 1 comments

commented

Given :

  • you have a field of type marked as @SaveInPlace ("The Field")
  • The Field is populated
  • you have some nbt where The Field is not present

When :

  • you try to load the nbt

Then :

  • the nbt reading handler crashes trying to instantiate the field (see stacktrace below)

Expected :

  • the nbt reading handler ignores the missing field from nbt and keeps the existing value (cf @SaveInPlace)
Stacktrace (click to expand)
com.teamwizardry.librarianlib.features.saving.serializers.SerializerException: [NBT] Error deserializing  PlayerStats
	at com.teamwizardry.librarianlib.features.saving.serializers.Serializer.read(Serializer.kt:53)
	at com.teamwizardry.librarianlib.features.saving.AbstractSaveHandler.readAutoNBT(AbstractSaveHandler.kt:35)
	at be.bluexin.rpg.stats.PlayerStats$Storage.readNBT(PlayerStats.kt:123)
	at be.bluexin.rpg.stats.PlayerStats$Storage.readNBT(PlayerStats.kt:115)
	at be.bluexin.saomclib.capabilities.CapabilitiesHandler$CapabilitySerializableImpl.deserializeNBT(CapabilitiesHandler.kt:170)
	at net.minecraftforge.common.capabilities.CapabilityDispatcher.deserializeNBT(CapabilityDispatcher.java:135)
	at net.minecraft.entity.Entity.readFromNBT(Entity.java:2075)
	at net.minecraft.server.management.PlayerList.readPlayerDataFromFile(PlayerList.java:338)
	at net.minecraft.server.management.PlayerList.initializeConnectionToPlayer(PlayerList.java:127)
	at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.completeServerSideConnection(NetworkDispatcher.java:258)
	at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher.access$100(NetworkDispatcher.java:72)
	at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:208)
	at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:307)
	at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197)
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:865)
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:743)
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:192)
	at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:592)
	at java.lang.Thread.run(Thread.java:748)
Caused by: com.teamwizardry.librarianlib.features.saving.serializers.SerializerException: Error reading field classData from NBT
	at com.teamwizardry.librarianlib.features.saving.serializers.builtin.special.SerializeObjectFactory$SerializeObject.readFields(Objects.kt:100)
	at com.teamwizardry.librarianlib.features.saving.serializers.builtin.special.SerializeObjectFactory$SerializeObject.readNBT(Objects.kt:53)
	at com.teamwizardry.librarianlib.features.saving.serializers.Serializer.read(Serializer.kt:51)
	... 18 more
Caused by: com.teamwizardry.librarianlib.features.saving.serializers.SerializerException: Cannot create instance of class marked with @SaveInPlace
	at com.teamwizardry.librarianlib.features.saving.serializers.builtin.special.SerializerAnalysis$14.invoke(Objects.kt:341)
	at com.teamwizardry.librarianlib.features.saving.serializers.builtin.special.SerializerAnalysis$14.invoke(Objects.kt:276)
	at com.teamwizardry.librarianlib.features.saving.serializers.builtin.special.SerializeObjectFactory$SerializeObject.getDefault(Objects.kt:368)
	at com.teamwizardry.librarianlib.features.saving.serializers.SerializerRegistry.getDefault(SerializerRegistry.kt:34)
	at com.teamwizardry.librarianlib.features.saving.FieldCache$setter$1.invoke(SavingFieldCache.kt:491)
	at com.teamwizardry.librarianlib.features.saving.FieldCache$setter$1.invoke(SavingFieldCache.kt:487)
	at com.teamwizardry.librarianlib.features.saving.serializers.builtin.special.SerializeObjectFactory$SerializeObject.readFields(Objects.kt:97)
	... 20 more
commented

This is somewhat expected and—according to the current structure—correct behavior. As far as the serializer can tell, missing == null. The problem comes from the fact that when it tries to set a null value to a nonnull field a default value will be created and used instead of null. @SaveInPlace classes have no default value, along with a slew of other types.

The right way to solve this would be to explicitly store null values, but that might break any existing nbt that stores null values through missing keys.