Better Enchanted Books (Fabric)

Better Enchanted Books (Fabric)

691k Downloads

Crash when observing empty enchanted book, like the one in the Advancements screen

Partonetrain opened this issue ยท 5 comments

commented

The game crashes when trying to render an enchanted book without enchantment data, such as the icon of the advancement Enchanter (minecraft:story/enchant_item).

Not a Kotlin user, but it looks like there's no check for this

To Reproduce
Open Advancements screen

Expected behavior
No crash

Screenshots

Please include:

  • Minecraft Version: 1.20.1
  • Mod Version 1.20.4-2.0.0-beta

Crash stack:

java.util.NoSuchElementException: List is empty.
	at kotlin.collections.CollectionsKt___CollectionsKt.first(_Collections.kt:214)
	at dev.bernasss12.bebooks.util.NBTUtil.getPriorityEnchantmentData(NBTUtil.kt:45)
	at dev.bernasss12.bebooks.manage.BookColorManager.itemColorProvider$lambda$1(BookColorManager.kt:22)
	at net.minecraft.class_325.method_1704(class_325.java:86)
	at net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext.colorizeQuad(ItemRenderContext.java:182)
	at net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext.renderQuad(ItemRenderContext.java:175)
	at net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext$1.emitDirectly(ItemRenderContext.java:73)
	at net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl.emit(MutableQuadViewImpl.java:220)
	at net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl.emit(MutableQuadViewImpl.java:56)
	at net.fabricmc.fabric.impl.renderer.VanillaModelEncoder.emitItemQuads(VanillaModelEncoder.java:81)
	at net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel.emitItemQuads(FabricBakedModel.java:128)
	at net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel.emitItemQuads(ForwardingBakedModel.java:56)
	at me.pepperbell.continuity.client.model.EmissiveBakedModel.emitItemQuads(EmissiveBakedModel.java:84)
	at net.fabricmc.fabric.impl.client.indigo.renderer.render.ItemRenderContext.renderModel(ItemRenderContext.java:131)
	at net.minecraft.class_918.handler$dpd000$fabric-renderer-indigo$hook_renderItem(class_918.java:5549)
	at net.minecraft.class_918.method_23179(class_918.java:125)
	at net.minecraft.class_332.method_51425(class_332.java:531)
	at net.minecraft.class_332.method_51424(class_332.java:511)
	at net.minecraft.class_332.method_51445(class_332.java:503)
	at betteradvancements.gui.BetterAdvancementWidget.draw(BetterAdvancementWidget.java:239)
	at betteradvancements.gui.BetterAdvancementWidget.draw(BetterAdvancementWidget.java:243)
	at betteradvancements.gui.BetterAdvancementWidget.draw(BetterAdvancementWidget.java:243)
	at betteradvancements.gui.BetterAdvancementWidget.draw(BetterAdvancementWidget.java:243)
	at betteradvancements.gui.BetterAdvancementWidget.draw(BetterAdvancementWidget.java:243)
	at betteradvancements.gui.BetterAdvancementWidget.draw(BetterAdvancementWidget.java:243)
	at betteradvancements.gui.BetterAdvancementWidget.draw(BetterAdvancementWidget.java:243)
	at betteradvancements.gui.BetterAdvancementTab.drawContents(BetterAdvancementTab.java:100)
	at betteradvancements.gui.BetterAdvancementsScreen.renderInside(BetterAdvancementsScreen.java:386)
	at betteradvancements.gui.BetterAdvancementsScreen.method_25394(BetterAdvancementsScreen.java:220)
	at net.minecraft.class_437.method_47413(class_437.java:110)
	at net.minecraft.class_757.mixinextras$bridge$method_47413$219(class_757.java)
	at net.minecraft.class_757.wrapOperation$efa000$fancymenu$wrapRenderScreenFancyMenu(class_757.java:5607)
	at net.minecraft.class_757.mixinextras$bridge$wrapOperation$efa000$fancymenu$wrapRenderScreenFancyMenu$220(class_757.java)
	at net.minecraft.class_757.wrapOperation$eli000$konkrete$wrapRenderScreenKonkrete(class_757.java:6106)
	at net.minecraft.class_757.method_3192(class_757.java:945)
	at net.minecraft.class_310.method_1523(class_310.java:1219)
	at net.minecraft.class_310.method_1514(class_310.java:802)
	at net.minecraft.client.main.Main.main(Main.java:250)
	at net.fabricmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:470)
	at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
	at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)

(crash stack mentions other mods, but the issue happens anywhere with an enchanted book without NBT data)

commented

I added a check stack.hasEnchantments() before any NBT parsing so I could avoid making the method return nullable and add complexity when it's really not useful (at least at first sight, might change opinion in the future as I usually do :P).

commented

The fix commit was pushed now I'm just manually building and uploading the files. Really should look into automating that hahaha

commented

I see Bernass is already on it.

Just wanted to mention: The Java code (linked above) doesn't have this issue, findFirst returns an empty Optional if the collection is empty (and the whole method returns "" in this case).

The Kotlin code would need to use something like firstOrNull instead of first here and make the whole method nullable probably.

commented

Needs to be uploaded to CurseForge :)

commented

It's under manual review since saturday morning already, I'm not sure what to do about it at this point :(

Edit:
image

The first fix patched the crash but broke the rest of the mod, oops :P
But the second version is the right one and still under review.