Just Enough Items (JEI)

Just Enough Items (JEI)

495M Downloads

[Crash]: ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 256

pietro-lopes opened this issue ยท 7 comments

commented

Steps to Reproduce the Crash

Join a multiplayer world
Exit the world
Try to a singleplayer world
You will get an error that prevents you from joining

javaw_BC30OsPI2X.mp4

Mod Pack URL (Optional)

No response

Mod Pack Version (Optional)

No response

Extra Notes (Optional)

This was tested with only JEI on the instance.
I did a little debugging and the recipe serializer jei:jei_shaped is somewhat related to it

Crash Report

https://mclo.gs/1fxfCiH#L368

commented

It is the interaction between RegistryManager/RegistrySnapshot.

Set a breakpoint at:

net.minecraft.core.MappedRegistry#clear
with condition this.toString().contains("recipe")

net.minecraft.core.MappedRegistry#registerIdMapping
with condition key.toString().contains("jei_shaped")

net.neoforged.neoforge.registries.RegistrySnapshot#RegistrySnapshot(net.minecraft.core.Registry, boolean) (this is the constructor)
with condition registry.toString().contains("recipe_serializer")

--

Loading game, taking a vanilla snapshot: Ids and registry all fine

Image

Still loading game, now a frozen snapshot: Still ids and registry fine

Image

Going to load a Multiplayer world

Image

Apply snapshot is called and will clear partially the registry (only byId and toId)

Image

Image

Logged in, now I will disconnect

Image

Now I will join my Singleplayer world

Image

Some snapshot will be taken and notice the size of the maps does not match

Image

Image

when registry.getId(key) runs and get a key that is not mapped, it will give -1
Now snapshot is poisoned with a -1 Id

Some more clearing

Image

It will now try add to the mapping that cursed -1 that it got from the snapshot

Image

Setting -1 here causes the ArrayIndexOutOfBoundsException

Image

Image

Image

commented

Hello,

Sorry JEI does not sync anything at startup in 1.21.1, so I am not sure how it can be the cause of this particular issue.
The JEI shaped recipes only exist on the client and aren't added to the vanilla registry.
Can you share your findings about jei:jei_shaped?

commented

Fun fact: when you lose connection/is disconnected on that multiplayer, looks like a revertToFrozen is called and makes joining singleplayer normally.

commented

When I click disconnect, this is where it goes:

Image

When I'm disconnected (like losing connection), this is where it goes:

Image

So we can see that when I click disconnect, that revertToFrozen is never called.

commented

Did this as a test and it fixes this issue
(calling this on client side only)

public class FixSnapshot {
	private static final VarHandle DISCONNECTION_HANDLED;

	static {
		DISCONNECTION_HANDLED = ReflectionHelper.getFieldFromClass(Connection.class, "disconnectionHandled", boolean.class, false);
	}

	public FixSnapshot() {
		var gamebus = NeoForge.EVENT_BUS;
		gamebus.addListener(this::callRevertToFrozenOnDisconnect);
	}

	private void callRevertToFrozenOnDisconnect(ClientPlayerNetworkEvent.LoggingOut event) {
		if (Minecraft.getInstance().getConnection() instanceof ClientPacketListener listener) {
			var handled = (boolean)DISCONNECTION_HANDLED.get(listener.getConnection());
			if (!listener.getConnection().isMemoryConnection() && !handled) {
				RegistryManager.revertToFrozen();
			}
		}
	}
}

Tested and it does not call twice or in on wrong moment like login
Works for single player (will skip), multiplayer clicking quit (will trigger), or multiplayer being disconnected (will skip)

commented

Thanks for the analysis @pietro-lopes , it's rare that someone is so motivated to help dig in!

I wasn't aware of this functionality/optimization in the NeoForge registry manager when I registered my serializers to it. After looking at it for a bit, I think there is a potential that this is a NeoForge bug.

The NeoForge devs have a much deeper understanding of this, so for now the most efficient route to fixing it is to follow @ChampionAsh5357 's new NeoForge issue:

If the issue is in JEI after all, I'll be happy to accept their guidance to fix it!

commented

Will be fixed by neoforged/NeoForge#1944