ModManagerAccess
给「模组菜单」类模组用的管理能力:查询已注册模组、启用 / 激活状态与加载失败原因,并在运行期修改启用列表。内置模组菜单(ModListScene)功能与此接口等价,第三方模组可据此实现自己的管理 UI。
方法速览
| 方法 | 用途 |
|---|---|
registeredMods() | 全部已注册模组的元信息(含未启用 / 加载失败) |
getModInfo(String) | 单个模组的元信息 |
enabledMods() | 当前启用 id 列表(可能含未注册 id) |
isEnabled(String) | id 是否在启用列表中 |
isActive(String) | 是否已成功加载并处于激活状态 |
getLoadStatus(String) | 加载状态枚举 |
getLoadError(String) | 加载失败原因(消息文本) |
setEnabled(String, boolean) | 修改启用列表并持久化 |
完整签名
public interface ModManagerAccess {
List<ModInfo> registeredMods();
ModInfo getModInfo(String modId);
List<String> enabledMods();
boolean isEnabled(String modId);
boolean isActive(String modId);
ModLoadStatus getLoadStatus(String modId);
Optional<String> getLoadError(String modId);
void setEnabled(String modId, boolean enabled);
}registeredMods()
签名:
List<ModInfo> registeredMods();行为:返回全部已注册模组(含未启用与加载失败的),保持注册顺序;返回的是宿主内部列表的拷贝,调用方无法借此改写注册表。
示例:
for (ModInfo info : mgr.registeredMods()) {
ctx.getLogger().info(info.id() + " -> " + mgr.getLoadStatus(info.id()));
}getModInfo(String modId)
签名:
ModInfo getModInfo(String modId);行为:按 id 线性查找元信息;未注册或 modId 为 null 返回 null。
示例:
ModInfo info = mgr.getModInfo("mods-hinthud");
if (info != null) {
ctx.getLogger().info("已安装:" + info.name());
}enabledMods()
签名:
List<String> enabledMods();行为:返回当前启用 id 列表(拷贝)。可能包含未注册的残留 id——isEnabled 对它们同样返回 true。
示例:
for (String id : mgr.enabledMods()) {
if (mgr.getModInfo(id) == null) {
ctx.getLogger().warning("启用列表中有未注册 id:" + id);
}
}isEnabled(String modId) / isActive(String modId)
签名:
boolean isEnabled(String modId);
boolean isActive(String modId);行为:两者语义不同。
isEnabled只看 id 是否在启用列表,无论加载是否成功。isActive看该模组是否已成功加载并登记在激活表中(onLoad成功)。启用但加载失败的模组isEnabled = true、isActive = false。- 参数为
null时均返回false。
示例:
if (mgr.isEnabled(id) && !mgr.isActive(id)) {
ctx.getLogger().warning(id + " 已启用但未激活(可能加载失败)");
}getLoadStatus(String modId)
签名:
ModLoadStatus getLoadStatus(String modId);行为:返回 ACTIVE / LOAD_FAILED / REGISTERED / NOT_REGISTERED。判定顺序:已激活 → ACTIVE;jar 阶段就失败(API 版本、隔离、入口类)→ LOAD_FAILED;未注册 → NOT_REGISTERED;有加载错误 → LOAD_FAILED;否则 REGISTERED。modId 为 null 返回 NOT_REGISTERED。
示例:
if (mgr.getLoadStatus(id) == ModLoadStatus.LOAD_FAILED) {
mgr.getLoadError(id).ifPresent(reason -> ctx.getLogger().warning(id + " 失败:" + reason));
}getLoadError(String modId)
签名:
Optional<String> getLoadError(String modId);行为:返回加载失败原因的消息文本(Throwable#getMessage(),为空时退回 toString())。失败原因包括依赖缺失、循环依赖、onInit / onPostInit 抛异常,以及 jar 阶段的 API 版本 / 类加载失败;无失败或未注册返回 Optional.empty()。
示例:
mgr.getLoadError("mods-broken").ifPresent(msg -> ctx.getLogger().warning(msg));setEnabled(String modId, boolean enabled)
签名:
void setEnabled(String modId, boolean enabled);行为:把 id 加入 / 移出启用列表并写回设置(与内置模组菜单同一路径)。modId 为 null 或空串时直接返回;目标状态与当前一致时也直接返回(不重复持久化)。传入未注册的 id 会进入启用列表(isEnabled 为真)并输出一次告警,但不会激活。
注意(热停用已取消,严格 Minecraft 模型):模组注册表在启动装配结束后永久冻结。冻结后本方法只记录启用集合并在下次启动生效,本进程内的激活状态不变(isActive 仍反映当前已加载的模组),宿主输出"需重启生效"的告警。只有在冻结前(启动早期)调用才会真正按依赖拓扑执行 onLoad / onUnload。
示例:
mgr.setEnabled("mods-hinthud", true); // 冻结后:已记录,重启生效线程:实现把查询转发给 ModManager 的 synchronized 方法;任意线程可调用。
稳定性:2.0 起冻结:2.x 内只增不破。