Gateways to Eternity

Gateways to Eternity

20M Downloads

[1.16] GatewayManager not properly initialized in multiplayer

embeddedt opened this issue ยท 4 comments

commented

I received a report that having ModernFix and JEI installed alongside Gateways To Eternity causes it to not work when connecting to a multiplayer server on 1.16.5. I noted the following stacktrace in the log:

[01Aug2023 12:24:07.923] [Render thread/FATAL] [net.minecraft.util.concurrent.ThreadTaskExecutor/]: Error executing task on Client
java.lang.RuntimeException: Received sync packet for unknown registry!
	at shadows.placebo.json.PlaceboJsonReloadListener.readItem(PlaceboJsonReloadListener.java:260) ~[placebo:4.7.1]
	at shadows.placebo.net.ReloadListenerPacket$Content.read(ReloadListenerPacket.java:65) ~[placebo:4.7.1]
	at shadows.placebo.net.ReloadListenerPacket$Content.read(ReloadListenerPacket.java:43) ~[placebo:4.7.1]
	at net.minecraftforge.fml.network.simple.IndexedMessageCodec.lambda$tryDecode$0(IndexedMessageCodec.java:106) ~[forge:?]
	at java.util.Optional.map(Unknown Source) ~[?:1.8.0_311]
	at net.minecraftforge.fml.network.simple.IndexedMessageCodec.tryDecode(IndexedMessageCodec.java:106) ~[forge:?]
	at net.minecraftforge.fml.network.simple.IndexedMessageCodec.consume(IndexedMessageCodec.java:148) ~[forge:?]
	at net.minecraftforge.fml.network.simple.SimpleChannel.networkEventListener(SimpleChannel.java:66) ~[forge:?]
	at net.minecraftforge.eventbus.EventBus.doCastFilter(EventBus.java:247) ~[eventbus-4.0.0.jar:?]
	at net.minecraftforge.eventbus.EventBus.lambda$addListener$11(EventBus.java:239) ~[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.network.NetworkInstance.dispatch(NetworkInstance.java:72) ~[forge:?]
	at net.minecraftforge.fml.network.NetworkHooks.lambda$onCustomPayload$1(NetworkHooks.java:77) ~[forge:?]
	at java.util.Optional.map(Unknown Source) ~[?:1.8.0_311]
	at net.minecraftforge.fml.network.NetworkHooks.onCustomPayload(NetworkHooks.java:77) ~[forge:?]
	at net.minecraft.client.network.play.ClientPlayNetHandler.func_147240_a(ClientPlayNetHandler.java:1905) ~[?:?]
	at net.minecraft.network.play.server.SCustomPayloadPlayPacket.func_148833_a(SCustomPayloadPlayPacket.java:59) ~[?:?]
	at net.minecraft.network.play.server.SCustomPayloadPlayPacket.func_148833_a(SCustomPayloadPlayPacket.java:11) ~[?:?]
	at net.minecraft.network.PacketThreadUtil.func_225383_a(SourceFile:21) ~[?:?]
	at net.minecraft.util.concurrent.ThreadTaskExecutor.func_213166_h(SourceFile:144) ~[?:?]

I believe the reason this is occurring is that the GatewayManager is not classloaded when connecting to a multiplayer server, as it only seems to be referenced from an AddReloadListenerEvent here. This differs from the 1.18+ implementation which explicitly calls registerToBus in its FMLCommonSetupEvent. Due to this implementation difference, there doesn't seem to be a guarantee that the underlying Placebo synced registry will have been initialized when the server attempts to send gateway data to the client.

To confirm this theory I added the following hack to ModernFix and relaunched the game. The issue immediately went away. I am not entirely sure why ModernFix and JEI are required to reproduce it, but the original logic does seem incorrect in any case.

    @SubscribeEvent
    public void loadComplete(FMLLoadCompleteEvent event) {
        event.enqueueWork(() -> {
            try { Class.forName("shadows.gateways.gate.GatewayManager"); } catch(Throwable e) {
                e.printStackTrace();
            }
        });
    }

I think you could fix this on your end easily by adding a FMLLoadCompleteEvent handler with something like the code shown below. The use of enqueueWork is intentional as the 1.16 version of PlaceboJsonReloadListener's constructor doesn't appear to be thread-safe.

        event.enqueueWork(() -> {
            GatewayManager.INSTANCE.getKeys(); // be sure it's classloaded
        });
commented

It doesn't seem to be specifically ModernFix, as I couldn't get it to happen until also adding JEI to my instance. (It's not the JEI patch in ModernFix either, tested with that disabled.)

I'm not really sure why either of them would introduce this issue, but I did stop debugging once I discovered that the class loading solved the problem. I suppose one thing I can try is figuring out what causes GatewayManager to be loaded in the standalone scenario, it is definitely possible that ModernFix modifies a code path in a way that reveals the bug.

commented

Any clue why modernfix causes it to fail? From that information it seems like it should just never work, not be conditional on modernfix being installed. Does the AddReloadListenerEvent normally get triggered on the client (in 1.16), but something modernfix changes is preventing that?

commented

Hm, only thing I can think of is the creative search tree calculation - querying the gate pearl item for subitems would try to access the manager, and thus classload it - is that disabled by MF+JEI?

commented

Absolute genius. Yes. ModernFix disables creative search tree building when JEI is present and redirects searching to JEI instead. After adding a quirk to run fillItemCategory on all items anyway, the issue is resolved.