- 旧平铺模块(data/data_utils/database_op/image_builder*/get_bf6_data/ gametools_bf6/bf6_data/img_utils)拆分为 handlers(绑定/查询)、 services(fetchers/processing/query)、utils(渲染/参数)分层; 新增 repository.py / config.py / paths.py - 字体/图片/模板资源迁入 res/,新增 BF2042 卡面素材(bg/object_icon 等) - browser_ext/:BF2042 扩展捕获桥(WS 直连兜底通道)源码入库 - 新增 hexi/web/src/plugins/bf_bot 前端管理页 - 新增 tests:test_bf_bot_helpers / repository / tracker_api Co-Authored-By: Claude Code <noreply@anthropic.com>
4.3 KiB
HeXi BF2042 捕获桥(浏览器扩展)
被动捕获 tracker.gg 的 BF2042 API 响应,经 WebSocket 转发给本机 bot。
服务端有两个等价实现:bot 插件内的 services/fetchers/tracker_bridge.py(正式,
随 bot 启停,端口/token 是 /hub 插件配置页里的 bf_ext_ws_port/bf_ext_ws_token),
以及 debug/bf2042_bridge_server.py(独立联调用,不启 bot)。两侧默认
ws://127.0.0.1:39272/?token=hexi-bf2042。
原理
历史通道要走 --remote-debugging-port + Playwright connect_over_cdp。本扩展把捕获
搬进浏览器内部,参照 FetchV / 猫抓一类捕获扩展的通行模式:
inject.js(主世界,document_start)用 Proxy 包住fetch/XMLHttpRequest, 被动观察页面自己发出的请求(不改写、不重放,只读 clone 的响应体);content.js(隔离世界)把捕获经chrome.runtime转给 SW (内容脚本连ws://127.0.0.1会被页面 CSP 的 connect-src 拦掉,所以 WS 必须放 SW);background.js(SW)持有到 bot 的 WebSocket,转发捕获、执行取数任务: 找/开 tracker.gg 标签页 → 回首页落稳 → 站内跳转进 profile 页 → 等页面发 XHR。- 失败重试:单轮 22s 内关键响应没齐(多半撞了 CF 挑战/403,页面 XHR 拿不到 数据),自动重走"首页→站内跳转"刷新,最多 3 轮;每轮结束做页面健康检查 (挑战页/封禁页/登录过期)并打日志。
不需要任何调试端口,浏览器就是个普通 Edge 实例,可以常驻不关。
安装(一次性)
- 用专用配置开 Edge(登录态 + CF 信任都在里面):
msedge.exe --user-data-dir="<repo>\hexi\data\nonebot_plugin_bf_bot\edge_profile" - 地址栏开
edge://extensions→ 打开"开发人员模式" → "加载解压缩的扩展" → 选本目录。 - 若有"开发者模式扩展"启动提示,保留即可(纯提醒,不影响)。
代码改动后在 edge://extensions 点该扩展的"刷新"按钮生效;SW 日志在扩展详情页点
"Service Worker" 检查。
联调(不启 bot)
.venv\Scripts\python.exe debug\bf2042_bridge_server.py # 手动浏览观察
.venv\Scripts\python.exe debug\bf2042_bridge_server.py --job EAID # 自动取数全流程
预期输出:先 "扩展已连接";手动打开任意 BF2042 profile 页会打印被动捕获;
--job 时扩展自动完成首页→站内跳转,打印 4 个响应,最后 "任务完成 keys=..."。
注意:bot 在跑时 39272 已被 bot 自己的扩展桥占用——要跑独立联调服务端得先停
bot(或临时改扩展 background.js 的端口常量)。bot 在跑时直接看 bot 日志里
"BF2042 扩展桥" 相关行即可,不用另起服务端。
WebSocket 协议(v0)
服务端:ws://127.0.0.1:39272/?token=hexi-bf2042(仅回环 + 共享 token;
常量在 background.js 顶部,bot 侧对应配置项为 bf_ext_ws_port/bf_ext_ws_token,
两边保持一致)。
| 方向 | 消息 |
|---|---|
| ext→bot | {"type":"hello","name":"hexi-bf2042-bridge","version":"0.1.0"} |
| bot→ext | {"type":"fetch","id":"...","player":"X","platform":"origin","profileUrl":"https://tracker.gg/bf2042/profile/origin/X/overview","apiBase":"https://api.tracker.gg/api/v2/bf2042/standard/profile/origin/X"} |
| ext→bot | {"type":"capture","id":null 或任务id,"key":"profile|weapon|vehicle|soldier","url":"...","status":200,"body":{...}} |
| ext→bot | {"type":"job_done","id":"...","keys":["profile","weapon","vehicle"]} |
| ext→bot | {"type":"job_error","id":"...","keys":[...],"detail":"..."} |
| 双向 | {"type":"ping"} |
- 无任务时的捕获以
id: null被动转发。 - 任务的 URL 匹配"两遍 decode 再比",消除 python
quote()与 JSencodeURIComponent的转义差异。 - 任务期间只认自己驱动的标签页(
tabId过滤)。
注意
- 导航定律保留:首页 bootstrap → 站内跳转(
location.href);深链直开会被挑战。 - MV3 SW 保活:活跃 WebSocket(Chromium 116+)+
chrome.alarms(30s)双保险, bot 重启后扩展自动重连。 - 若手动浏览时页面有数据、扩展却捕获不到 → 该请求可能不经过页面
fetch/XHR(如 Worker 发起)。届时把捕获后端换成chrome.debugger(只开 Network 域), 管道其余部分不用动。 - 本目录不要放
.py(它是插件目录子目录的一部分,保持纯前端文件)。