onEquipped() called with player==null
HenryLoenwind opened this issue ยท 2 comments
see VazkiiMods/Botania#1757 and the linked Ender IO issues. (Ignore the stray call to onEquipped() for packet 30 stuff, that's just a small detail where the Capacitor Bank implementation differed from the Baubles Main Inventory implementation and is ultimately unrelated to the crash.)
I'd call it a freak occurrence, but we just got a second report in. In multiplayer on the client, the Baubles inventory returned by the API has lost its weak reference to its player. As a result, Botania's onEquipped() handling crashes with a NPE. It doesn't happen with the Baubles inventory, only when Ender IO's Capacitor Bank accesses the Baubles inventory.
I had a look at the Baubles code, and I can see some ways that an outdated Baubles inventory from a previous world could stay alive. But the user said they started the game and went straight onto the server where it crashed, so that's not the root cause here. Maybe you can find out what's happening here?
On the other hand, it'd look like a good idea to refresh that weak reference before handing out the Baubles inventory. After all, it is being looked up by player.
Current Ender IO code: https://github.com/SleepyTrousers/EnderIO/blob/master/src/main/java/crazypants/enderio/machine/capbank/ContainerCapBank.java#L45-L84 to be updated with HenryLoenwind/EnderIO@7b7ca9a for the packet 30 stuff...which won't change a thing as packet 2F still triggers a stray onEquipped(), just like in the Baubles inventory.
I was talking about refreshing it here: https://github.com/Azanor/Baubles/blob/1.7.10/src/main/java/baubles/common/lib/PlayerHandler.java#L29 e.g.
else { playerBaubles.get(player.getCommandSenderName()).refreshPlayer(player); }
Also, I just noticed a slight problem here in single player. The Baubles inventory object is shared between client and server (which leads to all kinds of problems), which means the player object that is stored there may will end up in the wrong thread via those callbacks.
However, that cannot be the reason for the weak ref to die here. We're talking multiplayer client here.
Unfortunately I cannot refresh the weak ref in the inventory, since the weak ref is the only way I know which player is doing the equipping - if the reference is dead then there is now way to recover it. The alternatives are for items to make sure the passed player is valid, or I could simply not trigger the call if the player is null. Neither are ideal solutions.