AI生成

方块盒子开发者平台概览

方块盒子(BlockBox)插件平台是基于 Qt 启动器宿主的扩展系统。插件以 .BlockBox 包分发(本质是 zip 改后缀),包内用 plugin.json 声明元数据、权限、命令与界面,用 PowerShell 脚本或宿主内置原生模块实现业务逻辑。

当前宿主 API 版本:1.0(见 PluginManager::hostApiVersion())。插件可通过 apiVersion / minApiVersion 声明兼容范围。

平台特征

  • 声明式清单:一份 plugin.json 描述 ID、版本、权限、命令、表单、设置与样式贡献
  • 脚本驱动:PowerShell(.ps1,UTF-8 BOM)实现逻辑,无需编译即可运行
  • 内嵌 UI:通过 ui.fields + ui.actions 在插件详情页渲染表单与按钮,输出回显到结果区
  • 安全风控:权限声明 + 脚本危险模式扫描 + 越权检测 + 导入时信任确认
  • 原生扩展:kind: "native" 挂载宿主内置模块,或通过 C++ SDK 加载 DLL
  • 样式贡献:声明 style 后追加到全局 QSS 末尾,停用自动恢复

插件类型

方块盒子目前支持三类扩展形态:

类型 声明方式 实现 适用场景
脚本插件(默认) 省略 kind 或 "kind": "script" scripts/*.ps1 + commands / ui 系统工具、下载、清理、表单型工具
内置原生模块 "kind": "native" + entry: "native://…" 宿主编译界面(如投影编辑器) 3D 编辑器等需要 Qt/OpenGL 的复杂 UI
SDK 原生 DLL "kind": "native" + nativeLibrary C++ 继承 IBlockBoxPlugin 需要本机性能/系统 API 的扩展

另有独立的 AI 技能(.skill / SKILL.md),供 AI 助手调用脚本工具,与插件体系并行,见 AI 技能。

快速开始

推荐路径:启动器「插件 → 制作插件」生成模板,或手工创建如下目录:

my_plugin/
├── plugin.json        # 插件清单(包内必需)
├── README.md          # 说明(可选)
├── scripts/
│   └── main.ps1       # 业务脚本(UTF-8 BOM)
└── assets/
    └── icon.png       # 图标(建议 128×128)

最小可用清单:

{
  "id": "my_plugin",
  "name": "我的插件",
  "version": "1.0.0",
  "author": "Your Name",
  "description": "示例:点击按钮执行脚本",
  "icon": "assets/icon.png",
  "apiVersion": "1.0",
  "category": "工具",
  "permissions": [],
  "commands": [
    {
      "id": "run",
      "label": "执行",
      "kind": "command",
      "target": "run:scripts/main.ps1",
      "risk": "low",
      "riskNote": "仅输出示例文本"
    }
  ]
}

对应脚本 scripts/main.ps1:

# 保存为 UTF-8 with BOM
param([switch]$Silent)

Write-Output "BBSTATUS:正在执行…"
Write-Output "BBPROGRESS:50"
Write-Output "BBRESULT:你好,来自 my_plugin"
Write-Output "BBPROGRESS:100"
Write-Output "BBRESULT:完成"
  1. 将目录压缩为 my_plugin.BlockBox(zip 改后缀)
  2. 在方块盒子「插件页」导入,阅读信任确认后添加
  3. 点击命令按钮,在结果区查看 BBRESULT 输出

安装与生命周期

插件文件存放在启动器可执行文件同级的 BlockBox/ 目录(不存在时自动创建)。状态(启用/禁用、设置值)持久化在 QSettings("BlockBox","Plugins")。

阶段 行为
导入 inspectPluginFile 解析包内清单 → 信任确认 → 复制到插件目录 → refresh()
启用 / 停用 默认启用;停用后命令入口与样式贡献一并隐藏/移除
执行命令 / UI 动作 解包到 %TEMP%/BlockBox/<id>,按扩展名选择解释器执行
更新 清单 updateUrl 指向新 .BlockBox,异步下载替换本地文件
删除 移除包文件与图标缓存;设置项可一并清除

plugin.json 参考

清单为 UTF-8 JSON。必填字段保证插件可被识别;其余字段均可选,用于商店展示、兼容检查与扩展能力。

必填字段

字段 类型 说明
id string 唯一标识:英文、数字、下划线;用于目录名、设置分区、依赖引用
name string 显示名称
version string 语义化版本,如 1.2.0(更新时会与远端比较)

推荐 / 可选字段

字段 类型 说明
author / description string 作者与描述(信任确认弹窗会展示)
icon string 包内图标路径,如 assets/icon.png
entry string 入口:脚本路径、空字符串,或 native://module
kind string script(默认)/ native
nativeLibrary string SDK 原生插件 DLL 相对路径,如 build/sdk_demo.dll
apiVersion / minApiVersion string 适配 / 最低宿主 API 版本;当前宿主为 1.0
homepage / license string 主页与许可证(如 MIT)
tags / category array / string 标签与分类(工具 / 美化 / 功能 / 其他)
updateUrl string 指向新版本 .BlockBox 的下载地址
dependencies array 依赖插件 ID,可带版本要求:"other@>=1.2";依赖须已安装且启用
permissions array 能力权限 token 列表,见 权限系统
settings array 设置项定义,宿主生成「插件设置」表单
commands array 命令/动作列表,见 命令声明
ui object { fields, actions, style? } 内嵌表单与按钮
style string | object 启动器 QSS 贡献;需同时声明 ui:style,见 界面样式定制

完整示例(节选)

{
  "id": "multi_thread_downloader",
  "name": "多线程下载",
  "version": "1.0.1",
  "author": "BlockBox Team",
  "description": "多线程分片加速下载直链文件",
  "icon": "assets/icon.png",
  "entry": "scripts/multi_download.ps1",
  "apiVersion": "1.0",
  "minApiVersion": "1.0",
  "license": "MIT",
  "category": "工具",
  "tags": ["工具", "下载", "加速"],
  "permissions": ["network"],
  "settings": [
    { "key": "defaultThreads", "label": "默认线程数", "type": "number", "default": "8" }
  ],
  "commands": [
    {
      "id": "run",
      "label": "新建下载任务",
      "kind": "command",
      "target": "run:scripts/multi_download.ps1"
    }
  ],
  "ui": {
    "fields": [
      {
        "key": "url",
        "label": "下载链接",
        "type": "text",
        "required": true,
        "placeholder": "http(s)://直链文件地址"
      },
      { "key": "savePath", "label": "保存位置", "type": "path" },
      { "key": "threads", "label": "线程数", "type": "number", "default": "8" }
    ],
    "actions": [
      {
        "id": "run",
        "label": "开始下载",
        "script": "scripts/multi_download.ps1",
        "args": {
          "Silent": "true",
          "Url": "url",
          "SavePath": "savePath",
          "Threads": "threads"
        }
      }
    ]
  }
}

权限系统

插件在清单顶层通过 permissions 声明所需能力。宿主在导入信任确认时展示权限列表与风险说明,并结合脚本扫描做综合风控。

权限 Token 含义 最低风险
file:read 读取方块盒子(启动器)目录文件 低
file:write 修改方块盒子文件/代码(config.ini、资源等) 中
registry 读写 Windows 注册表 中
network 访问网络 低
admin 请求管理员权限(UAC 提权) 高
system 系统级操作(服务、关机、格式化等) 高
ui:style 修改启动器界面样式(仅外观) 低

声明示例

{
  "id": "my_modifier",
  "name": "修改方块盒子",
  "permissions": ["file:read", "file:write", "registry"]
}
最佳实践:只声明真正需要的权限。未声明却执行敏感操作会触发越权检测,综合风险自动升为「高」,用户必须勾选「我已了解风险」才能继续。

命令声明

commands[] 在插件详情页渲染为按钮行。kind 决定点击后的行为:

kind target / 行为 说明
command run:scripts/xxx.ps1 解包后执行包内脚本(按扩展名选解释器)
command 无 run: 前缀 交给系统 shell 执行
script 包内脚本路径 以系统默认方式打开该脚本(查看/编辑)
url 完整 URL 用系统浏览器打开链接
label 标题文本(用 label 字段) 分类标题,独占一行,不执行动作
native native://… 原生插件动作,由宿主界面处理
server-list data/servers.json 内嵌服务器列表(延迟检测、一键加入)

字段说明

字段 必填 说明
id是命令唯一标识
label是按钮/标题显示文本
kind是见上表
target视 kind脚本路径 / URL / 标题等
risk否low / medium / high,默认 medium
riskNote否风险说明,展示在信任确认中

示例:分组命令 + 风险分级

{
  "commands": [
    {
      "id": "lbl_system",
      "label": "🧹 系统垃圾清理",
      "kind": "label",
      "target": ""
    },
    {
      "id": "sys_quick",
      "label": "快速清理(推荐)",
      "kind": "command",
      "target": "run:scripts/sys_quick.ps1",
      "risk": "medium",
      "riskNote": "清理临时文件、预读取缓存、回收站(安全可恢复)"
    },
    {
      "id": "sys_deep",
      "label": "深度清理",
      "kind": "command",
      "target": "run:scripts/sys_deep.ps1",
      "risk": "high",
      "riskNote": "额外清理 Windows 更新缓存、系统日志、缩略图缓存"
    },
    {
      "id": "open_docs",
      "label": "查看文档",
      "kind": "url",
      "target": "https://example.com/docs"
    }
  ]
}

UI 表单字段

声明 ui.fields[] 后,宿主在插件详情卡片下方渲染表单,不再弹出独立 PowerShell 窗口。

type 控件 说明
text单行输入默认类型
path路径输入 + 浏览打开文件/目录选择对话框
number数字输入可配合 min/max 类约束在脚本侧校验
bool复选框值映射为 true / false
select下拉框options 为候选项
time时间输入如 22:30(部分插件已使用)
color颜色选择设置项类型中亦支持

字段属性

属性 说明
key字段键名,供 ui.actions.args 引用
label显示名称
type控件类型,缺省 text
default默认值
placeholder占位提示
required为 true 时,执行前校验非空
optionsselect 选项;支持两种写法(见下)

options 写法:

// 写法 A:纯字符串数组(显示值即提交值)
"options": ["查看", "放置", "破坏", "填充"]

// 写法 B:value|label(提交 value,界面显示 label)
"options": [
  "overworld_to_nether|主世界 → 下界(X、Z ÷ 8)",
  "nether_to_overworld|下界 → 主世界(X、Z × 8)"
]

UI 动作与参数映射

ui.actions[] 渲染为按钮。点击后宿主:

  1. 校验 required 字段
  2. 按 args 组装命令行参数
  3. 解包插件并执行 script 指定的脚本
  4. 捕获 stdout/stderr 显示在结果区

动作字段

字段 说明
id / label标识与按钮文字
script包内相对路径,如 scripts/main.ps1
args映射对象:PowerShell 参数名 → 字段 key 或字面量
risk / riskNote与命令相同的可选风险声明

参数组装规则

宿主按 args 生成 PowerShell 命令行:

  • 字面值 "true" → 开关 -Name
  • 字面值 "false" → -Name:$false
  • 其他值:先取对应字段当前值,再生成 -Name value
// 清单
"args": {
  "Silent": "true",
  "Action": "action",
  "Hours": "hours",
  "Deep": "deep"
}

// 用户选择 action=shutdown, hours=1, deep=false 时,等价执行:
// powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden ^
//   -File scripts\shutdown_timer.ps1 -Silent -Action shutdown -Hours 1 -Deep:$false

脚本侧对应声明:

param(
    [switch]$Silent,
    [string]$Action = '',
    [int]$Hours = 0,
    [switch]$Deep
)
约定:内嵌 UI 动作请始终接受 -Silent,静默模式下用 Write-Output 输出协议行/结果,不要弹 WinForms 窗口,否则与宿主结果区体验冲突。

插件设置

settings[] 与 ui.fields 不同:设置是持久化偏好,由「插件设置」对话框编辑,保存在 QSettings 的 <pluginId>/<key> 下;UI 字段是单次表单输入。

属性 说明
key设置键名
label设置界面显示名
typetext / bool / number / select / color / time
default未保存时的默认值
optionsselect 候选项
{
  "settings": [
    { "key": "defaultProjection", "label": "默认投影文件", "type": "text", "default": "" },
    { "key": "showAir", "label": "默认显示空气方块", "type": "bool", "default": "false" },
    {
      "key": "defaultTool",
      "label": "默认工具",
      "type": "select",
      "default": "查看",
      "options": ["查看", "放置", "破坏", "填充"]
    }
  ]
}

脚本若需读取设置,可在开发阶段通过约定路径或由 UI 动作把设置值映射进 args;宿主 C++ 侧使用 PluginManager::pluginSetting() / setPluginSetting()。

脚本编写指南

编码与启动方式

  • PowerShell 脚本使用 UTF-8 with BOM 编码(避免中文乱码)
  • 宿主启动参数固定为:
    powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File <script> …
  • 按扩展名选择解释器:.ps1 → PowerShell;.bat/.cmd → cmd
  • 包内路径相对于 plugin.json 所在根目录

推荐脚本骨架

# ============================================================
# 示例工具 - BlockBox 插件脚本
# 静默: powershell -NoProfile -ExecutionPolicy Bypass -File main.ps1 -Silent -Name value
# ============================================================
param(
    [switch]$Silent,
    [string]$Name = '',
    [switch]$Deep
)

$ErrorActionPreference = 'Stop'

function Write-BbProgress([int]$Percent) {
    if ($Percent -lt 0) { $Percent = 0 }
    if ($Percent -gt 100) { $Percent = 100 }
    Write-Output "BBPROGRESS:$Percent"
}
function Write-BbStatus([string]$Text) {
    Write-Output "BBSTATUS:$Text"
}
function Write-BbResult([string]$Text) {
    Write-Output "BBRESULT:$Text"
}

try {
    Write-BbStatus "开始执行…"
    Write-BbProgress 10

    # —— 业务逻辑 ——
    Write-BbResult "处理参数 Name=$Name Deep=$Deep"

    Write-BbProgress 100
    Write-BbResult "完成"
    exit 0
}
catch {
    Write-BbResult "错误: $($_.Exception.Message)"
    exit 1
}

交互模式与静默模式

内置工具普遍支持两种模式:无 -Silent 时可弹自研窗体做交互;有 -Silent 时只输出到 stdout,供宿主捕获。

# 交互
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\clean_system.ps1

# 静默(宿主 UI 动作常用)
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\scan_large.ps1 `
  -Silent -Path "D:\" -MinSizeMB 200

进度协议(PluginRunnerDialog)

当脚本在命令执行进度对话框中运行时,可用以下协议行驱动 UI:

协议行 效果
BBPROGRESS:<0-100> 更新进度条(超出范围会被钳制到 0–100)
BBSTATUS:<text> 更新状态标签文案
BBRESULT:<text> 向结果/日志区追加一行
其他普通行 原样追加到详细日志
Write-Output "BBSTATUS:正在清理临时文件"
Write-Output "BBPROGRESS:40"
Write-Output "BBRESULT:已删除 128 个文件"
Write-Output "BBPROGRESS:100"
Write-Output "BBRESULT:清理完成"

内嵌 UI 结果区会直接显示 stdout/stderr 全文;进度对话框会解析上述协议行。两者可同时兼容:始终用 Write-Output 输出协议行即可。

内置插件总览

以下插件源码位于仓库 插件/ 目录,可作为参考实现直接阅读或二次打包。

ID 名称 类型 要点
memory_optimizer内存优化脚本EmptyWorkingSet + DNS 刷新,支持深度多轮
disk_cleaner磁盘清理脚本系统垃圾 / 浏览器缓存 / 大文件 / 重复文件四专项
shutdown_timer定时关机脚本倒计时或指定时间,可关机/重启/取消
multi_thread_downloader多线程下载脚本Range 探测 + 分片并行 + 断点能力降级
github_acceleratorGitHub 加速脚本改 hosts + 刷新 DNS,可一键移除
nether_coords下界坐标转换脚本主世界/下界 8:1 换算,纯表单无弹窗
server_finder服务器浏览器数据server-list 内嵌列表 + 延迟检测
website_nav网站导航数据大量 url 命令分类平铺
world_converter存档互转脚本Java ↔ 基岩(Chunker),需 file:read/write
style_demo样式演示样式演示 style + ui:style
projection_editor投影方块编辑器原生3D 编辑 .litematic,宿主内置界面
sdk_demo / syntax_parserSDK / 语法解析示例SDK 原生DLL + IBlockBoxPlugin

内存优化器 memory_optimizer

遍历进程调用 EmptyWorkingSet 释放工作集,对比优化前后可用内存;可选深度模式多轮清理,并刷新 DNS 缓存。

# UI 字段
"deep": bool  # 深度优化

# 映射到脚本
param([switch]$Silent, [switch]$Deep)
  • 权限:无特殊敏感权限(进程工作集操作)
  • 参考:插件/memory_optimizer/scripts/optimize.ps1

磁盘清理 disk_cleaner

四类专项,命令区用 label 分组:

专项脚本风险
系统垃圾快速/深度清理sys_quick.ps1 / sys_deep.ps1中 / 高
浏览器缓存(Edge/Chrome/Firefox)clean_browser.ps1低
大文件扫描(C/D 盘)scan_large_*.ps1低(只读)
重复文件检测(SHA256)find_dup_*.ps1低(只读)
  • 权限声明:["system"](高风险,导入需勾选确认)
  • 扫描类操作不会删除文件,可在 riskNote 中写明以降低用户顾虑

定时关机 shutdown_timer

表单驱动:操作类型(关机/重启/取消、倒计时或指定时间)、时长、执行时间。

"fields": [
  { "key": "action", "type": "select", "options": [
      "shutdown|多久后关机",
      "restart|多久后重启",
      "shutdownAt|指定时间关机",
      "restartAt|指定时间重启",
      "cancel|取消定时任务"
  ]},
  { "key": "hours", "type": "number" },
  { "key": "minutes", "type": "number" },
  { "key": "atTime", "type": "time", "default": "22:30" }
]

多线程下载 multi_thread_downloader

  • HEAD + Range 探测是否支持断点/分片;不支持则降级单线程
  • 表单:url(必填)、savePath、threads
  • 设置项 defaultThreads 可作为默认线程数
  • 权限建议:["network"]
  • 注意:网盘分享链不是直链,需用户自行获取真实下载地址

GitHub 加速 github_accelerator

修改本地 hosts 添加 GitHub 域名映射,并刷新 DNS;提供「启用加速 / 移除加速」两个 UI 动作(共用同一脚本,用 Remove 参数区分)。

"actions": [
  { "id": "enable",  "label": "启用加速", "script": "scripts/github_accelerate.ps1",
    "args": { "Silent": "true" } },
  { "id": "disable", "label": "移除加速", "script": "scripts/github_accelerate.ps1",
    "args": { "Silent": "true", "Remove": "true" } }
]
  • hosts 修改属敏感操作,导入时可能升为高风险;建议声明 file:write 或 system 并在 riskNote 说明可回滚

下界坐标转换 nether_coords

纯表单工具:选择方向,填 X/Y/Z,点击「转换坐标」在结果区显示。适合学习 select 的 value|label 写法与只读计算类插件(无破坏性操作,risk: "low")。

服务器浏览器 server_finder

{
  "permissions": ["network"],
  "commands": [
    {
      "id": "server_list",
      "label": "服务器列表",
      "kind": "server-list",
      "target": "data/servers.json",
      "risk": "low",
      "riskNote": "访问网络检测服务器状态;加入服务器时使用当前实例启动游戏。"
    }
  ]
}

包内需提供 data/servers.json;宿主并发检测延迟与在线人数,并支持「加入」启动当前实例。

网站导航 website_nav

大量 kind: "url" 命令,配合 label 分类标题平铺展示,点击用系统默认浏览器打开。权限:["network"](或按需省略,若宿主仅外开浏览器)。

存档互转 world_converter

  • 基于 HiveGamesOSS/Chunker(MIT);Java ↔ 基岩双向
  • 权限:["file:read", "file:write"]
  • 命令与动作均建议 risk: "medium" + 提醒用户先备份存档
  • UI 含路径选择、版本 select、多项 bool/开关,是复杂表单的完整范例

投影方块编辑器 projection_editor native

{
  "id": "projection_editor",
  "kind": "native",
  "entry": "native://projection_editor",
  "settings": [
    { "key": "defaultProjection", "type": "text", "label": "默认投影文件" },
    { "key": "showAir", "type": "bool", "label": "默认显示空气方块" },
    { "key": "useTextures", "type": "bool", "label": "启用实例材质" },
    { "key": "sourceInstance", "type": "text", "label": "材质来源实例目录" },
    { "key": "useShapes", "type": "bool", "label": "真实形状渲染(活板门等)" }
  ],
  "commands": [
    {
      "id": "select_projection",
      "label": "选择投影并编辑…",
      "kind": "native",
      "target": "native://select_projection"
    }
  ]
}
  • 宿主提供 SchematicDocument 读写核心;界面在 ProjectionBlockEditorDialog + VoxelViewWidget
  • 停用插件后,投影管理页「编辑投影方块」入口自动隐藏

原生插件开发(内置模块)

当功能必须以 Qt 控件形式嵌入启动器时,使用 kind: "native" 并将 entry 指到宿主已注册的模块:

{
  "id": "my_native",
  "name": "我的原生插件",
  "kind": "native",
  "entry": "native://module_name",
  "apiVersion": "1.0"
}
  • 宿主按 id / entry 映射到内置功能
  • 仍遵循启停生命周期与信任导入流程
  • 通用能力(文件读写、文档模型)放宿主核心;插件专有交互放插件侧

原生插件 SDK(C++ DLL)

头文件位于启动器源码 sdk/:BlockBoxPlugin.h、BlockBoxHostAPI.h、BlockBoxTypes.h。

必须导出的符号

#include "BlockBoxPlugin.h"

class MyPlugin : public IBlockBoxPlugin {
public:
    const char* name() const override { return "My Plugin"; }
    const char* version() const override { return "1.0.0"; }
    const char* author() const override { return "Me"; }
    const char* description() const override { return "示例"; }

    bool initialize(IBlockBoxHostAPI* host) override {
        // 保存 host,注册命令、读设置、连日志
        return true;
    }
    void shutdown() override { /* 释放资源 */ }

    int commandCount() const override { return 1; }
    PluginCommandInfo command(int index) const override { /* … */ }
    bool executeCommand(const char* cmdId, const char** args, int argCount) override {
        // 处理命令
        return true;
    }
};

