插件的发布与索引
打包、GitHub Release 自动更新与 plugins.jsonl 索引
发布包就是插件文件夹
发布包是一个 zip,内容就是插件文件夹:
hello-stellaris-v0.2.0.zip
stl-plugin.json
hello_stellaris.dll
defaults\hello_stellaris.ini
data\… (如有)- 清单可以在 zip 根目录,也可以在其下一层的文件夹里;启动器解压后先找根目录,再找一层子文件夹。
- 必须包含清单和
dll指向的文件。 - 不得包含
config\、logs\(它们属于用户),也不能有任何要放进游戏目录的文件。 - 清单里的
version要与发布版本一致。
玩家可以用三种方式安装:启动器自动更新或从索引安装(推荐);下载解压后在插件页「安装」那个文件夹;或直接解压到 Documents\Paradox Interactive\Stellaris\plugins\<id>\。
用脚本打包:stellaris-mcp 的做法
stellaris-mcp 的 scripts/make_plugin.py 把构建产物组装成插件文件夹,并可选地生成 zip 和校验文件:
python scripts/make_plugin.py --version v0.6.1 --zip build/stellaris-mcp-v0.6.1.zip它做了几件值得照搬的事:
--version接受发布标签vX.Y.Z,写进清单时去掉v,并检查是否符合X.Y.Z格式;- 检查清单的
exe_timestamps是否包含 SDK 生成时对应的 exe 构建,不包含就拒绝打包; - zip 里的文件放在根目录;
- 在 zip 旁边写出
<zip 文件名>.sha256,内容是<十六进制摘要> <文件名>。
GitHub Release 与自动更新
清单里写了 update 的插件,启动器可以从 GitHub 自动更新:
"update": { "github": "Yidhar/stellaris-mcp", "asset": "stellaris-mcp-*.zip" }按启动器 updates.rs 的实现:
- 通过 GitHub API 读取仓库的最新正式发布(
/releases/latest,所以预发布和草稿不会被当作更新); - 标签去掉开头的
v作为版本号,比已安装的version新时才提供更新; - 在附件里找名字匹配
update.asset(默认*.zip)的 zip; - 如果附件里还有
<zip 文件名>.sha256,下载后计算 SHA-256,取校验文件里第一个空白分隔的字段比对,不一致就拒绝安装; - 解压,确认包里清单的
id与已安装的一致,然后原子安装:新版本先在plugins\.<id>.new\准备好,复制进旧的config\与logs\,再改名替换。游戏运行中 DLL 被占用时,替换失败,已安装的版本和设置原封不动。
命令行是 stl plugin update [<id>] [--check]。链接的开发中插件不会被更新。
版本比较规则
- 去掉开头的
v,按点分隔逐段比较数字:0.10.0比0.9.2新,1.0比0.9新; - 缺的段按 0 处理:
0.2.1比0.2新; -或+之后的部分被忽略:0.2.0-rc1与0.2.0视为相同,不会被当作更新。要发预览版,请在 GitHub 上标为预发布。
插件索引 plugins.jsonl
除了逐个仓库检查更新,启动器还能读取插件索引来浏览和安装插件。索引是一个 plugins.jsonl 文件,每行一个 JSON 对象,描述一个插件。官方默认索引是:
https://raw.githubusercontent.com/Yidhar/stellaris-plugins/main/plugins.jsonl其中一行(stellaris-live2d):
{"id":"stellaris-live2d","name":"Live2D portraits","author":"Yidhar","description":"Draws Live2D models into Stellaris' portraits (portrait mods declare them).","version":"0.2.0","download":"https://github.com/Yidhar/stellaris-live2d/releases/download/v0.2.0/stellaris-live2d-v0.2.0.zip","sha256":"a32e9817ac9ffa101a4d207bc7e4b009fc653390c259d4c6ef8182ee86dddc50","repository":"https://github.com/Yidhar/stellaris-live2d","game_builds":["0x6ABEAA3F"],"game_version":"4.5.2","tags":["portraits","live2d","ui"],"license":"MIT","updated":"2026-10-06"}| 字段 | 必填 | 说明 |
|---|---|---|
id、name、author、description、version | 是 | 插件信息;id 必须与 zip 内清单的 id 相同 |
download | 是 | zip 的下载地址,必须以 https:// 开头 |
sha256 | 是 | zip 文件的 SHA-256,十六进制写法,长度必须是 64 |
repository | 是 | 源码仓库地址 |
game_builds | 否 | 适配的 exe 构建时间戳,如 "0x6ABEAA3F";为空表示插件自己检查 |
game_version | 否 | 这些构建对应的游戏版本号,用于提示 |
tags、homepage、license、updated | 否 | 展示信息;homepage 只有以 https:// 开头时才会被用作链接,否则链接到 repository |
不满足必填要求的行会被跳过并计数;一个文件里一行有效的都没有时,整个地址会被判定为“不是插件索引”。
启动器如何使用索引
stl plugin index # 列出正在读取的索引
stl plugin index --add https://example.com/plugins.jsonl
stl plugin index --remove https://example.com/plugins.jsonl
stl plugin index --reset # 恢复为默认索引
stl plugin search live2d # 在所有索引里搜索
stl plugin get stellaris-live2d # 下载、校验并安装--add只接受https://地址,并会先实际读取一次验证。- 多个索引按顺序读取,同一个
id出现在多个索引里时,以第一个索引为准。 get安装时:下载 zip → 计算 SHA-256 并与索引中的值比对(不区分大小写),不一致就拒绝 → 解压找到清单 → 确认清单id与索引一致 → 若该插件是链接的开发版则拒绝 → 按普通安装流程原子安装,保留用户的config\。- 索引里的
game_builds与当前游戏不符时,get只会提示“为其他游戏版本制作”;真正决定是否加载的,仍是启动时对清单exe_timestamps的检查。
两个 SHA-256,别弄混
| 在哪里 | 算的是什么 | 谁检查 |
|---|---|---|
索引行的 sha256 | 发布 zip | stl plugin get 安装时 |
Release 附件 <zip>.sha256 | 发布 zip | 自动更新时(有才检查) |
stl plugin info <id> 显示的 SHA-256 | 已安装的 DLL | 不做校验,供人工核对 |
登记到官方索引
官方索引仓库 Yidhar/stellaris-plugins 不存放任何二进制文件,plugins.jsonl 由 GitHub Actions 每小时自动生成:取每个登记仓库的最新 Release,下载 zip、读出其中的 stl-plugin.json、算出 SHA-256。作者只需登记一次:
- 在自己的公开 GitHub 仓库发一个 Release,附上插件 zip;
- 在索引仓库的
sources.jsonl里加一行并提 Pull Request:
{"repository":"https://github.com/你的用户名/仓库名","tags":["标签1","标签2"]}Release 里有多个 zip 时加 "asset":"名字-v*.zip";作者名默认是仓库所有者,可用 "author" 修改。
- CI 检查你的最新 Release(zip、清单、DLL),合并后一小时内出现在索引里。
此后发新版本只要在自己仓库发 Release,索引会自动跟上;新 Release 无法使用时(例如 zip 里没有清单),索引保留上一个可用版本。可以先用 python scripts/plugin_entry.py <用户名/仓库名> 预览索引会怎么写你的插件。游戏更新后,索引仓库的 games.json 记录新的 exe 时间戳对应的游戏版本号。
索引仓库的规则:源码公开且 DLL 由该源码构建,zip 只能来自 repository 所写仓库的 Release;插件只在启动器加载时运行,不改游戏文件;不收集个人信息、不上传数据(确需联网的在简介里写明用途);一个仓库一个插件 id;plugins.jsonl 不要手改。
关于本站
本站的插件发布与索引订阅(/api/v1/plugins.jsonl 订阅源,以及 stl:// 一键订阅链接)目前尚未实现:后端只有一个用演示数据生成 plugins.jsonl 的原型接口,启动器也还不处理 stl:// 链接。现阶段请使用 GitHub Release + 官方索引的流程。
提示 发布前对照启动器手册的“发布前检查清单”过一遍:标签等于
v+version、附件名匹配update.asset、附带.sha256、是正式发布而非预发布,并实测一次“从上一版本自动更新后设置仍保留”。