# BridgeProtocol **Repository Path**: TayunStarry/bridge-protocol ## Basic Information - **Project Name**: BridgeProtocol - **Description**: 统一推送协议(以下简称“协议”)是一个为基岩版游戏设计的通信协议,旨在标准化多核模组端之间的数据交换。该协议提供了一套灵活的接口,允许开发者轻松集成和扩展功能,实现模块化的数据推送。 - **Primary Language**: TypeScript - **License**: MPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 7 - **Forks**: 0 - **Created**: 2024-11-16 - **Last Updated**: 2025-11-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: JavaScript, Server-API, TypeScript, Minecraft-Bedrock-Edition ## README # WorldBridge - 跨模组通信桥接器 [< 旧版 TS源码 >](./BridgeProtocol.ts) [< 旧版 JS源码 >](./BridgeProtocol.js) [< TS 源码 >](./2025-11-30/WorldBridge.ts) [< TS 源码 (紧凑编码协议) >](./2025-11-30/WorldBridge(紧凑编码版).ts) ## 概述 WorldBridge 是一个为 Minecraft 基岩版(Bedrock Edition)脚本引擎设计的**跨模组通信解决方案**。它利用游戏内的脚本事件系统,构建了一个安全、高效、类型安全的函数调用和数据传输框架,彻底解决了 Minecraft 脚本模组间隔离的问题。 ## 核心特性 ### 🔄 **跨模组函数调用** - **双向通信**: 允许任意模组注册函数供其他模组调用 - **异步返回值**: 支持获取远程函数的执行结果 - **自动发现**: 内置函数列表查询机制 - **超时控制**: 默认 200 tick(约10秒)超时保护 ### 🏗️ **完整类型系统** ```typescript // 支持的数据类型 type TransmitDataType = | string | boolean | number // 基础类型 | JSONObject | JSONArray // JSON结构 | server.Entity | server.Block // 游戏对象 | server.Dimension | server.ItemStack | server.Container | server.RawMessage | TransmitDataType[] // 数组嵌套 | undefined | null; // 特殊值 ``` ### 🎯 **游戏对象智能序列化** - **实体**: 通过ID自动重建,保持对象引用 - **方块**: 保留坐标和维度信息,动态获取最新状态 - **维度**: 跨维度安全传输 - **容器/物品**: 完整的库存系统支持 ### 🛡️ **可扩展的控制层** ```typescript interface ControlParameter { sourceLabel: BriefLabelType; // 调用源项目标识 callName: FunctionNameType; // 被调用函数名 onlyLabel: OutputLabelType; // 本次调用唯一ID parameter: string; // 原始参数字符串 allParameters: string[]; // 所有参数片段 cancel: boolean; // 可设置的取消标志 } ``` ### 📦 **大数据分片传输** - **自动分片**: 将长数据按255字符分块 - **透明重组**: 接收端自动拼接完整数据 - **流式处理**: 支持大体积参数和返回值 ## 快速开始 ### 1. 安装与导入 将 `WorldBridge.ts` 放入项目,并导入依赖模块: ```typescript import bridge from "./WorldBridge"; ``` ### 2. 注册函数供调用 ```typescript // 定义一个函数,它接受两个数字并返回它们的和 function add(a: number, b: number): number { return a + b; } // 注册函数,默认使用函数名 'add' 作为外部调用标识 bridge.release(add); // 你也可以自定义函数名 bridge.release(add, "myAddFunction"); // 带游戏对象的函数注册 function teleportEntity( entity: server.Entity, destination: server.Block, ): boolean { try { entity.teleport(destination.location, { dimension: destination.dimension }); return true; } catch { return false; } } bridge.release(teleportEntity); ``` ### 3. 调用远程函数 ```typescript // 调用其他模组注册的 'add' 函数,并传递参数 1 和 2 const result = await bridge.call("add", [1, 2]); console.log(result); // [3] 注意:返回值为数组,对应函数返回值的数组 // 基本调用 async function combatLogic() { const [damage] = await bridge.call("computeDamage", [player, enemy, sword]); console.log(`造成 ${damage} 点伤害`); } // 处理游戏对象返回值 async function findNearestEntity() { const [nearest] = await bridge.call("findNearestEntity", [player, 10]); if (nearest instanceof server.Entity) { await bridge.call("teleportEntity", [nearest, targetLocation]); } } ``` ### 4. 库存系统集成 ```typescript // 编码完整容器 const chestBlock = dimension.getBlock({ x: 10, y: 20, z: 30 }); // 编码整个库存容器 const chestData = bridge.inventoryEncoder(chestBlock); // 编码特定槽位 const playerSlot = bridge.inventoryEncoder(player, 0); // 主手物品 // 在远程函数中使用 // 在远程函数中,你不需要手动解码,WorldBridge 会自动将其还原为 Container 或 ItemStack 对象。 async function transferItems() { await bridge.call("transferToChest", [playerSlot, chestData]); } ``` ### 5. 事件监控与拦截 ```typescript // 权限控制 const permissionCheck = bridge.control.subscribe((data) => { if (data.callName === "adminCommand") { const [executor] = bridge.decoder(data.parameter); if (!isAdmin(executor)) { // 如果你想要阻止这次调用,可以设置 data.cancel = true data.cancel = true; console.warn(`非管理员 ${executor.name} 尝试执行管理命令`); } } }); // 调用日志 const callLogger = bridge.control.subscribe((data) => { console.log( `[Bridge] ${data.sourceLabel} -> ${data.callName} (ID:${data.onlyLabel})`, ); }); // 取消订阅 bridge.control.unsubscribe(permissionCheck); ``` ## 核心API详解 ### Bridge 类 #### `release(func: T, functionName?: string)` 注册函数供远程调用。 **参数:** - `func`: 符合 `ReleaseFunctionType` 签名的函数 - `functionName`: 可选,对外暴露的名称(默认使用函数名) **示例:** ```typescript // 类型安全的函数注册 type TeleportFunc = ( entities: server.Entity[], destination: server.Block, ) => number; const teleportGroup: TeleportFunc = (entities, destination) => { return entities.filter((e) => e.teleport(destination.location)).length; }; bridge.release(teleportGroup, "massTeleport"); ``` #### `call(functionName: string, parameters: TransmitDataType[]): Promise` 调用远程函数。 **参数:** - `functionName`: 目标函数名 - `parameters`: 参数数组 **返回:** 包含函数返回值的数组 **示例:** ```typescript const [successCount] = await bridge.call("massTeleport", [ villagers, townCenter, ]); ``` #### 手动序列化数据 `encoder(data: TransmitDataType[]): string` #### 手动反序列化数据 `decoder(jsonString: string): TransmitDataType[]` #### 生成库存查询中间对象 `inventoryEncoder(source: server.Block | server.Entity, slot?: number): object` ### Control 类 #### `subscribe(callback: (data: ControlParameter) => void): BriefLabelType` 注册控制回调。 #### `unsubscribe(briefLabel: BriefLabelType): void` 取消控制回调。 #### `execute(data: ControlParameter): void` 执行所有控制回调。 ## 架构深度解析 ### 通信协议设计 流程图 #### 桥接器初始化与函数注册 流程图 #### 远程函数调用 - 参数发送阶段 流程图 #### 远程函数执行与结果返回 流程图 #### 调用结果接收与处理 流程图 #### 库存编码与解码流程 流程图 #### 关键技术细节说明: 1. **分片机制**:所有超过255字符的数据都会被分片传输,确保脚本事件消息长度限制 2. **哨兵信号**:使用"open_execute"和"done_return"标记开始和结束 3. **对象序列化**:特殊游戏对象通过`__type`字段标记并在解码时重建 4. **异步处理**:使用Promise等待远程函数执行完成 5. **缓存管理**:通过onlyLabel区分不同调用,及时清理缓存防止内存泄漏 6. **错误处理**:超时机制和类型检查确保系统稳定性 7. **切面编程**:控制器在函数执行前后插入自定义逻辑 ### 序列化机制 **Encoder 特殊处理:** ```typescript // 方块: 存储坐标和维度 { __type: 'block', x: 0, y: 64, z: 0, dimension: 'overworld' } // 实体: 存储唯一ID { __type: 'entity', id: '-123' } // 库存: 存储源对象和槽位 { __type: 'inventory', source: { __type: 'block', ... }, slot: 0 } ``` ## 高级用法 ### 1. 函数发现机制 ```typescript // 获取所有可用函数 const [functionList] = await bridge.call("callName", []); const functions = functionList.split(";").filter(Boolean); console.log("可用函数:", functions); ``` ### 2. 自定义序列化 ```typescript // 扩展 Encoder 处理自定义类型 class CustomEncoder extends Encoder { private replacer = (key: string, value: any): any => { if (value instanceof CustomClass) { return { __type: "custom", data: value.serialize() }; } return super.replacer(key, value); }; } ``` ### 3. 批量操作优化 ```typescript // 减少多次调用开销 async function batchOperations() { const batchParams = entities.map((entity) => [entity, destination]); const results = await Promise.all( batchParams.map((params) => bridge.call("teleportEntity", params)), ); return results.flat(); } ``` ## 注意事项 ### 🚨 **性能考量** - **对象验证**: 传输的游戏对象在接收时应验证存在性 - **内存管理**: 及时清理完成的调用缓存 - **频率控制**: 避免高频调用造成性能压力 ### 🔒 **安全实践** ```typescript // 输入验证 bridge.control.subscribe((data) => { if (data.callName === "sensitiveOperation") { const [user, ...params] = bridge.decoder(data.parameter); if (!validateUser(user)) { data.cancel = true; } } }); ``` ### ⚡ **错误处理** ```typescript async function safeCall() { try { const results = await bridge.call("unstableFunction", params); return results[0]; } catch (error) { if (error === "Timeout after 200 tick") { console.error("远程调用超时"); } else { console.error("调用失败:", error); } return null; } } ``` ## 完整示例 ### 分布式权限系统 **权限中心模组:** ```typescript const permissions = new Map(); bridge.release(function checkPermission( player: server.Player, permission: string, ): boolean { const userPerms = permissions.get(player.id) || []; return userPerms.includes(permission) || userPerms.includes("*"); }, "checkPerm"); bridge.release(function grantPermission( player: server.Player, permission: string, ): void { const userPerms = permissions.get(player.id) || []; userPerms.push(permission); permissions.set(player.id, userPerms); }, "grantPerm"); ``` **功能模组:** ```typescript async function executeAdminCommand(player: server.Player, command: string) { const [hasPermission] = await bridge.call("checkPerm", [ player, "admin.command", ]); if (!hasPermission) { player.sendMessage("权限不足"); return; } // 执行管理命令 server.system.executeCommand(command); } // 动态权限授予 await bridge.call("grantPerm", [trustedPlayer, "admin.command"]); ``` ## 故障排除 ### 常见问题 1. **调用超时** - 检查目标函数是否存在 - 验证参数类型是否匹配 - 确认目标模组已加载 2. **对象为 undefined** - 实体可能已卸载/死亡 - 方块可能被破坏 - 维度访问权限问题 3. **内存泄漏** - 及时取消控制器订阅 - 避免在全局作用域重复注册 ## 总结 WorldBridge 为 Minecraft 脚本开发带来了**真正的模块化架构**,通过类型安全的远程过程调用(RPC)机制,让复杂的功能拆分和跨模组协作变得简单可靠。无论是构建大型插件系统、分布式游戏机制,还是简单的模组间数据共享,WorldBridge 都提供了企业级的解决方案。 **核心优势:** - ✅ 类型安全的跨模组调用 - ✅ 完整的游戏对象序列化 - ✅ 可扩展的控制层架构 - ✅ 大数据分片传输支持 - ✅ 异步调用与超时保护 - ✅ 丰富的监控和调试能力 开始使用 WorldBridge,构建更加模块化、可维护的 Minecraft 脚本生态系统! 蹦蹦跳跳的纳西妲