Modmenu produces a NPE when having an unknown Badge entry
zeichenreihe opened this issue ยท 0 comments
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
:
This happens because the
Set<Badge>
contains null
. After looking from where this set comes, you get to here: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
:This just calls
Badges.convert()
, which takes a Set<String>
and gives back a Set<Badge>
:ModMenu/src/main/java/com/terraformersmc/modmenu/util/mod/Mod.java
Lines 151 to 153 in 5d640d6
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, OrnitheMC/modmenu#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:
- Should there be some kind of API to register badge? This would, at least partially, remove the issue, as then one mod counld register the badge
liteloader
and define it's colors and text (see what skyrising used for an example here: skyrising@385c15f) - This would however still not 100% fix the issue,
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)
.