AlmuraDev / SGCraft

Stargates mod for Minecraft
https://www.almuramc.com/sgcraft/SGCraft.html
MIT License
31 stars 31 forks source link

Fix TileEntity dialing unloading remote gate. #165

Closed Zidane closed 4 years ago

Zidane commented 4 years ago

So OpenComputers/etc trigger an interesting flaw in how SGCraft performs remote dialing. SGCraft relies on loading the chunk of the remote gate to grab that gate (The TE) so it can tell the remote to start dialing (as is canon). Vanilla has a provision that any Tile Entities that are added as a result of another Tile Entities' tick are "queued" to be added at the end of that same tick. SGBaseTE of the remote gate keeps a Chunk ticket open with MinecraftForge which simply tells Forge to disallow Vanilla from unloading the chunk.

Phew...now why this is important is because of what happens when the pending Tile Entities are proceessed at the end of that tick. Since the source gate triggered the Chunk to load, that Chunk has it's Tile Entities. World does not though. When World goes to add those pending Tile Entities, it is effectively adding the same Tile Entity reference back to the Chunk (that it already has). Chunk detects this and calls invalidate() on the Tile Entity. As stated above, SGBaseTE keeps a Chunk ticket and hands back that ticket to Forge during invalidate...

As you can see, this is a fun Vanilla "gotcha". Vanilla MUST queue the Tile Entities added during Tile Entity ticks else it'll get a Concurrent Modification Exception.

So what do we do?

Barring re-writing the structure of the mod to store chunk tickets outside the remote gate's Tile Entity OR change the dialing sequence to not require that Tile Entity right away, we'll apply more of Dockter's famous duct tape.

I have added a "pending" flag to the connect sequence of events. If this is as a result of anything BUT OpenComputers then it'll be false. If it is, it'll be true. If this flag is set to true, we disregard the next invalidate call (which will be the faulty re-set of the reference from above).

That said, this isn't a 100% fix. This can still happen but frankly it now acts as an old car. Typically you run the computer command a second time and it'll work. Again, this needs a re-write for a permanent fix...

Signed-off-by: Chris Sanders zidane@spongepowered.org