跳转到内容

插件格式(.kgpg)

Kabegame 插件以 .kgpg 文件分发,本质上是一个 ZIP 压缩包,内部包含自描述清单、爬取脚本与可选资源。本页说明格式的心智模型与每类条目的用途;字段的完整定义见 插件清单字段。

文件格式概述

.kgpg 只支持 KGPG v3(固定头部 + ZIP):文件前面是只含 meta 与 icon 的固定头部,用于无需解压或通过 HTTP Range 读取 icon;后面是标准 ZIP body(SFX 兼容)。插件清单由 ZIP 内 package.json 提供——元数据、后端、表单、标签全部内联在这一个文件里(不再有独立的 manifest.json 或 config.json,那是已废弃的 v2 模型)。


ZIP 内部结构

plugin-name.kgpg
├── package.json # v3 自描述清单(必需)
├── dist/main.js / crawl.js # package.json.main 指向的脚本(必需)
├── icon.png # 插件图标源文件(可选;打包后另存于固定头部)
├── configs/*.json # 推荐运行配置预设(可选)
├── providers/*.json5 # PathQL provider DSL(可选)
├── metadata_migrations/
│ └── migrate.js # 图片 metadata 迁移脚本(可选,单文件)
├── doc_root/ # 插件文档目录(可选)
│ ├── doc.md # 默认语言文档(GFM Markdown)
│ ├── doc.<lang>.md # 其它语言,如 doc.zh.md / doc.en.md
│ └── <image> # kbAssets 显式导入的资源(jpg/jpeg/png/gif/webp/bmp)
├── CHANGELOG.md # kbChangelog 默认更新日志(可选)
└── templates/
└── description.ejs # 图片详情页 HTML 模板(可选)

package.json 用 kb* 指针字段声明这些文件的路径(main / kbIcon / kbDoc / kbChangelog / kbAssets / kbRecommendedConfigs / kbPathQLProviders / kbMetadataMigration / kbDescriptionTemplate)。解析器只读清单明确引用的条目,其余文件忽略。

条目必需由哪个字段引用作用
package.json是—v3 自描述清单(name / version / kbBackend / main / kbConfig / engines.kabegame 等)
main 指向的脚本是main爬取脚本;kbBackend 为 v8(自包含 ES module)或 webview(crawl.js)
icon.png否kbIcon插件图标源文件;打包时转换为固定头部内的 RGB 数据
configs/*.json否kbRecommendedConfigs一组推荐预设,供用户一键应用
providers/*.json5否kbPathQLProvidersPathQL provider DSL(后端用,不下发前端)
metadata_migrations/migrate.js否kbMetadataMigration历史图片 metadata 迁移脚本(单文件,见下)
templates/description.ejs否kbDescriptionTemplate图片详情区 HTML 模板;缺失时降级为原始 metadata 列表
doc_root/doc.md·doc.<lang>.md否kbDoc插件文档,多语言按键区分(default / zh / en / ja / ko / zhtw)
CHANGELOG.md·CHANGELOG.<lang>.md否kbChangelog插件更新日志;与 kbDoc 使用相同的多语言映射
<image>否kbAssets文档与更新日志共用的图片资源;数组项是插件根相对路径

所有 kb* 路径和 kbAssets 数组项都做安全校验:必须是包根相对路径,禁越界的 ..、禁绝对路径 / 盘符 / 前导 /。

kbAssets 数组项、kbDoc / kbChangelog Markdown 引用和运行时 assets[].key 共用一个插件根坐标系与同一套归一化规则:标题后缀、query/fragment、前导 / 会被去掉,反斜杠改为 /,百分号按 UTF-8 解码,. / .. 按段折叠且越过插件根时判非法;HTTP(S)、data: 与 // 外链不注册。键大小写敏感。Markdown 所在目录不参与解析,因此 doc_root/doc.md 引用同目录图片时要写 doc_root/images/a.png;Markdown 原文不会被加载器改写。运行时 assets 是 { key, dataBase64 }[],顺序与 kbAssets 声明顺序一致。

Markdown 的每个本地图片引用都必须在 kbAssets 声明;未引用项只警告,允许预留。字段缺失或空数组都表示零资源。

package.json 最小示例

{
"name": "my-plugin",
"version": "1.0.0",
"private": true,
"name.zh": "我的插件",
"description": "插件描述",
"author": "作者名",
"kbPackageVersion": 3,
"engines": { "kabegame": ">=4.3.0" },
"main": "dist/main.js",
"kbBackend": "v8",
"kbBaseUrl": "https://example.com",
"kbConfig": []
}

完整字段(多语言 name/description、kbLabels 4.4.0、kbIcon / kbDoc / kbChangelog / kbAssets 等)见 插件清单字段。

metadata_migrations/migrate.js

单一 metadata 迁移脚本,由 kbMetadataMigration 引用。ES module,可导出 migrate(metadata)(入参与返回值都是 JSON 字符串)、provideLabels(metadata)(给历史图片补标签)与 provideSearchTextList(metadata)(给历史图片提供搜索片段),至少导出一个;运行在裸 V8(无 import、无宿主 API)。搜索片段应覆盖 description.ejs 展示原文,可增加 <插件>_<字段>_<值> 前缀,不收录键名、不可见链接或过期文字。按 metadata 里的 schema 自检、幂等、一步到位;每行无论成败只处理一次。契约与示例见 V8 脚本 · 元数据迁移。

templates/description.ejs

由前端用 EJS 把图片的 metadata 渲染为 HTML 后写入 iframe srcdoc。metadata 来源是爬虫 downloadImage(url, { metadata }) 写入的 metadata 行;模板随插件元数据一起加载到内存,由前端直接消费。

模板渲染时只有一个变量 metadata:

<h3><%= metadata.title %></h3>
<p>作者:<a href="<%= metadata.authorUrl %>"><%= metadata.author %></a></p>

框架在模板内容之前自动注入脚本,提供以下全局能力(无需手写 postMessage):

API说明
window.__bridge.fetch(url, options)跨域 HTTP GET,走宿主 proxy_fetch 绕过浏览器 CORS;options.headers 可传 Referer 等,options.json: true 返回已解析 JSON,否则返回 { base64, contentType }(适合图片字节)。单响应上限约 3 MB。
window.__bridge.getLocale()返回应用当前语言(en / zh / ja / ko / zhtw),用于与远端 API 的 lang 参数对齐。
window.__bridge.openUrl(url)在系统浏览器打开;仅支持 http:// / https://。
<a href="https://..."> / <a data-url="...">自动桥接为 openUrl,点击即在外部浏览器打开。

若插件未提供 description.ejs,或 metadata 为空,详情区回退到原始 k-v 列表显示。


WebView 页面原生下载:Kabegame.onNativeDownload

仅 WebView 后端提供 Kabegame.onNativeDownload(callback): () => void。它用于接收页面自身触发、且无法由插件直接 fetch / downloadImage 的浏览器原生下载终态;V8 后端没有浏览器窗口,不适用此 API。返回值是取消监听函数。WebView 每次导航都会重跑 bootstrap 并重建监听集合,因此插件必须在每页 crawl.js 顶层重新注册。

页面原生下载会落到当前任务 VFS 的 tmp/Downloads/<sha256(url) 前 16 位 hex>-<安全文件名>。路径由 URL 与浏览器建议文件名纯函数生成,同一 URL 重复下载覆盖写入固定位置;Rust 不保存 waiter。下载成功、失败或取消都会触发回调,Requested 阶段分配 VFS 路径失败也会触发失败回调。

payload 字段类型说明
urlstring页面原生下载的原始 URL。
successboolean是否下载成功。
pathstring?仅成功时提供;当前任务 VFS 虚拟路径,可直接传给 Kabegame.downloadImage。
namestring?可取得时提供的下载文件名。
errorstring?失败或取消时提供的可读错误。
// crawl.js 顶层:每次页面导航都会重跑脚本,因此每页都要重新注册。
Kabegame.onNativeDownload((payload) => {
if (!payload.success) {
Kabegame.warn(payload.error || "页面下载失败");
return;
}
void Kabegame.downloadImage(payload.path, {
name: payload.name,
url: payload.url,
});
});

KGPG v3 固定头部规范

固定头部总大小:49216 bytes

区域大小说明
meta64 bytes偏移 0..64;文件魔数、版本、偏移等
icon49152 bytes偏移 64..49216;128×128 RGB24 图像,行优先
ZIP body其余字节从偏移 49216 开始

meta(64 bytes,小端)

字段偏移说明
magic0..44B,固定 "KGPG"
version4..6u16,固定 3
meta_size6..8u16,固定 64
icon_w8..10u16,固定 128
icon_h10..12u16,固定 128
pixel_format12u8,固定 1(RGB24)
flags13u8,bit0: icon_present
保留14..16u16,填 0
zip_offset16..24u64,固定等于 49216
其余24..64保留,填 0

HTTP Range 读取

用途Range
拉取完整头部(meta + icon)bytes=0-49215
仅拉取 iconbytes=64-49215

v3 优势

  1. 无需解压即可取 icon:客户端只需读取固定偏移的数据块。
  2. 支持 HTTP Range:商店列表可只拉取头部,不再依赖额外的 <id>.icon.png 资产。
  3. 保持 ZIP 兼容:插件清单从 ZIP 内 package.json 读取,通用 ZIP 工具也能直接打开。

延伸阅读