extern "C" {
    BB_PLUGIN_EXPORT IBlockBoxPlugin* createBlockBoxPlugin() {
        return new MyPlugin();
    }
    BB_PLUGIN_EXPORT void destroyBlockBoxPlugin(IBlockBoxPlugin* p) {
        delete p;
    }
}

清单挂载

{
  "id": "sdk_demo",
  "kind": "native",
  "entry": "native://sdk_demo",
  "nativeLibrary": "build/sdk_demo.dll",
  "permissions": ["file:read"],
  "settings": [ /* … */ ],
  "commands": [
    { "id": "show_info", "label": "查看系统信息", "kind": "native", "risk": "low" }
  ]
}

宿主服务(IBlockBoxHostAPI)

服务能力
ISettingsService读写插件设置(持久化)
ILogService写入启动器日志
IUIService添加操作按钮、通知、状态栏消息
IDownloadService复用宿主下载引擎,支持取消
IPluginService查询其他插件信息
ICoreService启动游戏、获取实例路径等核心能力

界面样式定制

清单顶层声明 style,并请求权限 ui:style。启用时样式追加到全局 QSS 末尾(可覆盖内置主题);停用/删除后自动恢复。

两种写法

// 1) 内联字符串
{
  "id": "my_skin",
  "permissions": ["ui:style"],
  "style": "TopBar { background-color: @PRIMARY@; }"
}

