平台:Windows11
Minecraft版本:1.20.1-Fabric-0.16.14
mod列表:
锦致装饰 | Supplementaries | 3.1.31
物品栏HUD+ | Inventory HUD+ | 3.4.26
Simple Animated Guns | 1.3
AzureLib | 3.0.8
Moonlight Lib | 2.14.8
Fabric API | 0.92.6
冲突现象
在Inventory HUD+模组开启HUD效果展示的情况下,将Simple Animated Guns模组相关的枪支取出到装备栏上,Minecraft崩溃。
在装载了锦致装饰 Supplementaries模组和Simple Animated Guns模组的情况下,点击存档进入游戏就会使得Minecraft崩溃。
崩溃原因
Inventory HUD+这类可能会显示物品信息的模组会检查玩家装备栏,当你把Simple Animated Guns的枪取出来准备使用,此时Inventory HUD+发现装备栏上一个物品为GunItem,检查这个物品发现它声明为远程武器,于是Inventory HUD+尝试调用GunItem.getProjectiles()方法来获取这个武器的弹药信息,但是Simple Animated Guns模组的重写方法提供的返回值却是null,Inventory HUD+并没有更多的手段应对这种情况,于是触发了空指针错误NullPointerException,进而导致Minecraft游戏崩溃。为什么Inventory HUD+要读取弹药类型呢?因为Inventory HUD+这个模组会在HUD中显示当前装备的武器还剩多少弹药或者耐久度。
锦致装饰 Supplementaries 模组通过 Mixin 修改了 ItemStack 的行为,以便能够查询物品是否是某个特定武器的弹药(可能是为了显示箭袋或类似功能?),这种行为使得锦致装饰 Supplementaries 模组和Inventory HUD+一样,因为Simple Animated Guns中的getProjectiles()提供的返回值为null而崩溃。
解决办法
思路有三类:
修改Simple Animated Guns代码:保证非空返回
修改Inventory HUD+代码:加 null 检查
修改Supplementaries代码:加 null 检查
Mixin折中
因为Simple Animated Guns适配Minecraft1.20.1的源代码工程在GitHub可以找到,所以我选择修改Simple Animated Guns代码来解决问题。
在源代码的:src\main\java\net\elidhan\anim_guns\item\GunItem.java的769行处,将原方法:
@Overridepublic Predicate
@Overridepublic Predicate
编译
修改好代码后,在根目录下执行命令:
.\gradlew build最后,编译成功后,你需要将编译后的jar文件替换回mod列表。
编译后的jar文件在build文件夹下的libs文件夹中,该文件夹中将会存在两个jar文件,你需要带回去替换的是文件名中不带sources的那个。
好了,享受游戏吧~
相关链接
原作者1.20.1的工程源码-提取码h47e