Skip to content

Latest commit

 

History

History
139 lines (106 loc) · 5.94 KB

CONTRIBUTING.md

File metadata and controls

139 lines (106 loc) · 5.94 KB

插件投稿指南

欢迎为 NipaPlay 贡献插件!请遵循以下流程。

前置条件

  • 阅读 JS 插件接口文档,了解可用接口和约束,若您需要的接口未暴露请直接在Issue中说明并提交申请。
  • 确认插件不依赖 Web 平台(当前 JS 插件运行时不支持 Web)。

投稿流程

  1. Fork 本仓库。
  2. 在 plugins/ 下创建子目录,以你的插件 ID 命名,例如 plugins/my.filter/。
  3. 在该目录中编写插件 .js 文件(文件名与目录名保持一致,如 my.filter.js)。
  4. (可选但建议)添加 README.md 说明插件用途。
  5. 提交 Pull Request。

无需手动编辑 plugins.json。 PR 合并后,CI 会自动从插件源文件中读取 pluginManifest 并更新索引。

插件编写规范

必须

  • 插件文件必须是 .js 格式。
  • 必须声明 pluginManifest 对象,且 id、name、version、minHostVersion 为非空字符串。
  • id 必须全局唯一,建议使用 前缀.名称 格式(如 my.filter)。

可选

  • pluginBlockWords — 字符串数组,用于弹幕过滤。
  • pluginUIEntries — 数组,用于在设置页生成功能入口。
  • pluginDanmakuRenderers — 数组,用于声明 Android/iOS WebView 弹幕渲染器。
  • pluginHandleUIAction(actionId) — 函数,处理用户点击事件。
  • pluginOnEvent(event) — 函数,监听应用事件。
  • pluginOnInitialize() — 函数,插件启用时调用。
  • pluginOnDestroy() — 函数,插件禁用时调用。
  • pluginOnResume() — 函数,应用恢复时调用。
  • pluginOnSuspend() — 函数,应用挂起时调用。

权限声明

插件可以通过 permissions 字段声明需要的权限:

const pluginManifest = {
  id: 'my.plugin',
  name: '我的插件',
  version: '1.0.0',
  minHostVersion: '1.11.0',
  description: '描述',
  author: '作者',
  permissions: [
    'player.control',
    'danmaku.modify',
    'ui.dialog'
  ]
};

支持的权限:

权限 ID 说明
player.control 控制播放器(播放/暂停/跳转)
danmaku.modify 修改弹幕显示和过滤规则
danmaku.renderer 声明 WebView 弹幕渲染器
script.external 下载并执行清单中声明的 HTTPS 外部脚本
library.read 读取媒体库信息
library.write 修改媒体库内容
ui.dialog 显示弹窗和提示信息
settings.read 读取应用设置
settings.modify 修改应用设置
storage 使用本地存储
system.override 覆盖系统级设置(如解锁下载器)
url.resolve 解析媒体链接并提供分集与播放地址(需包含该接口的宿主构建)

外部脚本与弹幕渲染器

  • 外部依赖必须声明在 pluginManifest.requires 中,每项使用绝对 HTTPS URL。
  • 发布到市场的外部依赖应固定版本,并填写 64 位 SHA-256;不要引用会变化的分支或 latest 文件。
  • pluginDanmakuRenderers 必须同时申请 danmaku.renderer 和 script.external。
  • 渲染器当前只支持 apiVersion: 1 和 platforms: ['android', 'ios'] 的子集;请勿提前声明 Windows。
  • 声明 supportsRealtimeAdd: true 的渲染器必须处理 add 消息,并立即显示 message.item,不能通过清空整表来实现。
  • 读取 settings.value.rendererSettings 时必须容忍对象或字段缺失,并忽略未知字段;渲染器专属设置不得改变其他渲染器的默认设置行为。
  • 渲染器引用的每个依赖 ID 必须存在于 pluginManifest.requires。
  • 外部代码的来源、许可和再分发条件由投稿者负责确认,并应在插件 README 中说明。

完整字段和消息协议见 JS 插件接口文档。

文件命名

  • 插件 JS 文件名应与插件 ID 一致,如 ID 为 my.filter 则文件名为 my.filter.js。
  • 目录名与插件 ID 一致。

CI 自动同步索引

PR 合并到 main 后,GitHub Actions 会自动运行 同步脚本:

  • 新增插件 — 检测到 plugins/ 下新目录,解析 pluginManifest 并追加到 plugins.json。
  • 更新插件 — 检测到插件文件变更,重新解析并更新对应条目。
  • 删除插件 — 检测到插件目录被移除,从 plugins.json 中删除对应条目。

你只需保证 pluginManifest 声明正确即可,索引维护由 CI 完成。

PR 校验会全量扫描市场插件,并检查:

  • 基础清单字段、插件 ID、目录名和全局唯一性;
  • 权限 ID 是否为宿主已支持的权限;
  • 外部依赖 ID/URL 是否重复、URL 是否为 HTTPS、SHA-256 格式是否正确;
  • 弹幕渲染器权限、ID、API 版本、平台、依赖引用和 bootstrap 是否有效。

plugins.json 索引格式(参考)

以下为 CI 自动生成的索引条目格式,无需手动填写:

{
  "id": "my.filter",
  "name": "我的过滤器",
  "version": "1.0.0",
  "minHostVersion": "1.10.4",
  "description": "简要描述插件功能",
  "author": "你的名字",
  "github": "https://github.com/yourname/yourrepo",
  "file": "plugins/my.filter/my.filter.js"
}

字段来源:

  • id、name、version、minHostVersion、description、author、github— 从插件的 pluginManifest 读取。
  • file — 由 CI 根据文件路径自动填入。

注意事项

  • 插件运行在 flutter_js 沙箱中,通过权限白名单控制可访问的宿主 API。
  • script.external 依赖会进入独立 WebView,不等同于普通 flutter_js 沙箱;请把它视为高权限代码。
  • 返回值格式不正确会导致错误(如 pluginHandleUIAction 的 type 必须为 text)。
  • 请确保屏蔽词和正则表达式经过测试,避免误杀正常弹幕。
  • PR 中请简要说明插件的用途和测试情况。