fix: peacematch 兑换用 multipart/form-data(与抓包一致)
根据实际兑换抓包修正: - Content-Type 从 urlencoded 改回 multipart/form-data(浏览器实际用 multipart) - postMultipart 支持组合 token csrf\x00ctn,自动拆分并合并 cvl_csrf_token+acf_ccn 到 Cookie - 移除不再需要的 postForm 方法和 net/url 导入 - 验证:表单字段(manualID/commodityID/num/rid/ctn)与抓包完全一致, storedetail 确认无 preExchange 字段(时间校准修复正确) 抓包来源:/Users/yml/Desktop/抓包/douyu/7.29/电竞手册-兑换并查询信息与积分.har
This commit is contained in:
+15
-42
@@ -7,7 +7,6 @@ import (
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -430,7 +429,7 @@ func (c *DouyuClient) Exchange(cookie, commodityID string, csrf *string) (string
|
||||
} `json:"data"`
|
||||
}
|
||||
if c.Activity.UseCTN {
|
||||
// 电竞手册:用 ctn(acf_ccn) 鉴权,urlencoded 表单
|
||||
// 电竞手册:用 ctn(acf_ccn) 鉴权,multipart 表单(与浏览器抓包一致)
|
||||
ctn := ""
|
||||
if csrf != nil {
|
||||
parts := strings.SplitN(*csrf, "\x00", 2)
|
||||
@@ -446,7 +445,7 @@ func (c *DouyuClient) Exchange(cookie, commodityID string, csrf *string) (string
|
||||
}
|
||||
ctn = ctnVal
|
||||
}
|
||||
if err := c.postForm(c.Activity.ExchangeURL, cookie, csrf, "正式兑换", map[string]string{
|
||||
if err := c.postMultipart(c.Activity.ExchangeURL, cookie, csrf, "正式兑换", map[string]string{
|
||||
"manualID": c.Activity.ManualID,
|
||||
"commodityID": commodityID,
|
||||
"num": "1",
|
||||
@@ -558,11 +557,22 @@ func (c *DouyuClient) postMultipart(url, cookie string, csrf *string, label stri
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 处理组合 token:csrf\x00ctn(电竞手册用 ctn 鉴权时)
|
||||
// 拆分后 cvl_csrf_token 和 acf_ccn 都合并到 Cookie 头
|
||||
currentCSRF := ""
|
||||
ctnVal := ""
|
||||
if csrf != nil {
|
||||
currentCSRF = *csrf
|
||||
parts := strings.SplitN(*csrf, "\x00", 2)
|
||||
currentCSRF = parts[0]
|
||||
if len(parts) > 1 {
|
||||
ctnVal = parts[1]
|
||||
}
|
||||
}
|
||||
c.setBrowserHeaders(req, utils.MergeCookie(cookie, "cvl_csrf_token", currentCSRF))
|
||||
mergedCookie := utils.MergeCookie(cookie, "cvl_csrf_token", currentCSRF)
|
||||
if ctnVal != "" {
|
||||
mergedCookie = utils.MergeCookie(mergedCookie, "acf_ccn", ctnVal)
|
||||
}
|
||||
c.setBrowserHeaders(req, mergedCookie)
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
resp, err := c.doJSON(req, out, label)
|
||||
if resp != nil {
|
||||
@@ -570,43 +580,6 @@ func (c *DouyuClient) postMultipart(url, cookie string, csrf *string, label stri
|
||||
if nextCSRF != *csrf {
|
||||
logger.LogEvent("网络", "info", "响应刷新CSRF已同步: %s %s %s", label, req.Method, requestPath(req))
|
||||
}
|
||||
*csrf = nextCSRF
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// postForm 发送 application/x-www-form-urlencoded POST 请求。
|
||||
// 用于电竞手册等使用 ctn 鉴权的活动。
|
||||
// csrf 参数为组合值 "cvl_csrf_token\x00acf_ccn",两者都会合并到 Cookie 头。
|
||||
func (c *DouyuClient) postForm(targetURL, cookie string, csrf *string, label string, fields map[string]string, out any) error {
|
||||
vals := url.Values{}
|
||||
for k, v := range fields {
|
||||
vals.Set(k, v)
|
||||
}
|
||||
req, err := http.NewRequest("POST", targetURL, strings.NewReader(vals.Encode()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 拆分组合 token,合并到 Cookie
|
||||
csrfVal := ""
|
||||
ctnVal := ""
|
||||
if csrf != nil {
|
||||
parts := strings.SplitN(*csrf, "\x00", 2)
|
||||
csrfVal = parts[0]
|
||||
if len(parts) > 1 {
|
||||
ctnVal = parts[1]
|
||||
}
|
||||
}
|
||||
mergedCookie := utils.MergeCookie(cookie, "cvl_csrf_token", csrfVal)
|
||||
if ctnVal != "" {
|
||||
mergedCookie = utils.MergeCookie(mergedCookie, "acf_ccn", ctnVal)
|
||||
}
|
||||
c.setBrowserHeaders(req, mergedCookie)
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
|
||||
resp, err := c.doJSON(req, out, label)
|
||||
if resp != nil && csrf != nil {
|
||||
if nextCSRF := csrfFromResponse(resp); nextCSRF != "" {
|
||||
if ctnVal != "" {
|
||||
*csrf = nextCSRF + "\x00" + ctnVal
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user