Closed doarlock closed 2 years ago
Can confirm that this is an issue, even if this gets fixed you will still have the same issue when you break the block as well. Magma and Mohist suffer from this issue as well. Sponge Forge works but they don't have much plugins support at the moment.
Should note that it happens with any version of forge and Java so don't waste your time trying versions. It has something to do with removing or inserting a block into the framed block. State change issue. Good luck!
This should report to FramedBlocks side with these information:
The
level
in BlockEntity can be null. For the onLoad implementation, forge actually provide aonLoad
callback inIForgeTileEntity
.
This should report to FramedBlocks side with these information:
The
level
in BlockEntity can be null. For the onLoad implementation, forge actually provide aonLoad
callback inIForgeTileEntity
.
I have been informed by the author of this issue about your response, so I might as well add my side to it:
I am well aware that the BlockEntity#level
can be null. However, on plain Forge I can expect the level to be set one tick after a blockentity has been deserialized from NBT data, which is the only reference point my implementation can rely on to be able to access the level in a way that doesn't cause deadlocks. This assumption is broken by all Bukkit-Forge hybrid implementations and only by those, removing any possible reference point for me to do a "first tick with level access" operation.
The IForgeTileEntity#onLoad()
hook you suggested as the fix is broken and unusable for this prior to 1.17 as it is called from within the chunk loading future mess, which leads to any level access in that method causing a chunk loading deadlock. In 1.17 this hook has been reimplemented outside of the future hell and can since then be used again for this kind of thing (which I am doing in all versions of FramedBlocks since the first 1.17 version, which is why this has never come up again with anything newer than 1.16).
This should report to FramedBlocks side with these information:
The
level
in BlockEntity can be null. For the onLoad implementation, forge actually provide aonLoad
callback inIForgeTileEntity
.I am well aware that the
BlockEntity#level
can be null. However, on plain Forge I can expect the level to be set one tick after a blockentity has been deserialized from NBT data, which is the only reference point my implementation can rely on to be able to access the level in a way that doesn't cause deadlocks.
Arclight(or other implementations maybe?) did not break the "level will be set after 1 tick" rule. Bukkit create a BE copy instance(serialize to nbt and deserialize it) in block breaking and other possible events, and these instances will not be placed into game worlds, therefore can be safely ignored. Forge itself actually uses the same trick in net.minecraftforge.common.util.BlockSnapshot#getTileEntity
.
My point is that you can simply ignore these instances with null level, if you are still maintaining 1.16.
Arclight(or other implementations maybe?) did not break the "level will be set after 1 tick" rule. Bukkit create a BE copy instance(serialize to nbt and deserialize it) in block breaking and other possible events, and these instances will not be placed into game worlds, therefore can be safely ignored. Forge itself actually uses the same trick in
net.minecraftforge.common.util.BlockSnapshot#getTileEntity
.
That's good to know. The major difference is that Forge keeps the BE as NBT data and only deserializes it again on demand.
My point is that you can simply ignore these instances with null level, if you are still maintaining 1.16.
I dropped support for 1.16 but I'll think about releasing a small update with this fix anyway since it has a very significant impact.
Thank you for the insights, I'm happy to finally get detailed info on what is actually happening behind the scenes from the Bukkit side.
I have confirmed that ...
Arclight version
arclight-1.16.5-1.0.24-SNAPSHOT-ef6b96f2
OS & Java versions
11.0.13 by Oracle Corporation
Plugins and Mods
Description
The server just crashed when put any block from the FramedBlocks mod by [XFactHD] https://www.curseforge.com/minecraft/mc-mods/framedblocks.
The console prints this crash:
[20Sep2022 18:06:21.045] [Server thread/ERROR] [net.minecraft.server.MinecraftServer/]: Encountered an unexpected exception java.lang.NullPointerException: null at xfacthd.framedblocks.common.tileentity.FramedTileEntity.checkSolidStateOnLoad(FramedTileEntity.java:539) ~[framedblocks:2.16.1] at java.util.ArrayList.forEach(ArrayList.java:1541) ~[?:?] at xfacthd.framedblocks.common.util.EventHandler.onServerTick(EventHandler.java:84) ~[framedblocks:2.16.1] at net.minecraftforge.eventbus.ASMEventHandler_383_EventHandler_onServerTick_ServerTickEvent.invoke(.dynamic) ~[?:?] at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85) ~[eventbus-4.0.0.jar:?] at net.minecraftforge.eventbus.EventBus.post(EventBus.java:302) ~[eventbus-4.0.0.jar:?] at net.minecraftforge.eventbus.EventBus.post(EventBus.java:283) ~[eventbus-4.0.0.jar:?] at net.minecraftforge.fml.hooks.BasicEventHooks.onPreServerTick(BasicEventHooks.java:101) ~[forge:?] at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServerMixin.java:785) ~[?:?] at net.minecraft.server.MinecraftServer.func_240802v(MinecraftServerMixin.java:1917) ~[?:?] at net.minecraft.server.MinecraftServer.func_240783a(MinecraftServerMixin.java:232) ~[?:?] at java.lang.Thread.run(Thread.java:829) [?:?] [20Sep2022 18:06:21.065] [Server thread/FATAL] [net.minecraftforge.common.ForgeMod/]: Preparing crash report with UUID ad0da6a7-be67-4dd4-884f-e5a35b9fd01b
I test without Arclight and the mod works right.
Step to reproduce
1 - Just install server 2 - Enters the server 3 - Pick up a block from Framedblocks mod using JEI or creative 4 - Put on anywhere 5 - Crashed
Logs
2022-09-20-2.log crash-2022-09-20_18.06.21-server.txt
Server pack link (Optional)
No response