docs(review): 沉淀 10.18 抢购实战复盘与对比优化路线图

- 新增 docs/seckill-analysis-20261018.md:覆盖 5 台机器 23 实例 562 账号全量指标剖析
- 新增 docs/seckill-optimization-roadmap.md:对标 dygou_go 形成四大工作包优化路线图
This commit is contained in:
yml2213
2026-10-18 21:23:45 +08:00
parent 41c05adc50
commit 908ceb0b3b
2 changed files with 249 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
# 2026-10-18 抢购实战全量复盘与引擎诊断报告
> **数据源**:`/Users/yml/Downloads/logs/10.18`(共 5 台机器 pc-1 ~ pc-5,23 个运行实例,覆盖 562 个账号)
> **活动信息**:sid=2277,开抢时刻 17:00:00,三个目标商品(13433 怪诞乔克 / 13435 天网终结者 / 13443 套装-潮萌小黄鸭)
> **软件版本**:huya-go v0.5.2(实施了双时间校准、首发错峰 300ms、动态提前量、30s 窗口模型)
---
## 一、核心战报总览
| 目标商品 | 账号数 | 成功数 | 成功率 | 兑换请求 | 限流(火爆) | 售罄 | 角色伪报错(未绑定) | 首笔成功(虎牙时间) | 最后一笔成功 |
|---|---|---|---|---|---|---|---|---|---|
| **13433 (怪诞乔克礼包)** | 301 | **186** | **61.8%** | 3,135 | 1,939 | 740 | 549 | 17:00:00.226 | 17:00:10.280 (售罄) |
| **13435 (天网终结者)** | 79 | **78** | **98.7%** | 601 | 385 | 0 | 115 | 17:00:00.228 | 17:00:19.361 |
| **13443 (潮萌小黄鸭)** | 182 | **182** | **100.0%** | 1,818 | 1,112 | 0 | 250 | 17:00:00.226 | 17:00:20.476 |
| **全网合计** | **562** | **446** | **79.4%** | **5,554** | **3,436 (61.8%)** | **740** | **914** | **17:00:00.226** | **17:00:20.476** |
### 关键战报结论
1. **整体胜率大幅跃升**:562 账号斩获 446 件,总成功率 **79.4%**(比 10.16 的 71% 提高 8.4 个百分点)。小黄鸭 182/182 达成 **100% 满贯**,天网终结者 78/79 达成 **98.7% 满贯**。
2. **极速秒杀款(乔克)硬碰硬**:在全国高并发争夺下,301 个账号拿下 186 件(**61.8%**),窗口期约 **10 秒**(17:00:00.226 首单放行,17:00:09.335 全网首次报售罄,17:00:10.280 最后一笔成交)。
3. **0 崩溃 / 0 掉队**:23 个实例全部平稳跑完 30s 窗口,无 panic、无卡死、无 WUP 截断。
---
## 二、23 个实例运行明细矩阵
| 机器 | 实例 | 目标商品 | 账号 | 成功 | 成功率 | 兑换请求 | 限流 | 售罄 | 账号未绑定 | 本机偏差 | RTT | 首笔成功(H虎牙时间) | 末笔成功(H虎牙时间) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| pc-1 | default | 13433 乔克 | 30 | 18 | 60.0% | 389 | 234 | 83 | 53 | +14ms | 56ms | 17:00:00.226 | 17:00:09.414 |
| pc-1 | instance-2 | 13433 乔克 | 29 | 14 | 48.3% | 424 | 246 | 117 | 47 | +9ms | 75ms | 17:00:00.311 | 17:00:10.266 |
| pc-1 | instance-3 | 13433 乔克 | 30 | 20 | 66.7% | 342 | 213 | 71 | 38 | +14ms | 62ms | 17:00:00.270 | 17:00:09.398 |
| pc-1 | instance-4 | 13433 乔克 | 30 | 22 | 73.3% | 328 | 193 | 58 | 55 | +8ms | 62ms | 17:00:00.286 | 17:00:10.262 |
| pc-1 | instance-5 | 13433 乔克 | 27 | 15 | 55.6% | 341 | 192 | 84 | 49 | +12ms | 75ms | 17:00:00.238 | 17:00:09.375 |
| pc-2 | default | 13435 天网 | 30 | 29 | 96.7% | 219 | 144 | 0 | 44 | -30ms | 65ms | 17:00:00.254 | 17:00:12.335 |
| pc-2 | instance-2 | 13433 乔克 | 27 | 17 | 63.0% | 335 | 195 | 71 | 52 | -36ms | 69ms | 17:00:00.246 | 17:00:10.075 |
| pc-2 | instance-3 | 13435 天网 | 30 | 30 | 100.0% | 233 | 158 | 0 | 45 | -32ms | 73ms | 17:00:00.228 | 17:00:14.526 |
| pc-2 | instance-4 | 13435 天网 | 16 | 16 | 100.0% | 106 | 67 | 0 | 23 | -30ms | 78ms | 17:00:00.267 | 17:00:19.361 |
| pc-2 | instance-5 | 13433 乔克 | 30 | 20 | 66.7% | 344 | 203 | 68 | 52 | -32ms | 78ms | 17:00:00.280 | 17:00:09.404 |
| pc-3 | default | 13433 乔克 | 24 | 15 | 62.5% | 282 | 170 | 51 | 44 | -101ms | 72ms | 17:00:00.264 | 17:00:10.280 |
| pc-3 | instance-2 | 13433 乔克 | 20 | 16 | 80.0% | 191 | 112 | 28 | 34 | -99ms | 69ms | 17:00:00.237 | 17:00:09.409 |
| pc-3 | instance-3 | 13433 乔克 | 20 | 10 | 50.0% | 215 | 130 | 42 | 29 | -98ms | 77ms | 17:00:00.240 | 17:00:09.413 |
| pc-3 | instance-4 | 13435 天网 | 1 | 1 | 100.0% | 10 | 8 | 0 | 1 | -97ms | 68ms | 17:00:11.350 | 17:00:11.350 |
| pc-4 | default | 13443 小黄鸭 | 30 | 30 | 100.0% | 238 | 161 | 0 | 47 | -761ms | 70ms | 17:00:00.239 | 17:00:20.476 |
| pc-4 | instance-2 | 13443 小黄鸭 | 30 | 30 | 100.0% | 201 | 131 | 0 | 40 | -763ms | 67ms | 17:00:00.226 | 17:00:19.394 |
| pc-4 | instance-3 | 13433 乔克 | 30 | 17 | 56.7% | 308 | 190 | 52 | 43 | -764ms | 78ms | 17:00:00.265 | 17:00:09.384 |
| pc-4 | instance-4 | 13435 天网 | 2 | 2 | 100.0% | 8 | 6 | 0 | 0 | -763ms | 72ms | 17:00:00.310 | 17:00:06.408 |
| pc-4 | instance-5 | 13433 乔克 | 4 | 2 | 50.0% | 58 | 35 | 15 | 6 | -762ms | 76ms | 17:00:06.331 | 17:00:08.341 |
| pc-5 | default | 13443 小黄鸭 | 30 | 30 | 100.0% | 249 | 168 | 0 | 51 | -500ms | 72ms | 17:00:00.267 | 17:00:19.445 |
| pc-5 | instance-2 | 13443 小黄鸭 | 30 | 30 | 100.0% | 233 | 156 | 0 | 47 | -498ms | 82ms | 17:00:00.288 | 17:00:14.531 |
| pc-5 | instance-3 | 13443 小黄鸭 | 30 | 30 | 100.0% | 234 | 153 | 0 | 51 | -499ms | 80ms | 17:00:00.264 | 17:00:17.219 |
| pc-5 | instance-4 | 13443 小黄鸭 | 32 | 32 | 100.0% | 266 | 171 | 0 | 63 | -496ms | 65ms | 17:00:00.308 | 17:00:19.301 |
---
## 三、重大实战发现与深度逆向证据
### 发现 1:双时间校准机制(H-time)表现堪称完美
- **证据**:
- pc-1 本机时钟偏快 +14ms;
- pc-2 本机偏慢 -30ms;
- pc-3 本机偏慢 -100ms;
- pc-4 本机偏慢高达 **-763ms**(近 0.8 秒误差);
- pc-5 本机偏慢高达 **-500ms**(0.5 秒误差)。
- **实测结果**:在动态提前量(`dynamicAdvance = ErrorBound + RTT/2`)换算后,**所有 5 台机器打向虎牙的第一发请求,抵达虎牙服务端的估算时间全部精准收敛在 `H17:00:00.004 ~ H17:00:00.018` 之间!误差 < 15ms!**
- **首单成交时间一致性**:所有实例的首笔成功全部精准定格在 `H17:00:00.226 ~ H17:00:00.311`,没有任何一台机器因为本地时钟偏差而过早白打或过晚落后。
### 发现 2:虎牙服务端的微观放量门槛(0~200ms 的硬限流墙)
- **日志切片证据**:
- `H17:00:00.000 ~ 00.200`:第一批抢跑的 42 个请求中,33 个直接被服务端返回「活动太火爆了,请稍后重试」,只有极少数(9个)通过。
- `H17:00:00.220+`:服务端才真正开闸放水,第一批成交井喷。
- **结论**:虎牙整点秒杀虽然在 17:00:00 激活,但在 0~200ms 内服务端网关存在初始抗峰/排队限流(或微服务放量延迟)。请求在途 50ms 左右,刚好在 0.22s 触发第二波抢兑。
### 发现 3:全网 914 次「账号未绑定!」的真正元凶——角色服务降级伪报错
- **现象**:日志出现高达 914 次 `category=session_lost msg=账号未绑定!`。
- **逆向真相(证据)**:
- 账号 `1199668644708`(pc-1 default):
- `17:00:00.309(H17:00:00.323)`:报 `账号未绑定!`
- `17:00:00.769(H17:00:00.783)`:报 `活动太火爆了,请稍后重试`
- `17:00:01.616(H17:00:01.630)`:报 `账号未绑定!`
- `17:00:02.066`:报 `请求太频繁,请稍后重试`
- `17:00:04.462`:报 `账号未绑定!`
- `17:00:09.318(H17:00:09.333)`:**请求成功!积分成功扣除,兑换成功,并查到兑换记录!**
- **数据分布**:
- 270 次发生在 17:00:00 秒,178 次发生在 17:00:01 秒,119 次发生在 17:00:02 秒。
- 单账号最大连续遇到该提示的次数只有 4 次(387 个账号连续 1 次,48 个账号连续 2 次,8 个连续 3 次,2 个连续 4 次)。
- **业务结论**:
- 该提示根本**不是虎牙 Cookie 或 Web 登录态失效**!
- 在秒杀洪峰时,虎牙兑换接口需要同步校验用户的「和平精英游戏角色绑定(game_role)」。下游角色绑定系统瞬间过载超时,虎牙兑换接口直接 fallback 抛出「账号未绑定!」。
- 随着洪峰在 2~3 秒后略微缓解,下游角色校验恢复,该账号立刻正常兑换成功!
### 发现 4:服务端放量形态分析与 9.5s 的放量脉冲
- **现象**:
- 17:00:00 ~ 17:00:09 之间,服务端保持每秒 10~20 个的稳定匀速放行。
- **在 `H17:00:09.5` 这一半秒内,三大商品同时爆发大量成功(乔克 80 个、小黄鸭 59 个、天网 26 个,合计 165 个成功!)**
- 紧接着在 `H17:00:10.0`,乔克立刻全面售罄(17:00:10 报 SoldOut 8 次,10.5 报 17 次,11.0 报 16 次,随后彻底无货)。
- **推论**:
- 虎牙在秒杀开启后前 9 秒有严格的限流防刷漏斗,在第 9~10 秒网关放宽了限流阈值,瞬间消化了排队和重试的请求,把剩余库存全部释放并打空。
- 这再次印证了:**持续紧咬 10 秒窗口、不轻言放弃、保持合理退避的引擎策略是极其正确的**(80 个乔克都是在 9.5 秒抢到的!如果像老版本那样 2~3 秒烧光轮次就退出,这 80 个乔克就全丢了)。
### 发现 5:TAF/WUP 协议异常完整诊断生效,捕获 5 秒超时异常
- **日志切片**:
```
[pc-2] 2026-10-18 17:00:05.070 [监控][error][账号:1199664503824] loop=1 action=exchange_error category=protocol msg=兑换请求失败 error=协议响应异常: webActUI.scoreExchangePrize 响应缺少 tRsp/tResp(iRet=128 servant=webActUI.scoreExchangePrize status={STATUS_RESULT_DESC=wup request biz execption:-7} keys={(2B)} payload=11B)
```
- **价值分析**:
- 之前 10.16 优化项 P2 的诊断字段全部成功落地(抓到 `iRet=128` 与 `status={STATUS_RESULT_DESC=wup request biz execption:-7}`)。
- 并且定位到了耗时:请求从 17:00:00 发出,在 17:00:05.070 才收到响应(耗时整整 5.07 秒)。
- 这说明服务端微服务在处理此请求时发生 5s 超时后抛出异常。客户端虽然优雅捕获并重试,但单账号被阻塞了 5 秒,错过了秒杀黄金期。
---
## 四、对本项目(huya-go)代码的检视与优化建议
基于上述证据,我们对照当前代码仓库(`internal/sniper`、`internal/huya`、`internal/gui`)进行审查,发现以下改进空间:
### 1. 【高优先级】重构「账号未绑定!」的分类与退避语义
- **现状代码**(`internal/sniper/classify.go:116`):
```go
case containsAny(text, "账号未绑定", "未绑定账号", "未绑定手机", "登录态", "登录失效", "请先登录", "凭证失效", "token 失效"):
return CategorySessionLost, true
```
- **问题**:
1. 将「账号未绑定」与「登录态已失效」混在一块,划归为 `CategorySessionLost`。
2. 虽然 `defaultSessionLostLimit` 调到了 8,但如果某账号连续 8 次遭遇角色服务抖动,仍会被永久判死(`account.done = true`)。
3. 在 `retry.go:179` 中,`CategoryTooFrequent` 未包含在 `sessionAliveCategory` 中,导致账号在收到限流时 `sessionStreak` 无法被重置,连续限流中穿插的「未绑定」会产生虚假累加。
4. 日志里输出 `[warn] 结局 session_lost ×53(会话失效)` 造成恐慌。
- **改进方案**:
- 新增独立分类 `CategoryRoleUnbound = "role_unbound"`(角色未绑定 / 角色服务抖动),或归入临时业务重试(类似条件未满足,但不判死)。
- 「账号未绑定」单独抽出,不计入 `sessionStreak`,不触发 `account.done` 熔断,只执行普通退避(如 200~300ms)。
- 真正的凭证失效(「请先登录」「登录失效」「token失效」)才保留为 `CategorySessionLost`。
- 并在 `sessionAliveCategory` 中将 `CategoryTooFrequent` 也加入(能返回限流说明会话健全)。
### 2. 【高优先级】缩短单次秒杀请求的 Context 超时阈值(从 15s/10s 压缩至 1.5s~2.0s)
- **现状代码**(`internal/gui/app.go:725` 与 `internal/huya/wss_client.go:99`):
- 默认调用超时长达 10~15 秒。
- 当服务端某台微服务卡死时,账号会 hang 住 5 秒才返回 `biz exception:-7`。在只有 9 秒生命周期的乔克秒杀中,卡 5 秒等于宣告该账号出局。
- **改进方案**:
- 在秒杀作战期间(`RunTargets`),为单次 `ScoreExchangePrize` 设置专用的紧凑超时(例如 `1500ms` 或 `2000ms`)。
- 若 1.5 秒未回包,立刻 `cancel` 并重试下一次,绝不让一个卡死的请求占用账号 5 秒。
### 3. 【中优先级】首发错峰与第一波(0~200ms)策略精细化
- **现状**:
- 首发 300ms 错峰(`spread=300ms`, `step=8ms`)成功分散了 30 个账号。
- 但 0~200ms 的第一发请求 80% 遭遇了「太火爆」。
- **改进方向**:
- 第一波被限流后的重试退避:当前 `stageMultiplier` 头 2 秒乘数为 1,退避基准为 300ms。
- 第一发 0.00s 遇到火爆的账号,在 0.35s 左右刚好打出第二发并成功抢到。
- 可以保持当前退避节奏,但可将首轮火爆退避稍微加入微抖动(200ms~350ms),让第二波请求在 0.25s~0.50s 之间更均匀地切入放量窗口。
### 4. 【低优先级】同机多实例跨进程协调与 IP 限流缓释
- **现状**:
- pc-1 单机跑了 5 个实例,共 146 个账号全部打乔克,总共发了 1,824 次请求,其中 1,078 次限流(限流比高达 59.1%)。
- 多个独立进程之间没有共享首发错峰槽位,5 个实例的第 0 个账号在同一毫秒齐射。
- **优化建议**:
- GUI 启动多实例时,或配置文件中支持为不同实例分配初始偏移(如 instance-1 偏移 0ms,instance-2 偏移 50ms,instance-3 偏移 100ms...),实现跨实例的宏观交错。
+94
View File
@@ -0,0 +1,94 @@
# huya-go 全面架构深度分析与优化路线图(对比 dygou_go)
> **编制日期**:2026-10-18
> **基线版本**:huya-go v0.5.3
> **参考对标**:`/Users/yml/codes/dygou_go`(斗鱼自动化抢购系统)
> **实战支撑**:2026-10-18 5台机器 23实例 562账号实战日志
---
## 一、架构与功能全景对比矩阵
| 模块 / 维度 | `dygou_go`(斗鱼项目) | `huya-go`(虎牙现状) | 差距与优化潜力等级 |
|---|---|---|:---:|
| **1. 兑换请求超时控制** | 细粒度超短超时(秒级超时熔断,区分服务端超时与网络超时),单次请求绝不 hang 住 | 透传全局任务 `ctx`,底层网络超时为 10~15 秒;实战中曾出现账号被 hang 整整 5.07 秒 | 🔴 **高危 / 极高优先级** |
| **2. 错误分类与退避精度** | 细分 Transient / InFlight / RateLimited / Throttled / StockOut / Terminal;支付有专门退避阶梯 | 「账号未绑定!」被误判为 `CategorySessionLost`;`TooFrequent` 未纳入存活状态;退避阶梯较粗 | 🔴 **高危 / 极高优先级** |
| **3. 积分基线与刚性扣分对账** | `ScoreBaselineStore`(`scores.json`):抢购前建基线,抢购后自动比对 `余额差值 == 售价`,反查暗中成功单 | 仅抢购成功时单号异步刷新,无基线文件,无全局刚性对账能力,网络闪断或超时导致的暗中成交会漏单 | 🟡 **重要 / 高优先级** |
| **4. 作战战报持久化与导出** | `last_xiaodian_report.json` 保存战报,支持 GUI 一键导出 Excel / CSV,包含每账号、商品、耗时、状态 | 抢购战果仅保存在内存中,界面关闭或刷新即丢失,无 Excel / CSV 导出功能,代抢对账依赖翻日志 | 🟡 **重要 / 高优先级** |
| **5. 备选目标多级轮转 (Fallback)** | 允许配置主目标与备选目标,主目标一旦售罄(StockOut),未完成账号自动无缝切换到备选目标 | `RunTargets` 虽支持多目标,但采用同轮平铺探测,无“优先级与售罄自动降级”机制,GUI 仅能填单 PID | 🟡 **重要 / 高优先级** |
| **6. 成功战报精美长图生成** | 原生 `image/draw` + `freetype` 自动生成战报图片卡片(带标题、成功率、账号列表、耗时),支持一键发群晒单 | 无大图生成功能,用户只能手动截屏或拍照 | 🟢 **体验增强 / 中优先级** |
| **7. 跨实例同机协同错峰** | 跨平台互斥锁;支持实例级错峰参数,避免同机多开在 0.00s 齐射造成本地网卡与单 IP 限流 | 已做实例数据目录隔离,但同机多实例在 0.00s 同步发射,加剧单 IP 限流(10.18 pc-1 限流比达 60%) | 🟢 **微调优化 / 中优先级** |
---
## 二、四大优化工作包详细设计
### 📦 工作包 1:抢购引擎核心稳态升级(消灭卡死与误杀)
#### 1.1 单请求紧凑超时熔断(Per-Request Fast Timeout)
- **问题根源**:
在 `internal/sniper/exchange.go` 的 `exchangeTarget` 中,调用 `client.ScoreExchangePrize(ctx, ...)` 时直接透传了外部 `ctx`。底层 WSS/HTTP 连接的超时时间长达 10~15 秒。
10.18 实战日志证据:账号 `1199664503824` 与 `1199668733274` 在 loop 1 遭遇服务端微服务超时,单次请求足足耗时 **5.07 秒** 才返回 `biz exception:-7`,导致账号在黄金前 5 秒彻底停滞,直接错过抢购。
- **改进设计**:
引入秒杀专属请求超时 `RequestTimeout`(建议默认 `1500ms ~ 2000ms`):
```go
reqCtx, reqCancel := context.WithTimeout(ctx, cfg.RequestTimeout)
exchange, err := client.ScoreExchangePrize(reqCtx, account.UID, account.Cookie, sid, pid)
reqCancel()
```
若在 1.5 秒内未收到完整响应,立刻以超时错误返回并进入短退避重试,绝不阻塞当前账号的抢购节奏。
#### 1.2 剥离「账号未绑定!」分类,彻底解绑会话失效
- **问题根源**:
在 `internal/sniper/classify.go:116` 中,把「账号未绑定」归入 `CategorySessionLost`。
10.18 实战中出现 914 次该提示,实证表明:同一账号在遭遇数次「未绑定」后仍能成功抢到并扣分,这纯属虎牙下游和平精英角色服务超时降级。当前代码若连续遇到 8 次会直接永久判死(`account.done = true`),且界面上频频报警会误导用户。
- **改进设计**:
1. 引入独立分类 `CategoryRoleUnbound = "role_unbound"`(角色未绑定 / 服务抖动)。
2. `classifyExchangeText` 中,「账号未绑定/未绑定账号」映射到 `CategoryRoleUnbound`,真正的凭证失效(「请先登录/登录失效/token失效」)才保留为 `CategorySessionLost`。
3. `CategoryRoleUnbound` 仅触发普通业务重试退避(如 200~300ms),不计入连续会话失效判死阈值(`sessionStreak`)。
4. 在 `retry.go:179` 的 `sessionAliveCategory` 中补充 `CategoryTooFrequent`,只要服务端返回限流,说明账号凭证依然有效,避免 `sessionStreak` 在连续限流中虚假累积。
---
### 📦 工作包 2:积分基线与刚性对账体系(借鉴 dygou_go ScoreBaselineStore)
- **业务背景**:
抢购高并发下,常有边缘异常:客户端断网、RPC 超时、信封解析异常,但服务端其实已经扣除了积分并将礼包发放至背包。仅凭客户端是否收到 `category=success` 会发生严重漏单!
- **改进设计**:
1. 新增 `internal/sniper/score_baseline.go`(或 `internal/score/`):
- 数据文件:`scores.json`(保存在各实例的 `dataDir` 下)。
- 记录每个账号的基线积分及时间戳:`{"score": 1250, "at": 1729242000}`。
2. **基线更新时机**:
- 用户手动点击「查询积分」时批量更新并落盘。
- 导入/检查 Cookie 时自动更新。
3. **刚性对账(Verify / Reconcile)**:
- 抢购结束后(或用户随时点击「对账核对」):全量异步拉取一次所有账号的最新积分。
- 计算差值:`diff = baseline - current`。
- 若 `diff == target.Price`(或 `diff > 0`),即判定为“刚性扣分成功”,自动将原本标记为超时/未知的单子翻案为“成功”,补齐战报!
---
### 📦 工作包 3:战报持久化与 Excel / CSV 导出
- **业务背景**:
多账号操作、代抢代换必须给客户或管理员提供清晰的明细表格。当前版本任务一结束、窗口一关,明细就消失了,只能通过日志正则翻查,效率极低。
- **改进设计**:
1. 战报存储:每次抢购开始后,在实例数据目录下维护 `last_seckill_report.json`。
- 字段包含:`AccountUID`、`TargetPID`、`TargetName`、`Price`、`Status`(已抢到/售罄/限流/积分不足等)、`Attempts`、`FirstTime`、`SuccessTime`、`Duration`、`Msg`。
2. 导出功能(在 `internal/gui/app.go` 暴露 Wails 绑定方法):
- `ExportSeckillReportCSV() (string, error)`
- `ExportSeckillReportExcel() (string, error)`
3. 前端界面:
- 在作战表上方或「任务已结束」提示旁增加【导出战报】按钮,一键调出文件保存对话框。
---
### 📦 工作包 4:主备目标轮转(Priority Fallback)与售罄自动切换
- **业务背景**:
10.18 实战显示,最火爆的怪诞乔克(13433)在 10 秒即彻底售罄,而小黄鸭(13443)和天网(13435)在 15~20 秒依然有充沛库存。目前用户必须人工判断或多开不同实例去分别打。
- **改进设计**:
1. 支持配置主目标(Priority 1)与备选目标(Priority 2...)。
2. 在 `runAccountRound` 调度中:
- 默认只对主目标发起 `exchangeTarget`。
- 一旦主目标在当前实例被全量确认为售罄(`CategorySoldOut`),引擎自动标记主目标下线,账号无需停止,后续轮次立即自动无缝打向备选目标,把剩余的 20 秒窗口利用到底!