Files
yml2213 1f76c12b48 精英手册改为锁单支付并发布0.2.2
- 精英手册兑换改为 createExchangeOrder 锁单后 payExchangeOrder 支付,不再查询商品状态与预兑
- 电竞手册保留直接兑换,标准模式重新取鉴权,激进模式复用鉴权
- csrfToken 优先复用 Cookie,校验失败自动刷新后重试一次
- 锁单支付按频控/通用退避表重试,临近过期不再重试
- 定时复校发现抢购已开始则不再改写触发时刻
- 升级 wails 至 v2.15.0
2026-09-30 20:35:44 +08:00

146 lines
5.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package activity
import "douyu_go/internal/constants"
// Activity 描述一个斗鱼手册活动的全部接口参数。
//
// 不同活动(精英手册 / 电竞手册)的 manualID、roomID、actAlias 以及接口路径段都不同,
// 集中在这里可以让调度核心逻辑保持活动无关,新增活动只需在 registry 中加一项。
//
// 注意:peacematch 的 storehome / storedetail / exchange / exchangeList / score / bindInfo
// 已在 7.29「电竞手册-兑换并查询信息与积分.har」中验证;batchExchangeLimit / preExchange
// 在 UseCTN=true 时运行时跳过,字段仅保留为旧流程兼容,不视为已验证端点。
type Activity struct {
ID string // 注册表 key,例如 "peace" / "peacematch"
DisplayName string // 前端展示名
ManualID string
RoomID string
ActAlias string
BaseURL string
ShopReferer string
StoreHomeURL string
CSRFURL string
IsXiaodian bool // 和平小店商品列表使用 QQ 道具接口和响应格式。
ActID string // 和平小店道具活动 ID。
RoleParamURL string // 和平小店 H5 临时授权接口。
RoleURL string // 和平小店角色解析接口。
BatchLimitURL string
PreExchangeURL string
ExchangeURL string
ExchangeListURL string
// 精英手册正式兑换是锁单再支付。电竞手册仍走 ExchangeURL。
CreateOrderURL string
PayOrderURL string
BindInfoURL string
ScoreURL string
ScoreMethod string // "POST" 或 "GET"
// UseCTN 为 true 时(电竞手册),兑换接口用 ctn(acf_ccn) 鉴权而非 csrfToken:
// - multipart 表单发 ctn 字段(值=acf_ccn),不发 csrfToken
// - Cookie 已有 acf_ccn 时直接复用,缺失时再请求 CTNURL
// - 跳过 batchExchangeLimit / preExchange(Python 实现直接调 exchange)
UseCTN bool
CTNURL string // 获取 acf_ccn 的接口(UseCTN=true 时必填)
}
const douyuBase = constants.BaseURL
// peace 精英手册(旧活动,ActAlias=20260120QYOOB)。
var peace = &Activity{
ID: "peace",
DisplayName: "精英手册",
ManualID: "G4KA4Qnz4LDp7",
RoomID: "9263298",
ActAlias: "20260120QYOOB",
BaseURL: douyuBase,
ShopReferer: douyuBase + "/pages/live-peace-handbook/web/shop?ditchname=pass0&roomId=9263298",
StoreHomeURL: douyuBase + "/wgapi/ordnc/activity/peace/storehome?manualID=G4KA4Qnz4LDp7&rid=9263298",
CSRFURL: douyuBase + "/japi/carnival/nc/common/generateCsrf",
BatchLimitURL: douyuBase + "/wgapi/ordnc/activity/peace/batchExchangeLimit",
PreExchangeURL: douyuBase + "/wgapi/ordnc/activity/peace/preExchange",
ExchangeURL: douyuBase + "/wgapi/ordnc/activity/peace/exchange",
CreateOrderURL: douyuBase + "/wgapi/ordnc/activity/peace/createExchangeOrder",
PayOrderURL: douyuBase + "/wgapi/ordnc/activity/peace/payExchangeOrder",
ExchangeListURL: douyuBase + "/wgapi/ordnc/activity/peace/exchangeList?manualID=G4KA4Qnz4LDp7&limit=100&offset=0",
BindInfoURL: douyuBase + "/japi/carnivalApi/v2/tencent/bindInfo?actAlias=20260120QYOOB",
ScoreURL: douyuBase + "/japi/oms/web/peace/credit/balance",
ScoreMethod: "POST",
UseCTN: false,
}
// peacematch 电竞手册(新活动,ActAlias=20260226ZMGDG)。
// 数据来源:/Users/yml/Desktop/抓包/douyu/7.29/电竞手册-兑换并查询信息与积分.har。
var peacematch = &Activity{
ID: "peacematch",
DisplayName: "电竞手册",
ManualID: "1W0yGkOdDbAXb",
RoomID: "9263298",
ActAlias: "20260226ZMGDG",
BaseURL: douyuBase,
ShopReferer: douyuBase + "/pages/live-peace-pel/web/shop?roomId=9263298&isAnchorSide=0",
StoreHomeURL: douyuBase + "/wgapi/ordnc/activity/peacematch/storehome?manualID=1W0yGkOdDbAXb&rid=9263298",
// generateCsrf 为精英手册使用的嘉年华平台级接口;UseCTN=true 时不会调用。
CSRFURL: douyuBase + "/japi/carnival/nc/common/generateCsrf",
// batchExchangeLimit / preExchange 在 UseCTN=true 时跳过;exchange 已由 7.29 HAR 验证。
BatchLimitURL: douyuBase + "/wgapi/ordnc/activity/peacematch/batchExchangeLimit",
PreExchangeURL: douyuBase + "/wgapi/ordnc/activity/peacematch/preExchange",
ExchangeURL: douyuBase + "/wgapi/ordnc/activity/peacematch/exchange",
ExchangeListURL: douyuBase + "/wgapi/ordnc/activity/peacematch/exchangeList?manualID=1W0yGkOdDbAXb&limit=100&offset=0",
BindInfoURL: douyuBase + "/wgapi/ordnc/live/memberthird/tencent/bindInfo?actAlias=20260226ZMGDG",
ScoreURL: douyuBase + "/wgapi/ordnc/activity/peacematch/score/balance",
ScoreMethod: "GET",
UseCTN: true,
CTNURL: douyuBase + "/wgapi/livenc/liveweb/csrfApi/getCsrfCookie",
}
// xiaodian 和平小店。商品查询前自动从斗鱼 Cookie 获取角色上下文。
var xiaodian = &Activity{
ID: "xiaodian",
DisplayName: "和平小店",
RoomID: "9263298",
ActAlias: "20260623KDQFH",
ActID: "46195",
BaseURL: "https://app.daoju.qq.com",
ShopReferer: "https://app.daoju.qq.com/",
StoreHomeURL: "https://apps.game.qq.com/daoju/v3/recommend_xn_live_cjm/common",
RoleParamURL: "https://www.douyu.com/japi/carnival/nc/txEmbed/getIframeUrl",
RoleURL: "https://apps.game.qq.com/daoju/igw/live",
BindInfoURL: "https://www.douyu.com/japi/carnivalApi/v2/tencent/bindInfo",
IsXiaodian: true,
}
var registry = map[string]*Activity{
peace.ID: peace,
peacematch.ID: peacematch,
xiaodian.ID: xiaodian,
}
// DefaultActivityID 是新建配置时默认打开的活动。
const DefaultActivityID = "xiaodian"
// List 返回所有注册活动,按注册顺序(精英手册在前)。
func List() []*Activity {
return []*Activity{peace, peacematch, xiaodian}
}
// Get 按 ID 获取活动;不存在时返回 nil。
func Get(id string) *Activity {
if id == "" {
return nil
}
return registry[id]
}
// Default 返回默认活动。
func Default() *Activity {
if a := registry[DefaultActivityID]; a != nil {
return a
}
return peace
}