用于自动更新 PRTS Wiki 明日方舟相关页面的机器人。
机器人会定期或手动触发,从游戏官方资源中拉取最新游戏数据,解析后通过 MediaWiki API 写入 Wiki 对应页面(干员、敌人、关卡、家具、剧情、皮肤、模组、活动等)。
- 多服支持:CN(官服)、JP / US / KR(YoStar 海外服)、TW。
- 国服数据来源:直接从 Mooncell 自建的资源仓库 torappu(API 文档)按
resVersion在线读取解包好的 gamedata,不再依赖 GitHub 上的ArknightsGameData仓库;下载过的文件缓存在.cache/torappu/<resVersion>/。 - 海外服数据来源:开源仓库
ArknightsGameData_YoStar(子模块)。 - 版本对比:国服以 torappu 上 gamedata 已解包完成的最新版本为准,海外服查官方 CDN;仅在检测到
resVersion变化时执行更新。 - Wiki 写入:封装 MediaWiki API 提供
edit/read/category/protect/upload等操作,自动登录并带重试。 - 错误追踪:通过 Sentry 上报运行异常。
ptilopsis/
├── __main__.py # 入口,按命令行参数分派任务
├── config.py # config.json 的 pydantic 模型 + 环境变量读取
├── gamedata/ # 各表的 pydantic 模型(由 FBS 生成)+ 客户端展示规则
├── jobs/ # 各类 Wiki 更新任务
│ ├── basic.py # 干员基础信息
│ ├── sidebar.py # 侧边栏干员一览
│ ├── charword.py # 干员语音 / 档案
│ ├── skin.py # 皮肤 / 立绘
│ ├── stage.py # 关卡(含悖论模拟、剿灭等)
│ ├── enemy.py # 敌人图鉴 / 数据
│ ├── building_buff.py # 基建技能
│ ├── furni.py # 家具
│ ├── item.py # 道具
│ ├── medal.py # 勋章
│ ├── mission.py # 任务
│ ├── newModule.py # 新模组
│ ├── activity.py # 活动
│ ├── char_attr.py # 干员属性
│ ├── story_review.py # 剧情回顾
│ ├── term.py # 术语
│ ├── update_jp.py # JP 服增量更新
│ ├── weedy.py # 高规格自动任务
│ ├── params.py # job 可注入的现成依赖(gamedata / RichText / CharIdTable …)
│ └── ...
└── utils/
├── data.py # GameData,统一访问 torappu(国服)/ 子模块(海外服)数据
├── torappu.py # torappu HTTP 客户端:版本列表、文件下载、目录列举
├── unpacker.py # 各服版本号检查与记录(附官方 CDN 资源下载工具)
├── wiki.py # MediaWiki API 客户端(带 retry)
├── di.py # 依赖注入:Depends / analyze / Resolver
├── job.py # @job 注册表、JobContext、按名字调度
└── richTextStyles.py # 游戏富文本 → Wiki 模板转换
thirdparty/
├── OpenArknightsFBS/ # FlatBuffers schema (submodule,仅生成模型时用)
└── ArknightsGameData_YoStar/ # 海外服游戏数据 (submodule)
.github/workflows/ # GitHub Actions 定时 / 手动触发
config.json # 非敏感配置:各服 CDN 地址、FlatBuffers 表名等
.env.example # 敏感配置的环境变量样例
version_local.json # 本地已更新到的资源版本
version_remote.json # 通过 --remote 拉取时使用的版本记录
配置分为两部分,敏感信息一律不入库:
| 内容 | 位置 | 说明 |
|---|---|---|
| torappu 地址、各服 CDN 地址、FlatBuffers 表名、chatMask 等 | config.json |
随仓库提交,由 ptilopsis/config.py 中的 pydantic 模型校验;字段名以 camelCase 书写,多余或缺失字段会直接报错 |
| Wiki 登录凭据、Sentry DSN | 环境变量 | 本地开发用 .env(已被 .gitignore 忽略),CI 用 GitHub Actions Secrets |
需要的环境变量:
| 变量 | 必填 | 说明 |
|---|---|---|
PTILOPSIS_USERNAME |
是 | Wiki 用户名,不带 @BotName 后缀 |
PTILOPSIS_PASSWORD |
是 | 请使用 Special:BotPasswords 生成的机器人密码,格式为 <BotName>@<32位随机串>,不要使用主账号密码 |
PTILOPSIS_SENTRY_DSN |
否 | 留空则不启用错误上报 |
PTILOPSIS_CONFIG_PATH |
否 | 指定 config.json 路径,默认取工作目录 / 仓库根目录 |
本地开发:
cp .env.example .env # 然后填入真实值CI:在仓库 Settings → Secrets and variables → Actions 中添加同名 Secret,
main1 ~ main4 四个 workflow 会自动注入。
注意:改动主账号密码会使该账号下所有 BotPassword 失效,需要重新生成并更新 Secret。
- Python ≥ 3.13
- uv
flatc(FlatBuffers 编译器,运行时位于仓库根目录调用)
git clone --recurse-submodules https://github.com/MooncellWiki/Ptilopsis_Bot.git
cd Ptilopsis_Bot
uv sync --locked如果忘记 --recurse-submodules,可以补一句:
git submodule update --init --recursiveuv sync 后会注册 ptil 命令
ptil [flags] [modes ...]| 参数 | 作用 |
|---|---|
--check |
检查 torappu 上是否有 gamedata 已就绪的新 CN 版本,无更新则退出 |
--check-jp |
检查 JP / US / KR 服是否有新版本 |
--check-global |
检查所有海外服版本后退出 |
--remote |
CI 模式:版本记录改用 version_remote.json,自动更新海外服数据子模块,并在结束后提交推送 |
--force |
即便没有新版本也强制运行 |
--dev |
Wiki 客户端进入预览模式,仅打印将要提交的内容,不实际写入 |
-h, --help |
显示完整帮助 |
| 模式 | 包含任务 |
|---|---|
new |
新干员相关:sidebar.update → basic.run → charword.run |
regular |
常规更新:基建、关卡、敌人、皮肤、家具、道具、新模组、活动、任务、属性、勋章、剧情、术语 |
special |
干员详情 / 密录、悖论模拟、剿灭、语音补全等 |
jp |
JP 服增量更新 |
weedy |
高规格自动任务 |
demand |
占位 / 调试入口 |
# 仅检查 CN 服并执行常规更新
ptil --check regular
# CI 模式:跑完 new + regular + special 并提交版本记录
ptil --check --remote new regular special
# 检查并更新 JP 服
ptil --check-jp --remote jp
# 预览模式:不真正提交到 Wiki
ptil --dev regular| Workflow | 触发 | 命令 |
|---|---|---|
main-cn |
workflow_dispatch |
ptil --check --remote new regular special |
main-cn-force |
workflow_dispatch |
同上,附 --force |
main-jp |
workflow_dispatch |
ptil --check-jp --remote jp |
weedy |
workflow_dispatch |
ptil weedy |
ruff |
push: master / PR |
Ruff lint |
使用 Ruff
uv run ruff check .
uv run ruff format .ptilopsis/gamedata/ 下的整表模型由 thirdparty/OpenArknightsFBS/FBS/*.fbs 生成,
FBS 更新后重新生成对应的表即可:
uv run python scripts/gen_gamedata_models.py character_table skill_tableFlatBuffers 里 string / table / vector 字段都可能缺失,生成的模型把它们一律声明成
T | None,未判空的访问会被 pyright 指出;标量按 FBS 默认值填充,枚举字段保留成员名字符串。
改动 basic / char_attr 的渲染逻辑后,用 scripts/parity_basic.py 把重构前后的页面落盘做 diff
(数据按 version_local.json 里的国服版本从 torappu 读取):
PYTHONHASHSEED=0 uv run python scripts/parity_basic.py out/before
# 切换分支后
PYTHONHASHSEED=0 uv run python scripts/parity_basic.py out/after
diff -r out/before out/after仓库已配置 pre-commit,建议本地启用:
uv run pre-commit installjob 是用 @job 注册的普通函数,参数按注解注入(实现见 ptilopsis/utils/di.py,
借鉴 torappu 的 task 写法):
from typing import Annotated, Any
from ptilopsis.jobs.params import CharIdTable, RawItemTable, RichText, category, gamedata
from ptilopsis.utils.job import SkipJob, job
from ptilopsis.utils.wiki import Wiki
@job
def run(
wiki: Wiki,
item_table: RawItemTable,
stage_table: Annotated[dict[str, Any], gamedata("excel/stage_table.json")],
id_table: CharIdTable,
rts: RichText,
pages: Annotated[list[str], category("分类:道具")],
) -> None:
...Wiki/GameData/Config/JobContext直接按类型注入,其余依赖用Depends标记;params.py里放着各 job 共用的表、富文本转换器、干员序号表等。- 同一次运行里相同的依赖只解析一次;依赖或 job 抛
SkipJob表示这次没事可做。 - job 名默认是
<模块>.<函数>,__main__.py的MODE_JOBS用它编排各模式的执行顺序。 签名有问题(参数注不进去)会在导入时就报错。 - 旧写法
def run(ctx: JobContext)仍然可用,逐个改写即可。
- torappu — Mooncell 自建的明日方舟资源仓库,国服游戏数据来源
- MooncellWiki/OpenArknightsFBS — FlatBuffers schema
- Kengxxiao/ArknightsGameData_YoStar — 海外服游戏数据