TerraformersMC / ModMenu

A menu for, you guessed it, mods!
MIT License
476 stars 140 forks source link

Modmenu produces a NPE when having an unknown Badge entry #693

Closed zeichenreihe closed 2 weeks ago

zeichenreihe commented 4 months ago

Having a mod that has for example the following entry in the fabric.mod.json lets modmenu produce a NPE while rendering badges.

"custom": {
    "modmenu": {
      "badges": [
        "liteloader"
      ]
    }
  }

This occours, because the badge variable in the second method here is null: https://github.com/TerraformersMC/ModMenu/blob/5d640d66a3e182889f84075d8fded0470534dbf5/src/main/java/com/terraformersmc/modmenu/util/mod/ModBadgeRenderer.java#L31-L40 This happens because the Set<Badge> contains null. After looking from where this set comes, you get to here: https://github.com/TerraformersMC/ModMenu/blob/5d640d66a3e182889f84075d8fded0470534dbf5/src/main/java/com/terraformersmc/modmenu/util/mod/fabric/FabricMod.java#L92-L131 As you can see, in Line 113 it sets the field this.badges, which is returned by the getBadges method. As you can see, this code doesn't directly add null as a value. Therefore, the value null must come from the field modMenuData.badges. This field is set in the constructor of ModMenuData: https://github.com/TerraformersMC/ModMenu/blob/5d640d66a3e182889f84075d8fded0470534dbf5/src/main/java/com/terraformersmc/modmenu/util/mod/fabric/FabricMod.java#L337-L341 This just calls Badges.convert(), which takes a Set<String> and gives back a Set<Badge>: https://github.com/TerraformersMC/ModMenu/blob/5d640d66a3e182889f84075d8fded0470534dbf5/src/main/java/com/terraformersmc/modmenu/util/mod/Mod.java#L151-L153 And this also shows us where the null comes from: KEY_MAP::get can return null if there's no key-value pair. And that's percisely what happens in my case.

Note that the usage of liteloader here is just because it happened in a modmenu port to Ornithe, a modding toolchain for old minecraft versions. The relevant code path was not changed in the code. Therefore it could also happen in modern modmenu. (I also fist asked there, https://github.com/OrnitheMC/modmenu/issues/4, and we determined that upstream also has the issue, and therefore I think that it should be fixed in upstream)

A crashlog from Ornithe:

Caused by: java.lang.NullPointerException
    at com.terraformersmc.modmenu.util.mod.ModBadgeRenderer.drawBadge(ModBadgeRenderer.java:33) ~[modmenu-0.2.0+mc1.12.2.jar:?]
    at com.terraformersmc.modmenu.util.mod.ModBadgeRenderer.lambda$draw$0(ModBadgeRenderer.java:29) ~[modmenu-0.2.0+mc1.12.2.jar:?]
    at java.lang.Iterable.forEach(Iterable.java:75) ~[?:1.8.0_392]
    at com.terraformersmc.modmenu.util.mod.ModBadgeRenderer.draw(ModBadgeRenderer.java:29) ~[modmenu-0.2.0+mc1.12.2.jar:?]
    at com.terraformersmc.modmenu.gui.widget.entries.ModListEntry.render(ModListEntry.java:75) ~[modmenu-0.2.0+mc1.12.2.jar:?]
    at net.minecraft.client.gui.widget.EntryListWidget.renderEntry(EntryListWidget.java:28) ~[1.12.2-TRv0.8.2-named-711666161528F3329D7A8C8C611232C03E2D58B845ABA1B8F40897F5800EAE50.jar:?]
    at com.terraformersmc.modmenu.gui.widget.ModListWidget.renderList(ModListWidget.java:246) ~[modmenu-0.2.0+mc1.12.2.jar:?]
    at net.minecraft.client.gui.widget.ListWidget.render(ListWidget.java:194) ~[1.12.2-TRv0.8.2-named-711666161528F3329D7A8C8C611232C03E2D58B845ABA1B8F40897F5800EAE50.jar:?]
    at com.terraformersmc.modmenu.gui.ModsScreen.render(ModsScreen.java:321) ~[modmenu-0.2.0+mc1.12.2.jar:?]
    at net.minecraft.client.render.GameRenderer.render(GameRenderer.java:947) ~[1.12.2-TRv0.8.2-named-711666161528F3329D7A8C8C611232C03E2D58B845ABA1B8F40897F5800EAE50.jar:?]
    ... 6 more

This issue also comes with further questions: