# nonebot_plugin_helldivers_tools 绝地潜兵小助手。命令: - `简报`:获取星系战争概况(现在走 **[helldivers-2/api](https://github.com/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](https://github.com/nonebotjs/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` 兜底。 示例: ```ini 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) 克隆(务必带子模块) ```bash 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`、含健康检查/重启/日志轮转。 ```yaml 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) 构建并启动 ```bash docker compose up -d --build ``` ### 4) 验证 ```bash # 应该返回 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`)写: ```ini 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 构建一次):** ```powershell 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` 做兜底翻译。