Files
HeXi/hexi/plugins/nonebot_plugin_helldivers_tools

nonebot_plugin_helldivers_tools

绝地潜兵小助手。命令:

  • 简报:获取星系战争概况(现在走 helldivers-2/api 社区接口,用 Playwright 渲染自建 HTML 卡片,不再打开外部网页截图)。
  • 随机战备:随机一套战备(自建 HTML 卡片,与 简报 一样用 nonebot_plugin_htmlrender 出图)。

为什么改成 API?

旧方案用 Playwright 打开 hd2galaxy.com 截全页图,要等 networkidle(本地化 30s 左右),还要在页面 DOM 里做星球名替换,慢且脆弱。

新方案:

  1. 调 helldivers-2/api 的 /api/v1/war、/assignments、/campaigns、/planets(带缓存,避免触发限流);
  2. 用自己的 HTML 模板(内联 CSS + base64 logo + 系统字体)渲染一张战况卡片;
  3. 交给 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、deaths
  • assignments[0]:title、description、briefing、reward/rewards、expiration
  • campaigns[] → planet:name、currentOwner、health、maxHealth、statistics.playerCount
  • planets[] → currentOwner(星系控制统计用)

翻译兜底

接口带 Accept-Language: zh-Hans 时,LocalizedMessage 字段会返回中文。若某字段仍为英文,渲染层会用 data/plantes_mix.json 做兜底翻译。