Per docs/plugin-audit-report.md (plugins normalized to Trigger(handlers) → Service(services) → Model(repository/models) + utils): - Split monolithic __init__.py into handlers/services/utils across dailywife, deer_pipe, dice, galgame_card, helldivers_tools, huoziyinshua, learning_chat, makeaquote, mc_server_status, ncm_saying, picfinder_take, picstatus, random_jm_code, regif, steam_info, video_analysis, group_tools - Move static assets under res/: deer_pipe font/img, makeaquote font, helldivers img/templates, huoziyinshua HuoZiYinShua - Add config.py + register_config_items to ncm_saying, random_jm_code, group_tools; learning_chat unified config bridge - Remove deprecated: voice_trans plugin, bf_bot/test.py, dead code in dailywife/deer_pipe, empty dirs, debug scripts under helldivers temp - Disable brash_general_supercredits_tools (stub comment only) - bot.py: optional stdout/stderr redirect to log file for Web log viewer, force ANSI colorize on non-TTY sinks - Move runtime data (jm_code.json) out of plugin dir into hexi/data - Docs: plugin-audit-report.md; README reflects removed plugins Co-Authored-By: Claude <noreply@anthropic.com>
nonebot_plugin_helldivers_tools
绝地潜兵小助手。命令:
简报:获取星系战争概况(现在走 helldivers-2/api 社区接口,用 Playwright 渲染自建 HTML 卡片,不再打开外部网页截图)。随机战备:随机一套战备(自建 HTML 卡片,与简报一样用nonebot_plugin_htmlrender出图)。
为什么改成 API?
旧方案用 Playwright 打开 hd2galaxy.com 截全页图,要等 networkidle(本地化 30s 左右),还要在页面 DOM 里做星球名替换,慢且脆弱。
新方案:
- 调
helldivers-2/api的/api/v1/war、/assignments、/campaigns、/planets(带缓存,避免触发限流); - 用自己的 HTML 模板(内联 CSS + base64 logo + 系统字体)渲染一张战况卡片;
- 交给 nonebot_plugin_htmlrender 的
get_new_page()出图。因为模板是本地内容、无外部资源,set_content后秒级完成,不再卡 30s。
说明:由
nonebot_plugin_htmlrender管理 Playwright 内核(机器人日志里HTMLRender Started.即已加载)。简报与随机战备都依赖require("nonebot_plugin_htmlrender"),与nonebot_plugin_picstatus的做法一致。
新增/改动文件
| 文件 | 作用 |
|---|---|
config.py |
NoneBot 插件配置 |
hd2_api.py |
异步 API 客户端(httpx + 进程内缓存 + 并发聚合) |
war_renderer.py |
战况 HTML 模板 + 用 nonebot_plugin_htmlrender 渲染为 PNG |
equipment_renderer.py |
随机战备 HTML 模板 + 用 nonebot_plugin_htmlrender 渲染为 PNG |
__init__.py |
简报 与 随机战备 命令改为走 API / 本地 + 渲染(移除了 screen_shot 依赖) |
配置
NoneBot 配置(.env / .env.dev)读取以下环境变量,均为可选,用默认值即可开箱即用:
| 环境变量 | 默认值 | 说明 |
|---|---|---|
hd2_api_base_url |
https://api.helldivers2.dev |
自托管 helldivers-2/api 的根地址;不填用公共社区 API |
hd2_api_language |
zh-Hans |
请求本地化语言(自托管默认支持 zh-Hans / zh-Hant) |
hd2_cache_ttl |
60 |
缓存秒数,避免频繁打接口触发限流(5次/10秒) |
hd2_super_client |
hexi-bot.local |
请求头,社区 API 必备 |
hd2_super_contact |
https://github.com/sansenhoshi/nonebot_plugin_helldivers_tools |
请求头,社区 API 必备 |
⚠️ 两个
X-Super-*头必须都存在:RateLimitMiddleware在ValidateClients=true时(公共实例默认开启)要求请求同时带X-Super-Client和X-Super-Contact,缺一即返回400 Bad Request / "The X-Super-Client and X-Super-Contact headers are required"。客户端已保证始终发这两个头,hd2_super_contact留空也会用hd2_super_client兜底。
示例:
hd2_api_base_url=http://127.0.0.1:8080
hd2_api_language=zh-Hans
hd2_cache_ttl=60
自托管 helldivers-2/api
项目是 .NET 10 + Docker。用 Docker Compose 最省事。
1) 克隆(务必带子模块)
git clone --recurse-submodules https://github.com/helldivers-2/api.git
cd api
src/Helldivers-2-Models/json是子模块,里面是星球名/本地化数据,不带上它接口会没数据。
2) 放一个 docker-compose.yml(在 api 根目录)
本仓库已写好一份:
HeXi/deploy/helldivers-api/docker-compose.yml,复制到api仓库根目录即可。要点:ASPNETCORE_URLS=http://+:8080(否则默认监听 5000)、Helldivers__API__Authentication__Enabled=false(必须)、ValidateClients=false、含健康检查/重启/日志轮转。
services:
helldivers-api:
build:
context: .
dockerfile: src/Helldivers-2-API/Dockerfile
image: helldivers2-api
container_name: helldivers2-api
ports:
- "8080:8080"
environment:
# 自托管务必关鉴权:默认 Authentication.Enabled=true 但没 SigningKey,直接启动会抛 ArgumentNullException(issue #90)
- Helldivers__API__Authentication__Enabled=false
# 抬高本地限流,多核打也不怕
- Helldivers__API__RateLimit=300
- Helldivers__API__RateLimitWindow=10
# 与 ArrowHead 官方接口同步频率(秒)
- Helldivers__Synchronization__IntervalSeconds=60
restart: unless-stopped
3) 构建并启动
docker compose up -d --build
4) 验证
# 应该返回 JSON(当前战争信息)
curl http://127.0.0.1:8080/api/v1/war
curl http://127.0.0.1:8080/api/v1/assignments
5) 让机器人指向它
在机器人 .env / .env.dev 里(本项目在 HeXi/.env)写:
hd2_api_base_url=http://127.0.0.1:8080
hd2_api_language=zh-Hans
然后重启机器人,发 简报 即可。默认配置的 Languages 已含 zh-Hans,星球名/大指令就是中文。
常见问题
docker compose up报ArgumentNullException (Parameter 's'):忘关鉴权了,确认有Helldivers__API__Authentication__Enabled=false。/api/v1/war一直是 200 但planet.name为空:子模块没拉全,重新git submodule update --init --recursive后重建。- 返回 400 / "X-Super-Client and X-Super-Contact headers are required":这是实例开了
ValidateClients;我方客户端已永远带这两个头,正常不会触发。 - 容器能起但数组为空:容器要联网访问 ArrowHead 官方接口才能同步,检查机器能否访问外网。
- 想用 Fly.io:仓库自带
fly.toml,直接fly deploy。
备选部署(不用 Docker)
数据(星球名/本地化)由 Helldivers-2-SourceGen 在编译期写进二进制,运行时不读任何 json 文件,所以直接跑发布产物完全可行。
Windows 本机跑(只需 .NET 10 SDK 构建一次):
git clone --recurse-submodules https://github.com/helldivers-2/api.git && cd api
dotnet publish src/Helldivers-2-API/Helldivers-2-API.csproj `
-c Release -r win-x64 --self-contained true -p:PublishAot=false -o .\publish
$env:ASPNETCORE_URLS="http://127.0.0.1:8080"
$env:Helldivers__API__Authentication__Enabled="false"
$env:Helldivers__API__RateLimit="300"
.\publish\Helldivers-2-API.exe
-p:PublishAot=false:项目默认 AOT,Windows 上要 VC++ 工具链,关掉避免踩坑。
VPS + systemd:把发布产物换成 linux-x64 上传,用 systemd 挂服务(Environment=Helldivers__API__Authentication__Enabled=false)。
Fly.io / 其它 PaaS:仓库自带 fly.toml,fly deploy 即可;Render/Railway/Azure 同理。
接口字段依赖
war.statistics:playerCount、missionSuccessRate、terminidKills、automatonKills、illuminateKills、deathsassignments[0]:title、description、briefing、reward/rewards、expirationcampaigns[]→planet:name、currentOwner、health、maxHealth、statistics.playerCountplanets[]→currentOwner(星系控制统计用)
翻译兜底
接口带 Accept-Language: zh-Hans 时,LocalizedMessage 字段会返回中文。若某字段仍为英文,渲染层会用 data/plantes_mix.json 做兜底翻译。