- 🌟 原神 (Genshin Impact)
- ⭐ 崩坏:星穹铁道 (Honkai: Star Rail)
- 🔥 绝区零 (Zenless Zone Zero)
- ⚡ 崩坏 3 (Honkai Impact 3rd)
- 🌊 鸣潮 (Wuthering Waves)
- 🧪 明日方舟:终末地 (Arknights: Endfield) —— 实验性支持
- 📱 版本监控 - 实时检测游戏版本更新
- 🔔 自动推送 - 版本更新及预下载通知
- 🖼️ 图文推送 - 支持图片(可选模板)与纯文字两种推送形式
- 📥 下载链接 - 获取正式版 / 预下载的客户端、资源包直链
- 📊 历史数据 - 记录各版本包体与更新包大小,可随时查询
- ⚙️ 灵活配置 - 每个游戏独立配置推送开关、频率与推送群
- 🕐 定时任务 - 自动定时检查更新
- 💾 混合存储 - Redis 保存当前版本状态,内置 SQLite 保存历史版本数据
- 🎛️ 多端可视化配置 - Guoba、Karin-Web、Yunzai-NG 三套配置界面
- 🔘 快捷按钮 -
当前版本回复自动附带命令按钮 - 🧩 六框架同源 - Miao-Yunzai / TRSS-Yunzai / MangoCat-Yunzai / JiuLi / Karin / Yunzai-NG 共用一套业务代码,框架差异全部收敛在
lib/runtime/
- ✅ 任选其一:Miao-Yunzai、TRSS-Yunzai、MangoCat-Yunzai、JiuLi(玖璃)、Karin、Yunzai-NG
- ✅ Node.js 22.15+(依赖内置
node:sqlite,无需编译better-sqlite3) - ✅ Redis 数据库(Yunzai-NG 下由内核提供 KV,无需单独部署)
- 克隆插件
# Miao-Yunzai / TRSS-Yunzai / MangoCat-Yunzai / JiuLi / Yunzai-NG —— 目录名保持 GamePush-Plugin
## GitCode
git clone https://gitcode.com/rainbowwarmth/GamePush-Plugin.git ./plugins/GamePush-Plugin
## Gitee
git clone https://gitee.com/rainbowwarmth/GamePush-Plugin.git ./plugins/GamePush-Plugin
## CNB
git clone https://cnb.cool/rainbowwarmth/GamePush-Plugin.git ./plugins/GamePush-Plugin
## GitHub
git clone https://github.com/rainbowwarmth/GamePush-Plugin.git ./plugins/GamePush-Plugin
# Karin —— 目录名必须包含 karin
## GitCode
git clone https://gitcode.com/rainbowwarmth/GamePush-Plugin.git ./plugins/karin-plugin-gamepush
## Gitee
git clone https://gitee.com/rainbowwarmth/GamePush-Plugin.git ./plugins/karin-plugin-gamepush
## CNB
git clone https://cnb.cool/rainbowwarmth/GamePush-Plugin.git ./plugins/karin-plugin-gamepush
## GitHub
git clone https://github.com/rainbowwarmth/GamePush-Plugin.git ./plugins/karin-plugin-gamepush
⚠️ 目录名决定框架判定:目录名包含karin→ 按 Karin 加载;否则按宿主package.json的name区分miao-yunzai/trss-yunzai/MangoCat-Yunzai/jiuli/yunzai-ng。请勿随意改名。
- 安装依赖
pnpm install -P💡
@yunzai-ng/core不需要在插件里安装 —— 它由 Yunzai-NG 内核提供,插件从宿主node_modules解析。仅在 NG 下才会被导入,其余框架不会触碰该依赖。
- 启动机器人
# 重启对应的机器人框架即可自动加载插件首次加载时插件会自动从远端拉取游戏版本数据库(GamePush-Plugin.db),并在后续启动时按版本号增量更新。
拉取新版本后,请重启机器人,不要依赖热重载。
⚠️ Yunzai-NG 尤其注意:它的热重载只给入口文件加缓存戳(index.js?yzngReload=N), 嵌套模块(model/、lib/下的文件)仍复用更新前的实例。 插件更新一旦改动了内部模块结构(新增导出、删除文件),重载就会得到「新旧混合」的模块图而失败。 插件已内置检测,遇到这种情况会明确提示「热重载后的模块图不完整……请重启 yunzai-ng」, 但重启始终是可靠做法。
| 命令 | 功能 | 权限 | 特别说明 |
|---|---|---|---|
#[游戏]版本监控 |
手动触发一次版本检查 | Master | |
#[游戏]开启版本推送 |
将当前群加入推送列表 | Master | 仅限群聊 |
#[游戏]关闭版本推送 |
将当前群移出推送列表 | Master | 仅限群聊 |
#[游戏]当前版本 |
查看正式版本与预下载版本 | 所有用户 | 回复附带快捷按钮 |
#[游戏]版本数据 |
查看历史版本更新包大小列表 | 所有用户 | |
#[游戏]版本数据 [版本号] |
查看指定版本的详细数据 | 所有用户 | |
#[游戏]获取下载链接 |
获取当前正式版本下载链接 | 所有用户 | 原神、崩坏 3 不支持获取 |
#[游戏]获取预下载链接 |
获取当前预下载版本链接 | 所有用户 | 原神、崩坏 3 不支持获取 |
命令前的
#可省略或重复(#原神当前版本、原神当前版本均可)。
- 🌟 原神:
#原神/#ys/#YS - ⭐ 崩坏:星穹铁道:
*/#星铁/#崩铁/#星穹/#星轨/#穹轨/#铁道/#星穹铁道/#崩坏星穹铁道 - 🔥 绝区零:
%/%/#绝区零/#绝区/#zzz/#ZZZ - ⚡ 崩坏 3:
!/!/#崩坏3/#崩坏三/#崩三/#崩3/#三崩子/#bbb - 🌊 鸣潮:
~/~/#鸣潮/#ww/#WW/#mc - 🏜️ 终末地:
:/:/#终末地/#zmd
📌 原神的前缀可以省略:
#当前版本、#版本数据、#版本监控等不带游戏名的命令默认作用于原神。
⚠️ 别名区分大小写(#Zzz、#Ww不匹配);星铁与崩坏 3 没有sr/SR/bh3/BH3英文别名。
| 命令 | 功能 | 权限 |
|---|---|---|
#[游戏]删除rediskey |
删除游戏 Redis 键值 | Master |
#[游戏]删除预下载rediskey |
删除预下载 Redis 键值 | Master |
#[游戏]设置rediskey 版本 |
设置游戏 Redis 键值 | Master |
#[游戏]设置预下载rediskey 版本 |
设置游戏预下载 Redis 键值 | Master |
#更新游戏版本数据 |
稳定版,拉取远程稳定库并合并(保留本地记录) | Master |
#更新游戏版本数据稳定版 |
同上一行为,显式写法 | Master |
#更新游戏版本数据发行版 |
发行版,扫描本地 resources 目录,按游戏补齐缺失记录 |
Master |
管理命令的游戏前缀同样可省略,省略时默认作用于原神。
稳定版 vs 发行版
| 稳定版 | 发行版 | |
|---|---|---|
| 数据来源 | 远程稳定库(随官方节奏发布) | 本地 resources/<游戏>/main|pre/<版本号>.json |
| 是否联网 | 是 | 否,纯离线 |
| 写入方式 | INSERT OR IGNORE 合并 |
INSERT OR IGNORE 补齐 |
| 适用场景 | 获取经过验证的全量历史 | 用插件自带的较新快照补齐,或离线环境 |
两个命令都只增不改,已有记录不会被覆盖,可反复执行。
插件采用混合存储:当前版本状态存放在 Redis / 内核 KV,历史版本包体数据存放在内置 SQLite(node:sqlite,无需安装 better-sqlite3)。
数据库文件名恒为 GamePush-Plugin.db(取插件 package.json 的 name,不随目录名变化),存放目录随框架而变:
| 框架 | 数据库路径 |
|---|---|
| Miao-Yunzai / TRSS-Yunzai / MangoCat-Yunzai | data/GamePush-Plugin.db |
| JiuLi | data/plugins/GamePush-Plugin/GamePush-Plugin.db |
| Karin | @karinjs/karin-plugin-gamepush/data/GamePush-Plugin.db |
| Yunzai-NG | data/plugin/GamePush-Plugin/sql/GamePush-Plugin.db |
- 首次启动时会从远程拉取版本历史数据作为初始数据,失败仅告警并回退到本地库。
#更新游戏版本数据/#更新游戏版本数据稳定版采用INSERT OR IGNORE合并而非覆盖,本地记录不会丢失。- 使用 Yunzai-NG 时,插件在自己的
data/plugin/GamePush-Plugin/sql/下维护数据库,并在首次启动时只读导入原内核目录data/sql/GamePush-Plugin/中的历史数据;原数据库不会被删除或修改。
发行版命令会从两个起点向下探测,凡是直接包含「已知游戏(ys/sr/zzz/bh3/ww/zmd)的 main 或 pre 子目录」的目录,都会被当作数据根:
- 框架根目录
resources/ - 插件目录
resources/
之所以要向下探测而不是只扫起点:数据通常由独立的资源仓库维护,例如
D:/Desktop/Yunzai/resources/resources/ ← clone 的资源仓库(cnb: rainbowwarmth/resources)
└─ GamePush-Plugin/
├─ GamePush-Plugin.db ← 稳定版数据
└─ ys/ sr/ zzz/ bh3/ ww/ zmd/ ← 发行版数据(本命令读取)
├─ main/7.1.0.json
└─ pre/7.1.0.json
探测深度上限 4 层,遇到 .git / node_modules 等目录跳过;非已知游戏名的目录(如其他插件的 json/、http/)一律忽略。
每个 json 的内容(游戏名与版本号来自目录/文件名):
version缺省时取文件名;size必填;time缺省时回落文件修改时间。pre记录缺少oldver会被跳过(表定义中该列NOT NULL)。- 名称不以
.json结尾的文件一律忽略。
资源仓库内提供 scripts/ 与 .github/workflows/,由 GitHub Actions 定时驱动(也可本地手动执行):
| 脚本 | 作用 |
|---|---|
scripts/seed-from-db.mjs |
首次部署:把 GamePush-Plugin.db 按 gameid 拆分,铺成 <游戏>/main|pre/<版本号>.json |
scripts/update-versions.mjs |
增量采集:请求各家官方接口,把新版本写进数据目录(已存在的跳过) |
node scripts/seed-from-db.mjs --db=GamePush-Plugin/GamePush-Plugin.db # 导出种子
node scripts/update-versions.mjs # 全量采集 6 款游戏
node scripts/update-versions.mjs --game=ys # 只采集指定游戏
node scripts/update-versions.mjs --dry-run # 只打印,不落盘GitHub Actions 定时采集:.github/workflows/update-versions.yml,单 job 一次并发采集全部 6 款游戏,每 5 分钟一轮、覆盖北京时间 03:00–23:59。
on:
schedule:
- cron: "*/5 0-15,19-23 * * *" # GitHub cron 一律 UTC,= 北京时间 - 8h| 事项 | 说明 |
|---|---|
| 时区 | GitHub 的 cron 一律是 UTC。北京 03:00–23:59 换算后 = UTC 19:00–23:55(前一日)+ 00:00–15:55,故写作 0-15,19-23 |
| 延迟 | schedule 不保证准点,高峰期常延迟 5–30 分钟,做不到分钟级精确 |
| 免费额度 | 公开仓库免费且不限分钟数;私有仓库每月仅 2000 分钟,本频率约需 3800 分钟,仓库必须保持 public |
| 60 天停用 | 公开仓库连续 60 天无提交活动,schedule 会被自动停用(可在 Actions 页手动唤醒) |
| 分支 | schedule 只在默认分支上生效 |
| 权限 | 需要 permissions: contents: write 才能把采集结果提交回仓库 |
| 自触发 | 用默认 GITHUB_TOKEN 提交不会再次触发 workflow,天然避免死循环 |
脚本内部按游戏隔离 try/catch:某家接口超时只记日志,其余游戏照常写入并在同一次提交里推上去;本轮没采到的,5 分钟后下一轮自己会补上。
为什么不用 CNB 云原生构建:其免费额度仅 160 核时/月(核时 = 核数 × 运行时长),且每个 job 都要独立启动构建环境,5 分钟一轮、多 job 会明显超额。GitHub Actions 对公开仓库完全免费,故定时采集放在这里。
采集脚本在插件仓库
scripts/下同样保留一份,便于本地生成/校验数据。
| 框架 | 配置文件 |
|---|---|
| Miao-Yunzai / TRSS-Yunzai / MangoCat-Yunzai | data/GamePush-Plugin.yaml |
| JiuLi | data/plugins/GamePush-Plugin/GamePush-Plugin.yaml |
| Karin | @karinjs/karin-plugin-gamepush/config/GamePush-Plugin.yaml |
| Yunzai-NG | config/GamePush-Plugin.yaml(由内核托管,面板可视化编辑) |
插件支持三套可视化配置界面,按框架自动选用:
| 框架 | 配置方式 |
|---|---|
| Miao-Yunzai / TRSS-Yunzai / MangoCat-Yunzai / JiuLi | Guoba-Plugin(guoba.support.js) |
| Karin | Karin-Web(web.config.js) |
| Yunzai-NG | 内核配置界面(schema 由 lib/runtime/panels/yunzai-ng.js 生成) |
📌 三个根文件(
guoba.support.js/web.config.js/ NG 的configSchema)都只是薄暴露,真正的 schema 与面板实现统一下放在兼容层lib/runtime/panels/。
可配置项:
- 🎛️ 推送开关 / 日志开关
- ⏰ 定时任务 cron 表达式(默认
0 */5 3-23 * * ?—— 每天 3:00–23:55 每 5 分钟一次) - 👥 推送的「机器人 + 群」列表
- 🖼️ 消息类型(图片 / 文字)与 html 模板(默认 / 简约)
GamePush-Plugin/
├── 📁 apps/ # 插件类集合(云崽系 loader 展开 apps 字段;Karin 递归加载本目录)
│ ├── 🎮 games.js # 6 个游戏插件类(ys/sr/zzz/bh3/ww/zmd,逐个具名导出)
│ ├── ⚙️ set.js # 设置管理
│ └── 📋 task.js # 独立定时任务(Karin 用薄壳)
├── 📁 components/ # 组件模块(路径、配置、请求)
├── 📁 lib/ # 工具库
│ ├── api.js / common.js / plugin.js / puppeteer.js / redis.js / segment.js
│ │ # 兼容垫片:转发到 rt,业务侧仍按旧路径导入
│ └── 📁 runtime/ # ★ 框架兼容层(六框架差异全部收敛在此)
│ ├── index.js # 运行时单例 rt + 适配器装配
│ ├── detect.js # 框架探测(目录名 / 宿主 package.json)
│ ├── contract.js # 适配器契约校验
│ ├── define.js # 插件自有 DSL:defineCommand / defineTask / defineApp
│ ├── lifecycle.js # 卸载钩子与资源交接(JiuLi 热重载)
│ ├── sqlite-db.js # node:sqlite 历史数据存储
│ ├── buttons.js # 各框架按钮结构互转
│ ├── 📁 adapters/ # 六个适配器
│ │ ├── yunzai-base.js # 云崽系基座(Miao/TRSS/MangoCat/JiuLi 复用)
│ │ ├── yunzai.js # Miao-Yunzai / TRSS-Yunzai
│ │ ├── mangocat.js # MangoCat-Yunzai
│ │ ├── jiuli.js # JiuLi(玖璃)
│ │ ├── karin.js # Karin
│ │ └── yunzai-ng.js # Yunzai-NG
│ ├── 📁 panels/ # 前端配置面板(schema 与渲染器)
│ │ ├── schema.js # 框架无关的统一 schema
│ │ ├── guoba.js # Guoba 渲染
│ │ ├── karin-web.js # Karin-Web 渲染
│ │ └── yunzai-ng.js # Yunzai-NG 渲染
│ └── 📁 registry/ # 注册层:把 app 定义翻译成各框架的注册语法
│ ├── app-base.js # 插件基类(继承宿主 Base + 绑定命令 handler)
│ ├── apps.js # prepareApp(云崽系 / Karin)
│ ├── ng.js # definePlugin(Yunzai-NG)
│ └── tasks.js # 独立任务导出(Karin)
├── 📁 model/ # 数据模型与命令实现(框架无关)
│ ├── games.js # ★ 各游戏接口描述符:端点 / 请求方式 / 响应归一化
│ ├── util.js # 游戏元数据与纯工具(无网络、无兼容层依赖)
│ ├── api.js # 版本检查编排(比对 Redis → 触发推送)
│ ├── notice.js # 推送编排(文案模板 / 图片 / 文本)
│ ├── download.js # 下载数据编排(带缓存)+ 文案格式化
│ ├── base.js # 截图数据组装、图标内联
│ ├── commands.js # 命令定义
│ ├── tasks.js # 定时任务定义
│ └── index.js # 模型层出口
├── 📁 resources/ # 资源文件
├── 🔧 index.js # 入口:按框架分发到注册层
├── 🎛️ guoba.support.js # Guoba 暴露点(薄壳,转发兼容层)
├── 🎛️ web.config.js # Karin-Web 暴露点(薄壳,转发兼容层)
└── 📦 package.json # 项目配置(含 #GamePush.* 子路径导入映射)
- 框架: Miao-Yunzai、TRSS-Yunzai、MangoCat-Yunzai、JiuLi(玖璃)、Karin、Yunzai-NG
- 语言: JavaScript (ES6+ / ESM)
- 数据库: Redis(版本状态)+ Node 内置
node:sqlite(版本历史,无需安装better-sqlite3) - 任务调度: Cron
- 配置管理: Guoba / Karin-Web / Yunzai-NG schema(统一 schema,多渲染器)
所有框架差异收敛在 lib/runtime/,业务代码只依赖统一的 rt 对象:
- 框架探测(
detect.js)——按有序规则表识别:目录名含karin→ Karin;否则按宿主package.json的name匹配yunzai-ng/MangoCat-Yunzai/jiuli/miao-yunzai/trss-yunzai;全部落空但存在云崽全局时按未知云崽分支告警处理。 - 适配器契约(
contract.js)——适配器必须提供kv、db、dataDir、pluginRoot、segment、sendGroupMsg、makeForward、render、normalizeEvent、commandButtons、capabilities等接口,缺一即启动报错。 - 插件自有 DSL(
define.js)——业务侧用defineCommand/defineTask/defineApp声明「有哪些命令、什么频率」,不写rule:/ctx.command/karin.task。 - 注册层(
registry/)——把 app 定义翻译成各框架的注册语法:云崽系 / Karin 走prepareApp生成插件类选项,Yunzai-NG 走definePlugin+ctx.command/ctx.cron。 - 面板兼容层(
panels/)——一份框架无关的schema.js,加 Guoba / Karin-Web / Yunzai-NG 三个渲染器;根目录的guoba.support.js、web.config.js只是框架要求的固定暴露路径,内容转发到兼容层。 - 生命周期(
lifecycle.js)——统一登记模块级资源(SQLite 句柄、chokidar watcher),并在 JiuLi 热重载时通过globalThis交接旧模块图的资源,避免句柄泄漏。
➕ 新增框架:在
lib/runtime/adapters/补一个适配器文件 + 在detect.js规则表加一条匹配规则即可,apps/与model/业务逻辑零改动。
业务侧按「游戏」而不是「接口」来组织 —— 厂商差异全部收敛在 model/games.js:
games.js(接口描述符) —— 一个游戏一处,对外只暴露四个归一化能力:fetchVersion(game)→{ main, pre }、fetchPackages(game, type)→{ data, patch }、fetchSize(game, type)→{ formattedTotalSize, incrementalSize, Ver }、icon(game)。 三个厂商(米哈游mhy/ 库洛ww/ 鹰角zmd)各一个描述符,由GAME_CONFIG[game].api路由。api.js/download.js/notice.js(编排层) —— 只做「取归一化数据 → 比对 → 推送 → 回写」, 不再出现if (game === "zmd")这类分支。util.js(叶子层) —— 只有静态元数据与纯函数(formatSize、versionComparator等), 不依赖兼容层、不发请求,避免与components/config.js形成循环。
➕ 新增游戏:在
GAME_CONFIG加一条元数据、在games.js加一个描述符(若属已有厂商则直接复用), 编排层无需改动。
- 🧩 运行时抽象层 - 业务代码只依赖
rt接口,框架差异由适配器消化 - 🧭 命令描述符 - 命令逻辑写成纯函数,各框架按自己的方式注册
- 🔄 模块化设计 - 每个游戏独立模块
- 📡 API 监控 - 实时获取官方版本信息
- 💾 数据持久化 - Redis 保存当前版本状态,Node 内置 SQLite 保存历史版本数据
- 🎯 精准推送 - 避免重复通知
- ⚡ 高性能 - 异步处理,低资源占用
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
本项目基于 MIT License 开源协议。
rainbowwarmth
- 🐙 GitHub: @rainbowwarmth
感谢以下项目和开发者:
- Miao-Yunzai - 强大的机器人框架
- TRSS-Yunzai - 强大的机器人框架
- MangoCat-Yunzai - 内置 OneBotv11 适配器的云崽分支
- JiuLi(玖璃) - 兼容 TRSS 生态的 TS 内核框架
- Karin - 强大的机器人框架
- Yunzai-NG - 可插拔运行时内核
- Guoba-Plugin - 可视化配置支持