架构¶
SDK 自底向上分层。传输层之上的每一层都可注入,宿主可以覆盖任意默认实现,且 SDK 不会导入宿主代码:
McbeServerFacade ← 宿主入口;拥有完整 WS 生命周期
├── ConnectionManager ← 活跃连接 + 每连接一条 response-sender 协程
│ ├── ConnectionState ← 与传输无关的身份(id、send_payload、队列)
│ └── ResponseSink ← 宿主路由 OutboundText / SystemNotification
├── MinecraftProtocolHandler ← 解析 PlayerMessage、解析命令、渲染状态行
│ └── CommandRegistry
├── EventBus ← 按 WsEventType 分键的进程内 pub/sub
├── ConnectionHook ← 宿主实现的六个生命周期钩子
├── AddonBridgeService ← ScriptEvent 桥 + 分片重组
│ └── AddonBridgeSession
├── FlowControlMiddleware ← 字节安全的 tellraw/scriptevent 分片(461 B 上限)
└── McbeOutboundDelivery ← 统一出站适配器
SDK 没有自带 PlayerSession。多人会话隔离是宿主职责:网关只透传
PlayerMessageEvent.sender;宿主按 (connection_id, sender) 分桶历史 / 锁 /
上下文。
依赖倒置¶
McbeServerFacade.__init__ 是 keyword-only 的;每个协作者在 None 时折叠为网关默认值。
宿主只需子类化自己关心的部分:
NoOpHook/ConnectionHookDefaultResponseSink/ResponseSink
ConnectionHook 共六个纯副作用钩子(全部 -> None)。聊天钩子签名为:
async def on_player_message(
self,
state: ConnectionState,
player_event: PlayerMessageEvent,
parsed: ParsedCommand | None = None,
) -> None: ...
parsed 是 registry 的预解析匹配结果(若有);不是"已消费"布尔返回值 ——
宿主自行决定如何处理自由聊天与命令。
每连接消息路由¶
McbeServerFacade._on_connection创建连接状态,启动_response_sender协程, 并发送 handshake + subscribe。二者成功后先 emitWsEventType.CONNECTED, 再调用hook.on_connected(welcome 由宿主在该 hook 中负责发送,facade 本身 不发欢迎语)。_handle_raw对每帧入站数据分类:- error →
WsEventType.ERROR+hook.on_error - commandResponse →
WsEventType.COMMAND_RESPONSE+hook.on_command_response - addon 前缀匹配 →
AddonBridgeService(桥接 / UI 聊天重组) - PlayerMessage →
WsEventType.PLAYER_MESSAGE+hook.on_player_message(state, event, parsed=...) - response-sender 排空
state.response_queue,经RouteEnvelope.from_message()包装后 内联路由到 sink 的两个on_*方法(协议上不含dispatch)。 - 宿主 sink 使用
McbeOutboundDelivery把排队消息变成 MC WebSocket 负载。
流控 — 461 B 硬上限¶
FlowControlMiddleware 强制执行 MCBE commandLine 字节预算(461 字节,实测得出):
chunk_tellraw()/chunk_scriptevent()— 带字节安全保护的语义分句chunk_raw_command()— 不做语义切分;超限抛出FrameTooLargeErrorchunk_framed_scriptevent()— 两遍:先切分再带i/n元数据重编码
协议 profile¶
协议 profile 位于 profiles/,定义互操作层的线格式常量。
McbewsV1Profile 是唯一内置 profile(模块级单例 MCBEWS_V1)。线格式详见
协议。
Addon 桥运行要求¶
配套 Script addon 仅在世界开启 实验 → 测试版 API(Beta APIs)时加载。
未开启时 scriptEventReceive 不会触发,能力请求会超时。详见
addon/README.zh.md — 在世界中启用。
Addon 桥信任边界¶
桥接层不是安全边界。宿主必须自行认证 / 授权谁可以调用能力;addon 仅在 世界命令路径上提供防御性 allow/denylist。详见 addon/README.md — Trust boundary (中文见 addon/README.zh.md — 信任边界)。
不导入宿主¶
SDK 从不导入父级宿主应用。ConnectionState.send_payload 是不透明的
Callable[[str], Awaitable[None]]——facade 把它接到 websocket.send。
宿主专有的装帧(connection_id、时间戳、LLM 消息 id)留在宿主侧。