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 would however still not 100% fix the issue, Badges.convert() should at least either throw an exception if there's any null in the set (that could happen if a mod forgot to register a badge), or silently filter out nulls in the set. This could be done by filtering the stream: .filter(Objects::nonNull).
Having a mod that has for example the following entry in the
fabric.mod.json
lets modmenu produce a NPE while rendering badges.This occours, because the
badge
variable in the second method here isnull
: https://github.com/TerraformersMC/ModMenu/blob/5d640d66a3e182889f84075d8fded0470534dbf5/src/main/java/com/terraformersmc/modmenu/util/mod/ModBadgeRenderer.java#L31-L40 This happens because theSet<Badge>
containsnull
. 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 fieldthis.badges
, which is returned by thegetBadges
method. As you can see, this code doesn't directly addnull
as a value. Therefore, the valuenull
must come from the fieldmodMenuData.badges
. This field is set in the constructor ofModMenuData
: https://github.com/TerraformersMC/ModMenu/blob/5d640d66a3e182889f84075d8fded0470534dbf5/src/main/java/com/terraformersmc/modmenu/util/mod/fabric/FabricMod.java#L337-L341 This just callsBadges.convert()
, which takes aSet<String>
and gives back aSet<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 thenull
comes from:KEY_MAP::get
can returnnull
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:
This issue also comes with further questions:
liteloader
and define it's colors and text (see what skyrising used for an example here: https://github.com/skyrising/ModMenu/commit/385c15f8197f83f0603ec23db98a1a6b00bd7a64)Badges.convert()
should at least either throw an exception if there's anynull
in the set (that could happen if a mod forgot to register a badge), or silently filter outnull
s in the set. This could be done by filtering the stream:.filter(Objects::nonNull)
.