扩展 API
供其他模组接入 Opis 探针与面板的四个公开接口,全部位于 mcp.mobius.opis.api 包。
基本信息
| 属性 | 值 |
|---|---|
| 包路径 | mcp.mobius.opis.api |
apiPackage 配置 |
apiPackage = opis.api(gradle.properties:102),与 modGroup = mcp.mobius(gradle.properties:14)合成 |
| 接口数量 | 4(2 个接口 + 2 个枚举单例注册器) |
| 稳定标记 | 无:@Mod 注解只写了 modid / name / version / acceptableRemoteVersions 四个属性,未声明 dependencies;src/main/resources/mcmod.info 的 "dependencies": [] 也是空数组 |
功能
IMessageHandler
public interface IMessageHandler {
public boolean handleMessage(Message msg, PacketBase rawdata);
}
数据封包的处理回调。返回 false 会触发一条 WARN 日志(MessageHandlerRegistrar.java:28-30,格式 Unhandled msg %s in handler %s)。面板里的 23 个 Panel 都实现这个接口。
MessageHandlerRegistrar
enum 单例(MessageHandlerRegistrar.INSTANCE),按 Message 维护 HashMap<Message, HashSet<IMessageHandler>>:
registerHandler(Message, IMessageHandler):同一 Message 可注册多个 handler,路由时全部调用(用HashSet去重同一个实例)routeMessage(Message, PacketBase):遍历该 Message 的全部 handler;某个 handler 返回 false 就打一条 WARN(MessageHandlerRegistrar.java:28)。若该 Message 完全没有注册 handler,且suppressUnhandledMsgLogs为 false,则打一条Unhandled msg : %s的 WARN(MessageHandlerRegistrar.java:32)- 公共字段
suppressUnhandledMsgLogs:在modOpis构造函数里被设为FMLLaunchHandler.side().isClient() && java.awt.headless(modOpis.java:117),即无头客户端自动静音
ITabPanel
public interface ITabPanel {
SelectedTab getSelectedTab();
boolean refreshOnString();
boolean refresh();
}
面板页签接口。refreshOnString() 表示「是否在字符串缓存更新时刷新」,refresh() 执行实际刷新。实现类同时必须是 JPanel 子类 —— TabPanelRegistrar.registerTab 直接强转 (JPanel) panel。
TabPanelRegistrar
enum 单例(TabPanelRegistrar.INSTANCE),实现 ChangeListener,管理 Swing 标签页:
| 方法 | 作用 |
|---|---|
registerSection(String name) |
新建一个分组 JTabbedPane 并挂到顶层 |
registerTab(ITabPanel, String name) |
挂到顶层标签页 |
registerTab(ITabPanel, String name, String section) |
挂到指定分组内 |
getTab(SelectedTab) / getTabAsPanel(SelectedTab) |
按枚举值反查面板 |
refreshAll() |
对所有 refreshOnString() 为 true 的面板调 refresh() |
stateChanged(ChangeEvent) |
玩家切页时向服务端发 SWING_TAB_CHANGED |
stateChanged 会把 panel.getSelectedTab().ordinal() 包成 SerialInt 发给服务端(TabPanelRegistrar.java:64-72),服务端写入 PlayerTracker.INSTANCE.playerTab(ServerMessageHandler.java:242-244),因此切页状态是按玩家记忆的。
数值
| 数值名 | 值 |
|---|---|
Message 枚举成员总数 |
69 |
SelectedTab 枚举成员总数 |
27(24 个数据页签值 + ANY / NONE / ALL 三个控制用值) |
| 实际注册的面板数 | 23(grep -rn 'getSelectedTab' --include=*.java src/main/java/mcp/mobius/opis/swing/panels/ 命中 23 个实现) |
SelectedTab 中未被任何面板使用的值 |
PACKETS(grep -rn 'SelectedTab.PACKETS' --include=*.java src/main/java 0 命中) |
| 分组数 | 5 |
MessageHandlerRegistrar 单例键 |
INSTANCE |
TabPanelRegistrar 单例键 |
INSTANCE |
交互
| 外部模组动作 | 效果 |
|---|---|
实现 IMessageHandler 并 registerHandler |
收到该 Message 的所有封包 |
| handler 返回 false | 记一条 WARN,不影响其它 handler |
实现 ITabPanel 并 registerTab |
面板出现在 Opis 标签页中 |
| 玩家切换页签 | 自动发 SWING_TAB_CHANGED,服务端记住该玩家所在页 |
相关条目
- network-protocol -
Message与PacketBase的完整协议面 - swing-ui - 23 个面板的分组与页签清单
- config - accessLevel 如何限制封包可见性