// 2) 对象:内联 + 包内文件叠加
{
  "permissions": ["ui:style"],
  "style": {
    "qss": "/* 可选内联 */",
    "file": "styles/theme.qss"
  }
}

@TOKEN@ 占位符

与主样式相同,随当前主题/主题色解析,常见包括:

  • @PRIMARY@、@PRIMARY_DARK@、@PRIMARY_HOVER@、@PRIMARY_PRESSED@
  • @PRIMARY_GRAD1@、@PRIMARY_LIGHT@、@PRIMARY_LIGHTER@
  • @BG_CARD@、@TEXT_PRIMARY@、@BORDER@
  • @WHITE_RGBA_30@ 等半透明衍生色

示例(摘自 style_demo/styles/theme.qss):

TopBar {
    background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0,
        stop:0 @PRIMARY_DARK@,
        stop:1 @PRIMARY@);
    border-bottom: 2px solid @PRIMARY_PRESSED@;
}

QPushButton#cardPrimaryBtn,
QPushButton#launchGameBtn {
    background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
        stop:0 @PRIMARY_GRAD1@,
        stop:1 @PRIMARY@);
    color: #ffffff;
    font-weight: 700;
}
必须同时声明 "permissions": ["ui:style"],否则视为未声明样式能力。

AI 技能(.skill / SKILL.md)

