RuochenFu21 / CreateEnderTransmission

0 stars 6 forks source link

Transmitters lose data on world load/save on server #9

Open Swedz opened 1 year ago

Swedz commented 1 year ago

When my server loads I get the error

[23Aug2023 05:39:33.150] [Server thread/ERROR] [net.minecraft.world.level.storage.DimensionDataStorage/]: Error loading saved data: ender_transmission_matter_transmission
java.lang.NullPointerException: Cannot invoke "com.forsteri.createendertransmission.blocks.MatterWorldSavedData.m_77762_()" because "com.forsteri.createendertransmission.CreateEnderTransmission.savedData" is null
    at com.forsteri.createendertransmission.blocks.MatterTransmitterNetwork.lambda$static$1(MatterTransmitterNetwork.java:23) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at com.simibubi.create.foundation.fluid.SmartFluidTank.setFluid(SmartFluidTank.java:26) ~[create-1.20.1-0.5.1.d.jar%23224!/:0.5.1.d]
    at com.forsteri.createendertransmission.blocks.fluidTrasmitter.SerializableSmartFluidTank.deserializeNBT(SerializableSmartFluidTank.java:23) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at com.forsteri.createendertransmission.blocks.fluidTrasmitter.SerializableSmartFluidTank.deserializeNBT(SerializableSmartFluidTank.java:10) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at com.forsteri.createendertransmission.blocks.MatterWorldSavedData.lambda$load$0(MatterWorldSavedData.java:49) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at java.util.HashMap$KeySet.forEach(HashMap.java:1008) ~[?:?]
    at com.forsteri.createendertransmission.blocks.MatterWorldSavedData.load(MatterWorldSavedData.java:41) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at net.minecraft.world.level.storage.DimensionDataStorage.m_164868_(DimensionDataStorage.java:70) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at net.minecraft.world.level.storage.DimensionDataStorage.m_164858_(DimensionDataStorage.java:54) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at net.minecraft.world.level.storage.DimensionDataStorage.m_164861_(DimensionDataStorage.java:39) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at com.forsteri.createendertransmission.blocks.MatterWorldSavedData.load(MatterWorldSavedData.java:61) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at com.forsteri.createendertransmission.CreateEnderTransmission$CommonEvents.onLoadWorld(CreateEnderTransmission.java:67) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at com.forsteri.createendertransmission.__CommonEvents_onLoadWorld_Load.invoke(.dynamic) ~[createendertransmission-2.0.4-1.20.1.jar%23228!/:2.0.4-1.20.1]
    at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:73) ~[eventbus-6.0.5.jar%2352!/:?]
    at net.minecraftforge.eventbus.EventBus.post(EventBus.java:315) ~[eventbus-6.0.5.jar%2352!/:?]
    at net.minecraftforge.eventbus.EventBus.post(EventBus.java:296) ~[eventbus-6.0.5.jar%2352!/:?]
    at net.minecraft.server.MinecraftServer.m_129815_(MinecraftServer.java:343) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at net.minecraft.server.MinecraftServer.m_130006_(MinecraftServer.java:308) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at net.minecraft.server.dedicated.DedicatedServer.m_7038_(DedicatedServer.java:164) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at net.minecraft.server.MinecraftServer.m_130011_(MinecraftServer.java:634) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at net.minecraft.server.MinecraftServer.m_206580_(MinecraftServer.java:251) ~[server-1.20.1-20230612.114412-srg.jar%23299!/:?]
    at java.lang.Thread.run(Thread.java:833) ~[?:?]

This does not prevent the world from loading and server continuing to run, but the transmitters lose their stored data. In this case it was my fluid transmitter.

I'm running Forge 1.20.1 version 47.1.44 with Create Ender Transmission version 2.0.4.

RuochenFu21 commented 1 year ago

oh god wtf, same issue as #7

RuochenFu21 commented 1 year ago

This part I copied create so I don't know where I did wrong

Swedz commented 1 year ago

Strange, because in their case it crashes, in my case, likely because its a server, it just errors and continues to load and I can log in and work with the blocks just fine.

Tidy-Bear commented 3 weeks ago

This part I copied create so I don't know where I did wrong

先解释 #7 saveData 是个服务器字段,确实只会在服务器线程上实例化并赋值,那加入多人游戏的客户端没有服务器线程,代码中却依旧引用了这个字段,肯定报 NPE

再解释 #9 典型的循环依赖问题 维度加载事件触发,判断在服务器线程上,实例化 saveData,遍历 MatterTransmitterNetwork.values(),使用内置在枚举中的 INBTSerializable 反序列化文件数据 流体的你使用了 create 的 SmartFluidTank.setFluid 加载文件中的流体数据,而 setFluid 会触发构造函数中传入的 updateCallback,你传入的 callback 写着 saveData.setDirty() 换言之,实例化 saveData,过程中却调用了 saveData.setDirty(),NPE

两个问题,最简单的解决办法,加个 null 判断就行了,因为上面两种情况本质上都不需要真正调用 setDirty()

if (saveData != null) {
    saveData.setDirty();
}

可以抽象成工具方法,代替直接引用 saveData,如 CreateEnderTransmission.markDataDirty()

话都说到这了,就再问下 维度加载事件既然实例化了 saveDate,为什么玩家登录事件还要再实例化一遍,这点我倒没想通