• 欢迎加入MineBBS QQ讨论群:点击查看所有的官方讨论群
  • 我们将于近期对服务器进行迁移,服务可能中断至多2日。请各位安排好自己的访问计划,造成不便敬请谅解!
  • MineBBS入站考试已经上线!想要成为【正式会员】解锁更多功能吗?快来参与吧!【点我去看】
DebugShape-Protocol

原生 DebugShape-Protocol 26.10.4

请登录后获取
版权类型
原创
版权链接
#
语言支持
中文(简体)
适配版本(基岩)
  1. 26.x
[MD] # 很遗憾,此插件于此归档,后续将会移动到HologramLib为后续库使用 ## HologramLib为协议层完成的就虚假方块/悬浮字/原生渲染图形框 等服务端渲染内容使用 # DebugShape-Protocol 技术文档 ## 一、项目定位 DebugShape-Protocol 是一个**纯协议层实现**的 Minecraft Bedrock Edition DebugShape 服务端插件。 与传统的 DebugShape 插件不同,本插件**完全自主实现数据包的序列化**,仅借用 BDS 底层的 `NetworkPeer::sendPacket` 通道发送原始字节流,不依赖 BDS 的 `DebugDrawerPacket`、`ShapeDataPayload`、`cereal` 反射系统等任何上层协议封装。 本插件已集成 **MeowPAPI** 静态库,FloatingText 文本支持 `%name%` 和 `{name}` 两种格式的 PAPI 占位符翻译(通过 RemoteCall 调用 MeowSidebar 的 PAPI 中心)。 ### 核心设计准则 > **极致化的优化非必要的跳转,达到性能优化到极致。** - 序列化层:完全自主实现,零 BDS 依赖 - 数据结构:完全自主定义,零 BDS 依赖 - 发送层:仅借用 `NetworkPeer::sendPacket` 原始字节流发送 - 占位符翻译:集成 MeowPAPI 静态库,复用 MeowSidebar 的 PAPI 注册中心 前方案** | ## 二、架构设计 ### 整体架构 ``` ┌─────────────────────────────────────────────────────────┐ │ 应用层 (LSE API) │ │ FloatingTextManager / GradientLineManager / Exporters │ ├─────────────────────────────────────────────────────────┤ │ 占位符翻译层 (MeowPAPI 静态库) │ │ PlaceholderApi → RemoteCall → MeowSidebar PAPI 中心 │ │ (仅 FloatingText 文本路径经过此层) │ ├─────────────────────────────────────────────────────────┤ │ 形状管理层 │ │ PacketDebugRenderer │ │ (ShapeData 持有 ProtoShape) │ ├─────────────────────────────────────────────────────────┤ │ 协议层 (纯自主实现) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │ │ProtocolStream│ │ProtocolShape │ │ProtocolPackets │ │ │ │ (二进制流) │ │ (形状结构) │ │ (包构造+发送) │ │ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ ├─────────────────────────────────────────────────────────┤ │ BDS 底层网络通道 (仅借用) │ │ NetworkPeer::sendPacket() │ └─────────────────────────────────────────────────────────┘ ``` ### 文件结构 ``` src/ ├── ProtocolStream.h # 纯协议层二进制写入流 ├── ProtocolShape.h # 纯协议层形状数据结构 + 序列化 ├── ProtocolPackets.h # 协议层数据包构造与发送声明 ├── ProtocolPackets.cpp # 协议层数据包构造与发送实现 ├── PacketDebugRenderer.h # 形状管理器 ├── PacketDebugRenderer.cpp # 形状管理器实现 ├── FloatingTextManager.h # 悬浮文字管理器 ├── FloatingTextManager.cpp # 悬浮文字管理器实现 (集成 MeowPAPI 翻译) ├── GradientLineManager.h # 渐变线段管理器 ├── GradientLineManager.cpp # 渐变线段管理器实现 ├── RemoteCallExporter.cpp # LSE RemoteCall 导出 (DebugShape 命名空间) ├── FloatingTextExporter.cpp # LSE RemoteCall 导出 (FloatingText 命名空间) ├── GradientLineExporter.cpp # LSE RemoteCall 导出 (GradientLine 命名空间) ├── ModEntry.cpp # 插件入口 (初始化 MeowPAPI 客户端模式) └── MemoryOperators.cpp # 内存操作符 ../MeowPAPI/ # MeowPAPI 静态库 (通过 add_deps 链接) ├── include/meowpapi/ # 公开头文件 │ ├── PlaceholderApi.h # 统一 PAPI 入口 (自动路由服务端/客户端) │ ├── PlaceholderRegistry.h # 占位符注册表核心 │ ├── Builtins.h # 内置原生占位符 │ ├── RemoteCallBridge.h # RemoteCall 桥接层 │ └── BepApiBridge.h # BEPlaceholderAPI 双向兼容层 └── src/ # 实现文件 (随主插件一起编译) ``` ## 三、协议层实现 ### 3.1 ProtocolStream - 二进制写入流 `ProtocolStream` 是完全自主实现的 Minecraft Bedrock 协议二进制写入流,提供基础数据类型的写入能力。 **核心方法:** | 方法 | 说明 | 编码格式 | |------|------|---------| | `writeVarUInt(uint64_t)` | 变长无符号整数 | 7bit + 1bit continuation | | `writeVarInt(int64_t)` | 变长有符号整数 | ZigZag + VarUInt | | `writeFloat(float)` | 单精度浮点 | 4字节小端 | | `writeByte(uint8_t)` | 单字节 | 原始字节 | | `writeString(string)` | 字符串 | VarUInt(长度) + 字节 | | `writeBytes(void*, size_t)` | 原始字节 | 原始字节 | **辅助类型:** - `ProtoVec3` - 三维向量 (x, y, z float) - `ProtoColor` - RGBA 颜色 (4字节) ### 3.2 ProtocolShape - 形状数据结构 #### 形状类型枚举 ```cpp enum class ProtoShapeType : uint8_t { Box = 1, Sphere = 2, Circle = 3, Text = 4, Arrow = 5, }; ``` > **注意:** MC 没有 Line 类型,Line 使用 Arrow 类型实现。 #### 额外数据载荷 (variant) ```cpp using ProtoExtraData = std::variant< ProtoNullPayload, // index 0 - NullType (Sphere/Circle 使用) ProtoArrowPayload, // index 1 - ArrowData ProtoTextPayload, // index 2 - TextData ProtoBoxPayload, // index 3 - BoxData ProtoLinePayload, // index 4 - LineData ProtoSpherePayload // index 5 - SphereData (未使用) >; ``` #### ProtoShape 结构 ```cpp struct ProtoShape { uint64_t mNetworkId; // 网络ID std::optional<ProtoShapeType> mShapeType; // 形状类型 std::optional<ProtoVec3> mLocation; // 位置 std::optional<ProtoVec3> mRotation; // 旋转 std::optional<float> mScale; // 缩放 std::optional<ProtoColor> mColor; // 颜色 std::optional<float> mTimeLeftTotalSec;// 剩余时间 std::optional<int32_t> mDimensionId; // 维度ID (VarInt) std::optional<uint64_t> mAttachedToId; // 附加实体ID ProtoExtraData mExtraData; // 额外数据 }; ``` ### 3.3 序列化格式 #### 完整数据包格式 ``` ┌──────────────────────────────────────────────────────────┐ │ VarUInt(packetId=328) # 包头:数据包ID │ │ VarUInt(shapeCount) # 形状数量 │ │ [Shape] * shapeCount # 形状数据 │ └──────────────────────────────────────────────────────────┘ ``` #### 单个 Shape 序列化格式 ``` ┌──────────────────────────────────────────────────────────┐ │ VarUInt(mNetworkId) # 网络ID │ │ # 注意:无object start│ │ Optional(mShapeType) # 形状类型 │ │ Optional(mLocation) # 位置 │ │ Optional(mRotation) # 旋转 │ │ Optional(mScale) # 缩放 │ │ Optional(mColor) # 颜色 │ │ Optional(mTimeLeftTotalSec) # 剩余时间 │ │ Optional(mDimensionId, VarInt) # 维度ID │ │ Optional(mAttachedToId, VarUInt) # 附加实体ID │ │ VarUInt(variantIndex) # variant索引 │ │ [ExtraData] # 额外数据 │ └──────────────────────────────────────────────────────────┘ ``` #### Optional<T> 编码 ``` absent: 0x00 present: 0x01 + value ``` #### 各类型 ExtraData 编码 | variant index | 类型 | 数据格式 | |---------------|------|---------| | 0 | NullType | 无数据 | | 1 | Arrow | Optional(mEndLocation) + Optional(mArrowHeadLength) + Optional(mArrowHeadRadius) + Optional(mNumSegments) | | 2 | Text | String(mText) | | 3 | Box | Vec3(mBoxBound) | | 4 | Line | Vec3(mEndLocation) | | 5 | Sphere | uint8(mNumSegments) | ### 3.4 ProtocolPackets - 数据包发送 **发送链路:** ``` ProtoShape[] → ProtocolStream 序列化 → std::string 字节流 → ll::service::getNetworkSystem() → getPeerForUser(networkIdentifier) → NetworkPeer::sendPacket(data, ReliableOrdered, Compressible) ``` **发送方法:** | 方法 | 说明 | |------|------| | `sendToPlayer(player, shapes)` | 发送到指定玩家 | | `sendToAll(shapes)` | 发送到所有玩家 | | `sendToDimension(dimId, shapes)` | 发送到指定维度 | ## 四、LSE API 文档 本插件通过 LegacyRemoteCall 导出三个命名空间的 API 供 LSE 脚本调用。 ### 4.1 导入方式 ```javascript // 导入函数 const func = ll.import("命名空间", "函数名"); ``` ### 4.2 DebugShape 命名空间 - 基础形状 API #### 创建形状 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `createText` | (float x, float y, float z, string text) | int64 (shapeId) | 创建文本形状 | | `createLine` | (float x1, float y1, float z1, float x2, float y2, float z2) | int64 | 创建线段(使用 Arrow 类型) | | `createBox` | (float x1, float y1, float z1, float x2, float y2, float z2) | int64 | 创建方块 | | `createCircle` | (float x, float y, float z, float scale) | int64 | 创建圆圈 | | `createSphere` | (float x, float y, float z, float scale) | int64 | 创建球体 | | `createArrow` | (float x1, float y1, float z1, float x2, float y2, float z2) | int64 | 创建箭头 | | `createFilledQuad` | (float x, float y, float z, float width, float height, int plane) | int64 | 创建填充面(plane: 0=XY, 1=XZ, 2=YZ) | | `createFilledQuadBatch` | (float[] positions, float[] colors, float width, float height, int plane) | int64[] | 批量创建填充面 | #### 属性设置 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `setText` | (int64 id, string text) | bool | 设置文本内容 | | `getText` | (int64 id) | string | 获取文本内容 | | `setLocation` | (int64 id, float x, float y, float z) | bool | 设置位置 | | `getLocation` | (int64 id) | float[3] | 获取位置 [x, y, z] | | `setColor` | (int64 id, float r, float g, float b, float a) | bool | 设置颜色 (0.0~1.0) | | `getColor` | (int64 id) | float[4] | 获取颜色 [r, g, b, a] | | `setScale` | (int64 id, float scale) | bool | 设置缩放 | | `setDuration` | (int64 id, float seconds) | bool | 设置持续时间 | | `setRotation` | (int64 id, float pitch, float yaw, float roll) | bool | 设置固定朝向(弧度) | | `clearRotation` | (int64 id) | bool | 清除旋转,恢复 billboard 模式 | | `getRotation` | (int64 id) | float[3] | 获取旋转 [pitch, yaw, roll],billboard 模式返回空数组 | | `getShapeType` | (int64 id) | int | 获取形状类型 | #### 显示控制 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `draw` | (int64 id) | bool | 绘制到所有玩家 | | `drawToPlayer` | (int64 id, string playerName) | bool | 绘制到指定玩家 | | `drawToDimension` | (int64 id, int dimId) | bool | 绘制到指定维度 | | `remove` | (int64 id) | bool | 移除显示(所有玩家) | | `removeToPlayer` | (int64 id, string playerName) | bool | 移除指定玩家的显示 | | `removeToDimension` | (int64 id, int dimId) | bool | 移除指定维度的显示 | | `update` | (int64 id) | bool | 更新显示(属性变更后调用) | | `updateToPlayer` | (int64 id, string playerName) | bool | 更新指定玩家的显示 | | `updateToDimension` | (int64 id, int dimId) | bool | 更新指定维度的显示 | | `drawBatch` | (int64[] ids) | bool | 批量绘制 | #### 生命周期 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `destroy` | (int64 id) | bool | 销毁形状 | | `destroyAll` | () | void | 销毁所有形状 | | `destroyBatch` | (int64[] ids) | bool | 批量销毁 | #### 查询 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `findTextByLocation` | (float x, float y, float z, float radius) | int64[] | 根据位置查找文本形状 | | `findTextByLocationAndContent` | (float x, float y, float z, float radius, string text) | int64 | 根据位置和内容查找 | | `getAllShapeIds` | () | int64[] | 获取所有形状ID | | `exists` | (int64 id) | bool | 检查形状是否存在 | ### 5.3 FloatingText 命名空间 - 悬浮文字 API > **占位符支持**:FloatingText 的所有文本参数(`addLine`、`setLineText`)均支持 PAPI 占位符翻译。 > 文本中的 `%name%` 和 `{name}` 会被 MeowPAPI 自动替换为对应占位符的值(需 MeowSidebar 加载并注册占位符)。 > 同时保留内置变量 `{time}`/`{online}`/`{player}`/`{tps}` 作为兜底,PAPI 未注册时仍可用。 > 详见 [六、MeowPAPI 占位符翻译](#六meowpapi-占位符翻译)。 #### 创建与销毁 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `create` | (float x, float y, float z) | int64 | 创建悬浮文字 | | `destroy` | (int64 id) | bool | 销毁悬浮文字 | | `destroyAll` | () | void | 销毁所有悬浮文字 | #### 行管理 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `addLine` | (int64 id, string text) | bool | 添加一行 | | `setLineText` | (int64 id, int lineIndex, string text) | bool | 设置指定行文本 | | `setLineScale` | (int64 id, int lineIndex, float scale) | bool | 设置指定行缩放 | | `removeLine` | (int64 id, int lineIndex) | bool | 移除指定行 | | `clearLines` | (int64 id) | bool | 清空所有行 | | `getLineCount` | (int64 id) | int | 获取行数 | #### 颜色设置 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `setColor` | (int64 id, float r, float g, float b, float a) | bool | 设置整体颜色 (0.0~1.0) | | `setLineColor` | (int64 id, int lineIndex, float r, float g, float b, float a) | bool | 设置单行纯色 | | `setLineGradient` | (int64 id, int lineIndex, float r1, float g1, float b1, float r2, float g2, float b2) | bool | 设置单行渐变 | | `setLineRainbow` | (int64 id, int lineIndex, float speed) | bool | 设置单行彩虹效果 | #### 动画 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `setLineScroll` | (int64 id, int lineIndex, int direction, float speed) | bool | 设置行滚动 (direction: 0=无, 1=左, 2=右) | | `setVerticalAnimation` | (int64 id, int type, float speed, float range) | bool | 设置垂直动画 (type: 0=无, 1=弹跳, 2=滚动) | | `setLineSpacing` | (int64 id, float spacing) | bool | 设置行间距 | | `setLocation` | (int64 id, float x, float y, float z) | bool | 设置位置 | | `setFollowPlayer` | (int64 id, string playerName, float offsetY) | bool | 跟随玩家 | | `clearFollowPlayer` | (int64 id) | bool | 取消跟随 | | `tick` | (float deltaTime) | void | 更新动画(应在游戏tick中调用) | #### 显示控制 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `draw` | (int64 id) | bool | 绘制到所有玩家 | | `drawToDimension` | (int64 id, int dimId) | bool | 绘制到指定维度 | | `drawToPlayer` | (int64 id, string playerName) | bool | 绘制到指定玩家 | | `remove` | (int64 id) | bool | 移除显示 | | `refresh` | (int64 id) | bool | 刷新显示 | ### 5.4 GradientLine 命名空间 - 渐变线段 API #### 创建与销毁 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `create` | (float x1, float y1, float z1, float x2, float y2, float z2, int segments) | int64 | 创建渐变线段 | | `destroy` | (int64 id) | bool | 销毁线段 | | `destroyAll` | () | void | 销毁所有线段 | #### 属性设置 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `setGradient` | (int64 id, float r1, float g1, float b1, float r2, float g2, float b2) | bool | 设置渐变色 (0.0~1.0) | | `setRainbow` | (int64 id, float speed) | bool | 设置彩虹效果 | | `setColor` | (int64 id, float r, float g, float b, float a) | bool | 设置纯色 | | `setEndpoints` | (int64 id, float x1, float y1, float z1, float x2, float y2, float z2) | bool | 设置端点 | #### 显示控制 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `draw` | (int64 id) | bool | 绘制到所有玩家 | | `drawToDimension` | (int64 id, int dimId) | bool | 绘制到指定维度 | | `remove` | (int64 id) | bool | 移除显示 | #### 动画 | 函数名 | 参数 | 返回值 | 说明 | |--------|------|--------|------| | `tick` | (float deltaTime) | void | 更新动画(应在游戏tick中调用) | ### 4.5 LSE 调用示例 ```javascript // DebugShape 命名空间 const createText = ll.import("DebugShape", "createText"); const createBox = ll.import("DebugShape", "createBox"); const createSphere = ll.import("DebugShape", "createSphere"); const setColor = ll.import("DebugShape", "setColor"); const draw = ll.import("DebugShape", "draw"); const destroy = ll.import("DebugShape", "destroy"); // 创建文本 const textId = createText(100, 64, 0, "Hello World"); draw(textId); // 创建红色方块 const boxId = createBox(100, 64, 0, 102, 66, 2); setColor(boxId, 1.0, 0.0, 0.0, 1.0); draw(boxId); // 创建绿色球体 const sphereId = createSphere(100, 70, 0, 1.0); setColor(sphereId, 0.0, 1.0, 0.0, 1.0); draw(sphereId); // 销毁 destroy(textId); destroy(boxId); destroy(sphereId); // FloatingText 命名空间 const ftCreate = ll.import("FloatingText", "create"); const ftAddLine = ll.import("FloatingText", "addLine"); const ftSetLineColor = ll.import("FloatingText", "setLineColor"); const ftDraw = ll.import("FloatingText", "draw"); const ftDestroy = ll.import("FloatingText", "destroy"); // 创建多行悬浮文字 const ftId = ftCreate(100, 80, 0); ftAddLine(ftId, "第一行"); ftAddLine(ftId, "第二行"); ftSetLineColor(ftId, 0, 1.0, 0.0, 0.0, 1.0); // 第一行红色 ftSetLineColor(ftId, 1, 0.0, 1.0, 0.0, 1.0); // 第二行绿色 ftDraw(ftId); // 销毁 ftDestroy(ftId); // GradientLine 命名空间 const glCreate = ll.import("GradientLine", "create"); const glSetGradient = ll.import("GradientLine", "setGradient"); const glDraw = ll.import("GradientLine", "draw"); const glDestroy = ll.import("GradientLine", "destroy"); // 创建渐变线段 const glId = glCreate(100, 64, 0, 110, 70, 0, 16); glSetGradient(glId, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); // 红到蓝 glDraw(glId); // 销毁 glDestroy(glId); // FloatingText + MeowPAPI 占位符示例 // 需 MeowSidebar 加载以提供完整 PAPI 服务;未加载时 {time}/{online} 等内置变量仍可兜底 const ftId2 = ftCreate(100, 90, 0); ftAddLine(ftId2, "欢迎 %player_name% 来到服务器"); // %name% BEPAPI 格式 ftAddLine(ftId2, "当前在线: {online} 人"); // {name} BetterSidebar 格式 (内置兜底) ftAddLine(ftId2, "时间: {time}"); // 内置兜底变量 ftAddLine(ftId2, "TPS: {%server_tps%} MSPT: {%server_mspt%}"); // MeowSidebar 内置 PAPI ftSetFollowPlayer(ftId2, "Steve", 2.0); // 跟随玩家(提供 Player 上下文) ftDraw(ftId2); ``` ## 五、MeowPAPI 占位符翻译 ### 5.1 集成方式 DebugShape-Protocol 通过 xmake.lua 静态链接 MeowPAPI 静态库: ```lua -- xmake.lua includes("../MeowPAPI/xmake.lua") target("DebugShape-Protocol") add_deps("MeowPAPI") -- 链接静态库 add_includedirs("../MeowPAPI/include") -- 暴露 meowpapi/ 头文件 ``` 插件入口 `ModEntry::enable()` 中初始化为**客户端模式**: ```cpp // ModEntry.cpp #include "meowpapi/PlaceholderApi.h" bool ModEntry::enable() { // 客户端模式:通过 RemoteCall 调用 MeowSidebar 的 PAPI 中心 meowpapi::PlaceholderApi::getInstance().initAsClient(); // ... } ``` ### 5.2 工作原理 ``` FloatingTextManager::processVariables(text, playerName) │ ├─ 1. 通过 Level 查找 Player* (若 followPlayer 非空) │ ├─ 2. meowpapi::PlaceholderApi::translateStringWithPlayer(text, player) │ │ │ ├─ 客户端模式 → RemoteCall 调用 MeowSidebar │ │ ├─ MeowSidebar 本地注册表 │ │ └─ BEPAPI 回退解析器 (若加载) │ │ │ └─ 未注册的占位符保留原样 {%name%} / {{name}} │ └─ 3. 内置变量兜底替换: {time} / {online} / {player} / {tps} (仅当 PAPI 未注册这些占位符时生效) ``` ### 5.3 支持的占位符格式 | 格式 | 示例 | 说明 | |------|------|------| | `%name%` | `%server_name%` | BEPAPI 经典格式,纯占位符名(不含空格/特殊字符) | | `{name}` | `{player_name}` | BetterSidebar 格式,不含冒号或空格 | | `{js:expr}` | `{js:Date.now()}` | **不处理**,保留原样(含冒号) | | `{E:name}` | `{E:money}` | **不处理**,保留原样(含冒号) | ### 5.4 内置兜底变量 以下变量由 FloatingTextManager 自身提供,当 MeowSidebar 未加载或未注册同名占位符时生效: | 变量名 | 格式 | 示例值 | 说明 | |--------|------|--------|------| | `time` | `{time}` | `14:25:36` | 当前本地时间 (HH:MM:SS) | | `online` | `{online}` | `12` | 当前在线玩家数 | | `player` | `{player}` | `Steve` | 玩家名(取自 followPlayer 上下文) | | `tps` | `{tps}` | `20.0` | TPS(简化实现,固定 20.0) | ### 5.5 占位符来源 通过 MeowPAPI 客户端模式可访问的占位符来源: | 来源 | 说明 | |------|------| | **MeowSidebar 内置** | 由 `meowpapi::registerBuiltinPlaceholders()` 注册(MSPT/TPS/时间/玩家等) | | **LSE 插件注册** | LSE 脚本通过 `ll.import("MeowPAPI", "registerPlayerPlaceholder")` 等注册 | | **C++ 插件注册** | 其他 C++ 插件通过 `meowpapi::PlaceholderApi::registerXxxPlaceholder` 注册 | | **BEPAPI 兼容** | 若 MeowSidebar 检测到 BEPAPI 加载,会安装回退解析器访问 BEPAPI 占位符 | ### 5.6 依赖关系 | 依赖 | 类型 | 说明 | |------|------|------| | `MeowPAPI` | 静态库(编译期) | 通过 `add_deps` 链接,随主插件一起编译 | | `MeowSidebar` | 软依赖(运行时) | PAPI 中心,未加载时占位符翻译降级为内置变量兜底 | | `LegacyRemoteCall` | 必需依赖 | MeowPAPI 客户端模式通过 RemoteCall 调用 MeowSidebar | > **注意**:MeowSidebar 未加载时,`isRemoteAvailable()` 返回 false,PAPI 翻译返回原字符串, > FloatingText 的内置变量兜底仍可正常工作,不影响基本功能。 [/MD]
作者
伊希娅
价格
6.00金粒
下载
18
查看
359
首次发布
最后更新

评分

0.00 星 0 次评分

伊希娅 的其他资源

最新更新

  1. 架构更新

    修复浮点坐标的悬浮字会自动变为整数坐标的bug(神秘) 架构更新可看MeowSidebar的更新
  2. 适配Levilamina26.20.1

    上传错版本力,目前已经更新
  3. 适配Levilamina26.20.1

    适配Levilamina26.20.1
后退
顶部 底部