技能供方块盒子 AI 助手调用,与插件并行存放于 插件/skills/<name>/,包含 YAML front matter 与说明正文。

---
name: 系统信息查询
description: 查询本机系统信息(操作系统、CPU、内存、磁盘、Java 环境)
version: 1.0.0
author: BlockBox Team
permissions:
  - file:read
tools:
  - name: get_system_info
    description: 获取本机系统信息,包括操作系统、CPU、内存、磁盘使用情况。无参数。
    parameters:
      type: object
      properties: {}
      required: []
    script: scripts/get_system_info.ps1
    timeout: 30
---

# 系统信息查询技能

正文说明使用场景与输出含义……
  • tools[].script:技能包内脚本相对路径
  • timeout:秒级超时
  • parameters:JSON Schema 风格参数描述
  • 管理入口:启动器「AI 技能管理」对话框(查看/启停/导入/删除/信任确认)

安全机制详解

核心组件:PluginSafetyGuard + 导入时信任确认。

风险等级

等级含义
低常规只读或几乎无副作用
中可能影响系统/启动器设置(默认)
高可能删除数据、改系统、不可逆

综合风险计算

  1. 取清单声明与脚本扫描的较高者
  2. 声明了敏感权限:升级底线
    (admin/system → 高;file:write/registry → 至少中)
  3. 存在越权(脚本命中敏感操作但未声明对应权限)→ 高

