TerraFirmaCraft

TerraFirmaCraft

2M Downloads

(ATMG) SMP Exception with recipe manager missing for a Mac user

Gaelmare opened this issue ยท 2 comments

commented

All attempts to get this user to a working install have failed. Several of their attempts include a stack trace with TFC complaining about a missing recipe manager.


[02:12:37] [Netty Client IO #7/ERROR]: Exception caught in connection handler!
--
945 | java.lang.IllegalStateException: No recipe manager was present - tried server, client, and captured value. This will cause problems!
946 | at TRANSFORMER/[email protected]/net.dries007.tfc.util.Helpers.getUnsafeRecipeManager(Helpers.java:429)
947 | at TRANSFORMER/[email protected]/net.dries007.tfc.util.AlloyView.getResult(AlloyView.java:23)
948 | at TRANSFORMER/[email protected]/net.dries007.tfc.util.AlloyView.getHeatCapacity(AlloyView.java:59)
949 | at TRANSFORMER/[email protected]/net.dries007.tfc.common.items.VesselItem$VesselCapability.updateHeatCapacity(VesselItem.java:545)
950 | at TRANSFORMER/[email protected]/net.dries007.tfc.common.items.VesselItem$VesselCapability.load(VesselItem.java:517)
951 | at TRANSFORMER/[email protected]/net.dries007.tfc.common.items.VesselItem$VesselCapability.<init>(VesselItem.java:241)
952 | at TRANSFORMER/[email protected]/net.dries007.tfc.common.items.VesselItem.initCapabilities(VesselItem.java:200)

Here's one of the logs:
https://mclo.gs/ncZsqGg

They can run ATMG in SSP just fine.

Not sure if the TFC exception has anything to do with the later packet issue exception.

I've requested a enableNetworkDebugging log to see if that helps.

commented

This will be absolute hell to verify it's solved, but I think I see what is happening. The first thing to note is the packet order:

  • In ServerLoginPacketListenerImpl#handleAcceptedLogin()
    • Send ClientboundGameProfilePacket - which logs Connected to a modded server when received on client
    • In PlayerList#placeNewPlayer():
      • Sends ClientboundLoginPacket - this packet ultimately sets Minecraft.level when received on client.
      • Sends ClientboundContainerSetContentPacket (one of a few possible locations)

On client, and based on this log, we see:

  • "Connected to a modded server" (CliendboundGameProfilePacket) handled on main thread.
  • "No recipe manager was present" (from ClientboundContainerSetContentPacket`) received on network thread.
    • The only way I can think that this was possible, is if Minecraft.level was not set, as both other possibilities concern loading and runtime on a dedicated or integrated server.
    • This stack trace is during packet decoding, not handling (this is already mildly problematic). Which means we now have a race condition, because shortly thereafter..
  • JEI receives "ClientPlayerNetworkEvent$LoggedInEvent" on main thread
    • This event fires strictly after ClientboundLoginPacket was handled, and Minecraft.level was set.

So it appears to be a race condition for Minecraft.level being set. But why is that a problem in the first place?

  • ClientboundContainerSetContentPacket, among others, serialize ItemStacks
  • We need to serialize and deserialize a IHeat (and IFood, but it doesn't look like that can possibly cause this issue) on network thread
  • This means we need to fully unbox capabilities, since we call getCapability(HeatCapability.CAPABILITY) - this completely unboxes Forge's lazy capability loading.
  • In VesselItem, when we load a capability instance, we also compute the heat capacity, which queries the alloy, which queries the RecipeManager unsafely (because it doesn't have access to a level anywhere in the call path, as it's an ItemStack capability), which throws an exception.
commented

Tentative fix tested:

  • It does fix the RecipeManager race on our end.
  • It does not fix the end user issue (they still have a packet handler error). Does not seem related to TFC at this point.

https://mclo.gs/TVrsvKs