yml2213 0294606807 参考 dygou_go 优化抢购调度:请求级并发闸门、售罄继续探测与任务汇总
- 并发额度下沉到单次请求:runState.sem 只覆盖一次在途请求(列表/兑换/刷新),账号在退避等待期间释放额度;旧实现把额度给整个账号循环,退避中的账号一直霸占额度,账号多时互相饿死
- 售罄不再默认终止:normalizeConfig 去掉 StopOnSoldOut 默认 true,售罄按退避继续探测到轮次结束(别人取消或锁单过期会让库存回流);CategoryOffShelf 拆成独立分支,下架/不存在仍终止该奖品;删除已无意义的 ContinueOnSoldOut
- 退避统一加 0-25% 抖动(jitterDuration,只往上抖,配置值仍是下限),避免多账号在同一时刻整批重试形成周期尖峰
- 新增 Runner.OnSummary/RunSummary:轮次、账号、目标、耗时、列表/兑换/积分/记录请求次数、成功账号数与结局分布(按次数排序),在 refresh.Wait() 之后回调;CLI 与 GUI 各输出一行汇总加逐类结局
- 取消清理:等待额度的账号返回 action=exchange_canceled 且调用方直接返回,停止监控时不再为每个排队账号刷错误结果
- http 传输补连接池参数(MaxConnsPerHost=64、MaxIdleConns=128、MaxIdleConnsPerHost=64、IdleConnTimeout=30s),多账号不再反复重建连接
- CLI/GUI 的 waitUntil 从 200ms 轮询改为一次性定时器,消除 0-200ms 随机延迟(正好错过开抢窗口)
- GUI 抽出 runnerConfig(),用 ListBeforeExchange=!DirectExchange 表达界面语义,修复「直接兑换」开关失效(旧实现被引擎强制回落直兑,价格/库存过滤不生效)
- 测试:sniper 新增售罄继续探测、StopOnSoldOut 即停、下架终止、在途请求数等于并发数、汇总含刷新请求、抖动区间等用例;GUI 新增 runnerConfig 用例;README 补「抢购调度与退避(2026-10-16 调整)」
2026-10-16 16:06:49 +08:00

huya-go

虎牙活动积分兑换/抢购的 Go 复刻版。支持两种传输层,CLI 与 GUI 默认都走 wss:

  • wss(默认):浏览器实际使用的通道。先调用 launch.queryHttpDns 解析可用 host,再走 TAF WebSocketCommand 外层与 WSS 初始化流程(launch.wsLaunch → mobileui.getConfig)。host 留空即自动解析,解析失败会回退内置默认 host。
  • http:走 https://cdnws.api.huya.com/,作为可回退通道;CLI 用 -transport http,GUI 在设置里切换。

构建

CLI:

go test ./...
go build -o huya-go ./cmd/huya-go

GUI:

cd frontend
npm install
npm run typecheck
cd ..
wails build -debug -nopackage

GUI 二进制输出到 build/bin/huya-gui。开发时可以使用 wails dev 启动 Wails + React + Ant Design 界面。

Windows exe(文件名带版本号):

./scripts/build-windows.sh          # 默认 windows/amd64
./scripts/build-windows.sh arm64    # 如需 windows/arm64

产物为 build/bin/huya-gui-v<版本>.exe(PE32+ GUI)。版本号的单一来源是 internal/version/version.go:脚本从这里读取版本号,既拼进 exe 文件名,也通过 -ldflags "-X huya-go/internal/version.Version=..." 编译进程序,界面左下角的版本标签来自同一个值。发布新版本时改这一处,并同步 wails.json 的 info.productVersion(只影响 exe 文件属性)。在 macOS 上交叉编译不会生成 NSIS 安装包(-nopackage),只产出 exe。

推荐把账号 Cookie 放到本地文件,一行一个账号:

yyuid=...; udb_uid=...; guid=...; ...

不要把 Cookie、token、JWT 提交到仓库或写进文档。

常用命令

GUI 界面提供账号预览、奖品列表、积分查询、兑换记录、直接兑换、监控抢购、实时日志。

CLI 示例:

查询奖品列表:

./huya-go -cmd list -sid 2203 -cookie-file cookie.txt

查询积分:

./huya-go -cmd score -sid 2203 -cookie-file cookie.txt

直接兑换指定 PID:

./huya-go -cmd exchange -sid 2203 -pid 12889 -cookie-file cookie.txt

按奖品名轮询并抢购:

./huya-go -cmd monitor -sid 2203 -name 小黄鸭 -cookie-file cookie.txt -loops 20 -delay 120 -concurrency 5

定时开始:

./huya-go -cmd monitor -sid 2203 -pid 12889 -cookie-file cookie.txt -at "2026-07-06 20:00:00"

以上默认都走 wss。需要回退到 http 传输时,给任意命令加上 -transport http。

多开(多实例)

同一台机器可以同时启动多个实例,互不干扰:

  • 启动时按顺序占用「实例槽位」并加独占锁:第 1 个进程是默认实例(沿用历史数据目录),第 2 个及以后分别是 实例 2、实例 3…,数据目录为 <数据目录>/instances/instance-N。
  • 每个实例独占自己的日志目录与 WebView2 用户数据目录,所以多开时日志不会交错,Windows 上也不会出现「第二个窗口开不出来」。
  • 界面本地存储(账号、设置、商品缓存)按实例分片,每个实例各存各的账号;标题栏会显示当前实例名。
  • 槽位锁在进程退出时自动释放;若锁目录不可写,会退回到「进程唯一」的临时实例目录(日志降级为仅内存),绝不退回默认目录,以免两个进程互相覆盖。
  • 环境变量:HUYA_DATA_DIR 覆盖数据根目录,HUYA_LOG_DIR 覆盖日志目录,HUYA_LOG_LEVEL 覆盖默认日志等级。

日志

GUI 与 CLI 共用同一套结构化日志(分类 + 等级 + 账号标签),同时输出到界面与磁盘:

  • 路径:<数据目录>/logs/huya-go_<实例标识>_<时间戳>.log。macOS 数据目录为 ~/Library/Application Support/huya-go,Windows 为 %AppData%\huya-go。
  • 每次启动创建独立文件(O_EXCL 抢占,重名自动加 -2 后缀),所以多开或同秒重启都不会写进同一个文件;文件开头写明实例名、数据目录与格式说明。
  • 单文件上限 5MB,超出后滚动为 .1 ~ .5,最旧的被丢弃。
  • 每行格式:时间 [分类][等级][账号] 正文。逐条网络请求是 debug 级,默认不记录,可在界面「日志」页签打开「调试」开关,或 CLI 使用 -log-level debug。
  • 写盘是异步且队列有界:队列满时丢弃日志并在文件尾部与界面提示丢弃条数,避免磁盘 I/O 拖慢抢购链路。
  • 界面「日志」页签支持按等级筛选、按 ID 增量拉取、一键打开日志目录或复制路径。
  • GUI 启动失败(例如 WebView2 建不出环境)时,<用户缓存目录>/huya-go/startup.log 会记录原因。

参数说明

  • -cmd:list、score、records、exchange、monitor。
  • -sid:活动 SID,必填。
  • -pid:奖品 PID。exchange 必填,monitor 可用 -pid 或 -name。
  • -max-price:目标奖品最高积分,0 表示不限制(CLI 与 GUI 设置都支持)。
  • -min-left:目标奖品最少剩余库存,0 表示不限制(CLI 与 GUI 设置都支持)。
  • -category:类目过滤,支持类目名(如 限量返场、精英专享)或类目 id(如 99);留空表示不限。
  • -category-only:list 只输出该类目的商品(配合 -category 使用)。
  • -cookie:单账号 Cookie。
  • -cookie-file:多账号 Cookie 文件。
  • -transport:wss 或 http,默认 wss。
  • -wss-host:WebSocket host。默认留空,自动调用 launch.queryHttpDns 解析(带 TTL 缓存、多 host 轮询),解析失败时回退内置默认 host;需要固定时可显式指定。
  • -timeout:单次调用超时秒数。
  • -loops、-delay、-concurrency:轮询次数、轮询间隔、并发额度。-concurrency 限制的是同时在途的请求数(不是同时运行的账号数),账号在退避等待期间不占用额度。
  • -stop-after-success:monitor 中任一账号成功后是否停止。
  • -log-dir:日志目录,默认使用应用数据目录下的 logs。
  • -log-level:日志最低等级,debug/info/warn/error,默认 info。
  • -v:输出调试日志(等价于 -log-level debug,并把网络日志同时打到 stderr)。

抢购调度与退避(2026-10-16 调整)