脚本危险模式扫描

对去除注释后的行匹配典型危险模式,例如:

  • Remove-Item、递归删除、格式化卷
  • shutdown、服务控制
  • hosts 修改、注册表写入

扫描在导入前读取包内 ps1/bat/cmd/vbs/js/py/sh 文本汇总完成。

信任确认流程

  1. 展示名称 / 作者 / 版本
  2. 展示请求的能力权限列表(中文说明)
  3. 展示综合风险等级、riskNote、扫描发现
  4. 越权则明确警告并升为高风险
  5. 高风险(或 admin/system)必须勾选「我已了解风险…」才能导入
  6. 批量导入可「全部信任(仅低/中)」或「逐个确认」
信任时机:信任确认在添加/导入插件时进行一次;常规动作执行阶段不再重复弹窗(信任已建立)。请在 riskNote 中诚实描述副作用。

宿主 API 与脚本约定

宿主侧 C++ API(摘要)

组件职责
PluginManager扫描/导入/导出/解包、启停、依赖与 API 兼容、设置读写、样式收集、异步更新、模板与打包
PluginInfo清单数据结构(见源码字段注释)
PluginSafetyGuard风险解析、脚本扫描、越权检测、信任弹窗
PluginZip目录 ↔ .BlockBox 压缩
NativePluginLoader加载 SDK DLL
PluginRunnerDialog解析 BB* 协议行的执行进度 UI
CreatePluginDialog制作插件:生成模板并一键打包
PluginSettingsDialog按 settings 动态表单并持久化

