Psi

Psi

45M Downloads

IndexOutOfBoundsException whilst GUI with no slots is open

SanAndreaP opened this issue ยท 1 comments

commented

MinecraftForge: 1.12.2-14.23.5.2770
AutoRegLib: 1.3-20
Psi: r1.1-59

When a CAD is in a players inventory (not in the hotbar) and a container GUI is opened that has no slots (tested with the GUIs of Super Sound Muffler and Industrial Foregoing whilst configuring machine sides), the log is spammed with following stacktrace (and if you have VanillaFix installed, the game lags out and a seemingly endless amount of error message toasts from that mod pop up):

[14:24:41] [main/FATAL] [net.minecraft.client.Minecraft]: Error executing task
java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 9, Size: 0
	at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_181]
	at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_181]
	at net.minecraft.util.Util.func_181617_a(SourceFile:47) [h.class:?]
	at net.minecraft.client.Minecraft.func_71411_J(Minecraft.java:1087) [bib.class:?]
	at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:397) [bib.class:?]
	at net.minecraft.client.main.Main.main(SourceFile:123) [Main.class:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
	at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
	at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_181]
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_181]
	at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_181]
	at org.multimc.onesix.OneSixLauncher.launchWithMainClass(OneSixLauncher.java:196) [NewLaunch.jar:?]
	at org.multimc.onesix.OneSixLauncher.launch(OneSixLauncher.java:231) [NewLaunch.jar:?]
	at org.multimc.EntryPoint.listen(EntryPoint.java:143) [NewLaunch.jar:?]
	at org.multimc.EntryPoint.main(EntryPoint.java:34) [NewLaunch.jar:?]
Caused by: java.lang.IndexOutOfBoundsException: Index: 9, Size: 0
	at java.util.ArrayList.rangeCheck(Unknown Source) ~[?:1.8.0_181]
	at java.util.ArrayList.get(Unknown Source) ~[?:1.8.0_181]
	at net.minecraft.inventory.Container.func_75139_a(Container.java:120) ~[afr.class:?]
	at net.minecraft.inventory.Container.func_75141_a(Container.java:519) ~[afr.class:?]
	at net.minecraft.client.network.NetHandlerPlayClient.func_147266_a(NetHandlerPlayClient.java:1154) ~[brz.class:?]
	at net.minecraft.network.play.server.SPacketSetSlot.func_148833_a(SourceFile:30) ~[iu.class:?]
	at net.minecraft.network.play.server.SPacketSetSlot.func_148833_a(SourceFile:10) ~[iu.class:?]
	at net.minecraft.network.PacketThreadUtil$1.run(SourceFile:13) ~[hv$1.class:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_181]
	at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_181]
	at net.minecraft.util.Util.func_181617_a(SourceFile:46) ~[h.class:?]
	... 17 more

Here's the full latest.log: https://gist.githubusercontent.com/SanAndreasP/3ee93b2294746d1e5611c21294eec98a/raw/be686b7cc38a9ba0371dfa42ad1030acfaa56139/latest.log

commented

After debugging for quite a while I found the cause of this issue:

  • It always errors exactly on this line: https://github.com/Vazkii/Psi/blob/master/src/main/java/vazkii/psi/common/core/handler/PlayerDataHandler.java#L139
  • What's happening is Psi updates the CAD time on the server, doing so will cause the server to send a packet to the player with the updated info
  • The update packet uses the slot ID to determine which item needs to be updated
  • This works fine if there's a container GUI that renders the inventory slots or the CAD is in the hotbar/offhand (as they're always rendered even when hiding the HUD)
  • As soon as there's a container that doesn't render slots on the client for some reason, the packet fails to find that slot. Notable examples:
    • Industrial Foregoing - when configuring sides of a machine, the slots are "removed" from the container
    • OpenBlocks Manual - even though it's theoretically not even a container, it uses a DummyContainer with 0 slots on the client because they extend GuiContainer for every GUI

AFAIK there would be the following solutions:

  • intercept the update on the client (doesn't work without ASM as there's no Forge event for that)
  • intercept sending the update packet on the server, cancel it and send your own packet (doesn't work, see above)
  • Detect when a player opens a GUI from the client (not from the server, as OpenBlocks non-container GUIs don't even provide a container to the server), send a packet to the server to notify Psi to not update the item until the GUI is closed (extremely hacky, I personally wouldn't like this solution)
  • Only allow updating the CAD if it's in a players hotbar/offhand (cleanest, non-ASM solution, but could have issues with hotbar-extending mods like Multi-Hotbar, since the hotbar slot ID range is hardcoded)
  • use ASM to be able to do the first solution