参考 dygou_go 的抢购调度经验(该项目的实测复盘结论)做了以下调整:

  • 并发额度按单次请求计:额度只覆盖一次在途请求,账号在退避等待期间释放额度。旧实现把额度给整个账号循环,退避中的账号会一直霸占额度,账号多时互相饿死。
  • 售罄不再默认终止:服务端回「已抢完 / 库存不足」时继续按退避节奏探测到轮询结束——别人锁单未支付或取消会让库存回流。需要「售罄即停」时显式设置 Config.StopOnSoldOut。
  • 下架仍然终止:已下架 / 奖品不存在 视为本窗口内的终态,直接停止该奖品(与售罄区别对待)。
  • 积分不足仍然终止:积分不会自己变多,默认 StopOnNotEnough,避免无意义的重复请求。
  • 退避带抖动:所有退避(限频 / 失败 / 售罄探测)在配置值基础上叠加 0-25% 随机抖动,避免多个账号在同一时刻整批重试形成周期性尖峰;配置值始终是退避下限。
  • 定时精确触发:定时开抢改用一次性定时器(旧实现按 200ms 轮询,醒来时刻会随机晚 0-200ms,正好错过开抢窗口)。-lead 仍用于按 RTT 提前起跑。
  • 任务结束汇总:每次监控结束输出一行汇总(轮次 / 账号 / 目标 / 成功账号 / 耗时 / 请求次数)与按次数排序的结局分布(success、sold_out、too_frequent、not_found 等),便于复盘。
  • HTTP 传输连接池:http 传输补上 MaxConnsPerHost=64、MaxIdleConnsPerHost=64(Go 默认每主机只有 2 个空闲连接),多账号并发时不再反复重建连接。

已确认的小黄鸭参数

2026-07-06 浏览器手动抢购抓包确认:

  • sid=2203
  • pid=12889
  • 奖品名:套装-潮萌小黄鸭
  • 消耗积分:988

远端配置里的子奖品代码不能直接当兑换 PID,实际兑换以 scoreExchangePrize 请求里的 pid 为准。

精英宝典/幸运币(2026-10-13 抓包)

m-shop.huya.com 积分中心的兑换记录里确认到:

  • sid=2277
  • pid=13409
  • 奖品名:幸运币礼包(小)
  • 消耗积分:20
  • 订单号格式:sOrderId_2277_13409_<uid>_<时间戳>_<随机>

该活动的列表/积分/兑换接口与 sid=2203 走同一套 webActUI,可直接用 -cmd list -sid 2277 验证;同一次抓包里「开通精英宝典 / 购买精英币」属于商城付费链路(shopMiddleUI.* + 支付宝),本项目未实现,详见 WSS_NOTES.md。

商品类目:限量返场 / 精英专享(2026-10-15 抓包)

webActUI.getActPrizeList 的响应除商品外还下发类目字典(tRsp.4),每件商品用 tags(TAF tag14) 标注归属:101=精英专享、99=限量返场。2026-10-15 真号实测 sid=2277:

  • 共 30 件商品:限量返场(99) 12 件(怪诞乔克服装礼包 8000 积分、天网终结者大礼包 4800 积分、潮萌小黄鸭系列…)+ 精英专享(101) 18 件(幸运币/荣耀勋章礼包、套装…)。
  • sid=2203(上一期活动)已停止下发商品,列表为空,需要把 SID 切到 2277。
  • 限量返场是「预告上架」类商品:start_time(TAF tag25,实测 2026-10-16 17:00:00)与 end_time(tag26)决定 可兑换时间窗,页面上的「xx:xx:xx 后上架」倒计时就来自它;daily_start/daily_end(tag27/28)是每日可兑时段。

用法:

# 全量列表(日志里会打出「类目=精英专享(101)=18项/限量返场(99)=12项」)
./huya-go -cmd list -sid 2277 -cookie-file cookies.txt

# 只看限量返场(也支持类目 id 或模糊名,如 -category 99 / -category 返场)
./huya-go -cmd list -sid 2277 -cookie-file cookies.txt -category 限量返场 -category-only

# 抢购时限定只在该类目里选品(配合 -auto)
./huya-go -cmd monitor -sid 2277 -cookie-file cookies.txt -category 限量返场 -auto

界面「商品列表」同样按类目分了页签(全部 / 限量返场 / 精英专享,带商品数),每行标注类目, 未上架的商品显示上架时间与倒计时;当前选中的类目会一起提交给监控,用作自动选品的范围。

S
Description
No description provided
Readme
20 MiB
Languages
Go 72.2%
TypeScript 23.4%
CSS 2.3%
JavaScript 1.8%
Shell 0.2%