Issue 1: 加载配置时模块的 enabled/key 字段缺失会导致 NPE,且错误信息不够精确
文件: src/main/java/top/fpsmaster/modules/config/ConfigManager.java,第 284-285 行
问题描述:
loadConfig 在读取每个模块的配置时,只检查了 moduleJson 是否包含 "settings" 字段:
if (moduleJson == null || !moduleJson.has("settings")) {
continue;
}
module.set(moduleJson.get("enabled").getAsBoolean());
module.key = moduleJson.get("key").getAsInt();
如果配置文件中某个模块对象缺少 "enabled" 或 "key" 字段(手工编辑、外部工具生成、部分写入损坏等情况下均可能发生),这里会抛出 NullPointerException。虽然外层有 catch (Throwable) 兜底,但用户只会看到一条模糊日志 "Failed to load module from config: xxx",无法定位到具体是哪个字段缺失。
建议修复:
if (moduleJson == null || !moduleJson.has("settings")) {
continue;
}
if (moduleJson.has("enabled")) {
module.set(moduleJson.get("enabled").getAsBoolean());
}
if (moduleJson.has("key")) {
module.key = moduleJson.get("key").getAsInt();
}
Issue 2: 高版本配置在低版本客户端上会被直接删除,无备份
文件: ConfigManager.java,resolveMigrationPath(第409-428行)与 migrateConfigIfNeeded(第380-385行)
问题描述:
当 fromVersion > targetVersion(即配置文件的 schemaVersion 高于当前客户端支持的版本,常见于用户从新版本降级回旧版本时),resolveMigrationPath 返回空列表,随后 migrateConfigIfNeeded 会直接调用 deleteConfigFile 永久删除用户的配置文件,且没有任何备份步骤:
if (migrationPath.isEmpty()) {
ClientLogger.warn("No config migration path from schema " + currentVersion + " to " + SCHEMA_VERSION + ", deleting " + name + ".json");
deleteConfigFile(name);
return null;
}
对用户来说,只是切换/回退了一次客户端版本,就会丢失全部自定义设置(模块状态、按键绑定、UI 布局等),体验很差,也没有恢复手段。
建议修复:在删除前先将原文件重命名/复制为 name.json.bak-schemaV{currentVersion},而不是直接删除;或至少提示用户"检测到更高版本的配置,将重置为默认设置,原文件已备份为 xxx"。
Issue 3: MultipleItemSetting 反序列化时未处理 Item.getItemById 返回 null 的情况
文件: ConfigManager.java 第 325 行,配合 ItemsUtil.getItemStackWithMetadata
问题描述:
int id = item.get("id").getAsInt();
int metadata = item.get("meta").getAsInt();
multipleItemSetting.addItem(ItemsUtil.getItemStackWithMetadata(Item.getItemById(id), metadata));
若配置中记录的物品 ID 在当前游戏环境下已不存在(比如卸载了某个添加该物品的模组、或 Minecraft/Forge 版本变化导致 ID 映射改变),Item.getItemById(id) 会返回 null。而 ItemsUtil.getItemStackWithMetadata:
public static ItemStack getItemStackWithMetadata(Item item, int metadata) {
ItemStack itemStack = new ItemStack(item);
itemStack.setItemDamage(metadata);
return itemStack;
}
对 item 参数没有做 null 检查,直接构造 new ItemStack(null)。这会生成一个语义上无效的 ItemStack,后续任何依赖 itemStack.getItem() 非空的渲染或逻辑代码都有出错风险。
建议修复:
Item resolvedItem = Item.getItemById(id);
if (resolvedItem != null) {
multipleItemSetting.addItem(ItemsUtil.getItemStackWithMetadata(resolvedItem, metadata));
} else {
ClientLogger.warn("Skipping unknown item id " + id + " in setting " + setting.name);
}
Issue 1: 加载配置时模块的
enabled/key字段缺失会导致 NPE,且错误信息不够精确文件:
src/main/java/top/fpsmaster/modules/config/ConfigManager.java,第 284-285 行问题描述:
loadConfig在读取每个模块的配置时,只检查了moduleJson是否包含"settings"字段:如果配置文件中某个模块对象缺少
"enabled"或"key"字段(手工编辑、外部工具生成、部分写入损坏等情况下均可能发生),这里会抛出NullPointerException。虽然外层有catch (Throwable)兜底,但用户只会看到一条模糊日志"Failed to load module from config: xxx",无法定位到具体是哪个字段缺失。建议修复:
Issue 2: 高版本配置在低版本客户端上会被直接删除,无备份
文件:
ConfigManager.java,resolveMigrationPath(第409-428行)与migrateConfigIfNeeded(第380-385行)问题描述:
当
fromVersion > targetVersion(即配置文件的 schemaVersion 高于当前客户端支持的版本,常见于用户从新版本降级回旧版本时),resolveMigrationPath返回空列表,随后migrateConfigIfNeeded会直接调用deleteConfigFile永久删除用户的配置文件,且没有任何备份步骤:对用户来说,只是切换/回退了一次客户端版本,就会丢失全部自定义设置(模块状态、按键绑定、UI 布局等),体验很差,也没有恢复手段。
建议修复:在删除前先将原文件重命名/复制为
name.json.bak-schemaV{currentVersion},而不是直接删除;或至少提示用户"检测到更高版本的配置,将重置为默认设置,原文件已备份为 xxx"。Issue 3:
MultipleItemSetting反序列化时未处理Item.getItemById返回 null 的情况文件:
ConfigManager.java第 325 行,配合ItemsUtil.getItemStackWithMetadata问题描述:
若配置中记录的物品 ID 在当前游戏环境下已不存在(比如卸载了某个添加该物品的模组、或 Minecraft/Forge 版本变化导致 ID 映射改变),
Item.getItemById(id)会返回null。而ItemsUtil.getItemStackWithMetadata:对
item参数没有做 null 检查,直接构造new ItemStack(null)。这会生成一个语义上无效的 ItemStack,后续任何依赖itemStack.getItem()非空的渲染或逻辑代码都有出错风险。建议修复: