80 lines
4.3 KiB
Markdown
80 lines
4.3 KiB
Markdown
# 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 实例,可以常驻不关。
|
||
|
|
|
||
|
|
## 安装(一次性)
|
||
|
|
|
||
|
|
1. 用专用配置开 Edge(登录态 + CF 信任都在里面):
|
||
|
|
```
|
||
|
|
msedge.exe --user-data-dir="<repo>\hexi\data\nonebot_plugin_bf_bot\edge_profile"
|
||
|
|
```
|
||
|
|
2. 地址栏开 `edge://extensions` → 打开"开发人员模式" → "加载解压缩的扩展" → 选本目录。
|
||
|
|
3. 若有"开发者模式扩展"启动提示,保留即可(纯提醒,不影响)。
|
||
|
|
|
||
|
|
代码改动后在 `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()` 与 JS
|
||
|
|
`encodeURIComponent` 的转义差异。
|
||
|
|
- 任务期间只认自己驱动的标签页(`tabId` 过滤)。
|
||
|
|
|
||
|
|
## 注意
|
||
|
|
|
||
|
|
- 导航定律保留:首页 bootstrap → 站内跳转(`location.href`);深链直开会被挑战。
|
||
|
|
- MV3 SW 保活:活跃 WebSocket(Chromium 116+)+ `chrome.alarms`(30s)双保险,
|
||
|
|
bot 重启后扩展自动重连。
|
||
|
|
- 若手动浏览时页面有数据、扩展却捕获不到 → 该请求可能不经过页面 `fetch`/`XHR`
|
||
|
|
(如 Worker 发起)。届时把捕获后端换成 `chrome.debugger`(只开 Network 域),
|
||
|
|
管道其余部分不用动。
|
||
|
|
- 本目录不要放 `.py`(它是插件目录子目录的一部分,保持纯前端文件)。
|