脚本侧常用 PowerShell 能力

# 路径与文件
Test-Path $path
Get-ChildItem $path -Recurse
Get-Content / Set-Content / Remove-Item

# 网络
Invoke-WebRequest -Uri $url -OutFile $dest
Start-BitsTransfer -Source $url -Destination $dest

# 系统
Get-CimInstance Win32_OperatingSystem
shutdown.exe /s /t $seconds
ipconfig /flushdns

# 进度输出
Write-Output "BBPROGRESS:42"
Write-Output "BBSTATUS:处理中"
Write-Output "BBRESULT:已完成一项"

插件打包与更新

包格式

  • 扩展名:.BlockBox
  • 内容:标准 zip(根目录含 plugin.json)
  • 安装目录:启动器旁 BlockBox/<id>.BlockBox

打包方式

  1. 启动器内:「插件 → 制作插件」→ 生成模板或选择目录 →「打包为 BlockBox 文件」
  2. PowerShell:
# 在插件源码根目录执行
Compress-Archive -Path .\* -DestinationPath .\my_plugin.zip -Force
Move-Item .\my_plugin.zip .\my_plugin.BlockBox -Force

# 或显式列出
Compress-Archive -Path .\plugin.json, .\scripts, .\assets, .\styles `
  -DestinationPath .\my_plugin.zip -Force
Rename-Item .\my_plugin.zip my_plugin.BlockBox
  1. 批量脚本:仓库中可使用类似 pack_plugins.py 的脚本遍历 插件/*/ 打包到 packaged/

在线更新

  • 清单填写 updateUrl → 指向新版本 .BlockBox 的直链
  • 宿主 updatePluginAsync 下载后校验版本更高再替换
  • 结果通过 pluginUpdateFinished(id, success, error) 信号返回

依赖与 API 兼容

  • dependencies:缺失或未启用的依赖会阻止正常使用
  • minApiVersion:高于当前宿主 1.0 则判定不兼容
  • 版本比较为语义化比较;非法版本按 0 处理

项目模板

调用 PluginManager::createTemplate() 或 UI「制作插件」会生成:

<id>/
├── plugin.json     # 含示例 settings、扩展元数据字段
├── main.js         # 入口示例(onEnable/onDisable 钩子注释)
├── README.md       # 打包说明
└── assets/
    └── icon.png    # 128×128 默认图标(首字母)

生成后修改为 scripts/*.ps1 + commands/ui,再用「打包为 BlockBox 文件」输出到插件目录并自动刷新列表。

故障排查

现象排查
导入失败 / 清单损坏 校验 JSON 语法;根目录必须有 plugin.json;必填 id/name/version
中文乱码 .ps1 保存为 UTF-8 with BOM
按钮无反应 / 找不到脚本 target 是否为 run:scripts/...;路径大小写与包内一致
UI 动作参数未传入 args 值是否指向 fields[].key;脚本 param() 名称是否与 args 键一致
结果区空白 是否用了 Write-Output;是否误弹窗且 -Silent 分支未实现
信任确认判为高风险 补全 permissions;为只读命令标注 risk: "low" + 说明;避免注释外的敏感命令误用
越权警告 脚本行为与 permissions 对齐(写文件→file:write,改 hosts→system 等)
样式不生效 是否声明 ui:style;插件是否启用;选择器/objectName 是否匹配当前主题控件
原生插件不出现 kind 是否为 native;宿主是否注册对应 entry;DLL 位数与 Qt 构建是否一致
更新失败 updateUrl 是否直链 zip;新版本 version 是否更高
插件列表不刷新 文件是否在启动器旁 BlockBox/;手动触发刷新或重启启动器

术语表

术语说明
宿主 / Host方块盒子启动器本体(Qt 应用)
.BlockBox插件分发包(zip 改后缀)
plugin.json插件清单
commands详情页命令按钮声明
ui.fields / ui.actions内嵌表单与动作按钮
settings持久化插件设置
style对启动器全局 QSS 的贡献
kind: native原生/内置模块型插件
BBPROGRESS / BBSTATUS / BBRESULT脚本输出协议行
run: 前缀命令 target 表示执行包内脚本
信任确认导入插件时的「你信任该插件吗?」流程
越权脚本做了敏感操作但未声明对应权限
文档来源:本页内容与仓库实现对齐(C-BlockBox/utils/plugin/*、sdk/*、插件/*/plugin.json、插件/README.md)。实现演进时请同步更新本页与源码注释。