- 版权类型
- 原创
- 语言支持
- 中文(简体)
- 适配版本(基岩)
- 最新版本
[MD] # MeowLib LeviLamina 虚拟箱子 API - 轻量级原生库,用于实现虚拟容器 UI。 ## 技术实现 本库使用 **协议层直接发送** 数据包,绕过 LeviLamina 的 `RuntimePacket` 包装机制(ID=201),确保客户端正确接收数据包。 ### 协议层发送原理 - 使用 `NetworkPeer::sendPacket()` 直接发送原始二进制数据 - 数据包格式:`[Packet ID (UnsignedVarInt)] + [Packet Body]` - 支持的数据包: - `UpdateBlockPacket` (ID=21) - `ContainerClosePacket` (ID=47) - `InventoryContentPacket` (ID=49) - `InventorySlotPacket` (ID=50) ### 关键修复 **Packet ID 编码问题**:必须使用 `writeUnsignedVarInt` 而非 `writeVarInt`,因为后者使用 ZigZag 编码会导致错误的 packet ID。 - 正确:`writeUnsignedVarInt(50)` → `0x32` - 错误:`writeVarInt(50)` → `0x64` (ZigZag: 50*2=100) ## 许可证 本库基于 **LGPL 3.0** 许可证发布,并附加以下限制: 1. **修改限制**:对本库的任何修改必须在发布前获得原作者 (Ieckseyr) 的批准。未经授权的修改将导致本项目转为闭源许可。 2. **署名要求**:任何使用本库的项目必须明确标注以下贡献者。 - **KobeBryant114514** - 技术指导与支持 - **冰凌ᯤ²ᴳ** - 原型插件启发 - **伊希娅** - 主要项目撰写人 ## 致谢 本项目的实现离不开以下人员的帮助: - **坤佬 (KobeBryant114514)** - 技术指导与支持 - MineBBS: https://www.minebbs.com/members/39046/#resources - GitHub: https://github.com/KobeBryant114514 - **冰凌ᯤ²ᴳ** - 原型插件启发 - MineBBS: https://www.minebbs.com/members/58622/ ## 功能特性 - 无需放置实际方块即可显示虚拟容器 UI - 物品点击事件处理 - 容器关闭事件处理 - RemoteCall API 支持 JavaScript 调用 ## API 参考 ### VirtualBox_API | 函数 | 参数 | 返回值 | 说明 | |------|------|--------|------| | `isInVirtualBox` | `Player*` | `bool` | 检查玩家是否在虚拟箱子中 | | `getBoxName` | `Player*` | `string` | 获取当前箱子名称 | | `getOriginalPos` | `Player*` | `BlockPos` | 获取原始方块位置 | | `getOriginalBlock` | `Player*` | `string` | 获取原始方块类型 | | `registerOpen` | `Player*, boxName, x, y, z, originalBlock, containerId` | `bool` | 注册虚拟箱子打开 | | `registerClose` | `Player*` | `bool` | 关闭虚拟箱子 | | `clearState` | `Player*` | `void` | 清除玩家状态 | | `restoreBlock` | `Player*` | `bool` | 恢复原始方块 | | `setItemActionCallback` | `pluginName, funcName` | `int64` | 注册物品点击回调 | | `removeItemActionCallback` | `id` | `bool` | 移除物品点击回调 | | `setContainerCloseCallback` | `pluginName, funcName` | `int64` | 注册关闭回调 | | `removeContainerCloseCallback` | `id` | `bool` | 移除关闭回调 | | `sendInventorySlotPacket` | `Player*, containerId, slot, item*` | `void` | 发送物品到槽位 (协议层) | ### 回调函数签名 ```cpp // 物品点击回调 void(const std::string& xuid, int actionType, int slot, int containerId) // 容器关闭回调 void(const std::string& xuid) ``` ### 操作类型 | 值 | 类型 | 说明 | |----|------|------| | 0 | Take | 从容器取出物品 | | 1 | Place | 向容器放置物品 | | 2 | Swap | 交换容器与背包物品 | | 3 | Drop | 丢弃物品 | | 4 | Destroy | 销毁物品 | ## 已知问题 ### 光标物品残留 (未解决) 使用 Take (0) 操作时,光标物品可能会在客户端残留。 **尝试解决方案** (均失败): 1. `InventorySlotPacket` (容器 ID 59,槽位 0) - 协议层 2. `InventoryContentPacket` - 协议层 3. 服务端 `mCursorSelectedItemGroup` 清除 **当前状态**:已禁用,等待进一步调查。 ## 环境要求 - LeviLamina 1.9.4+ - LegacyRemoteCall 0.17.2+ ## 使用示例 ### JavaScript 端调用 ```javascript // 注册物品点击回调 ll.import("VirtualBox_API", "setItemActionCallback")("MyPlugin", "onItemClick"); // 打开虚拟箱子 ll.import("VirtualBox_API", "registerOpen")(player, "testBox", 0, 64, 0, "minecraft:air", 1); // 回调处理 function onItemClick(xuid, actionType, slot, containerId) { if (actionType === 2) { // Swap 操作 // 处理物品交换逻辑 } } ``` [/MD]