]> 127.0.0.1 Git - bili_danmu/.git/commitdiff
Fix api info更新使用wbi
authorqydysky <qydysky@foxmail.com>
Fri, 21 Apr 2023 19:47:34 +0000 (03:47 +0800)
committerqydysky <qydysky@foxmail.com>
Fri, 21 Apr 2023 19:47:34 +0000 (03:47 +0800)
F/api.go
F/api_test.go [new file with mode: 0644]
Json/nav.go
Reply/F.go
go.mod
go.sum

index 95098ee46425ef1f6f2122389e5c123f90f7b090..1a62f62064f295dcf893ca21ce3575dc77a4e3da 100644 (file)
--- a/F/api.go
+++ b/F/api.go
@@ -1,6 +1,7 @@
 package F
 
 import (
+       "crypto/md5"
        "encoding/json"
        "errors"
        "fmt"
@@ -16,6 +17,7 @@ import (
        c "github.com/qydysky/bili_danmu/CV"
        J "github.com/qydysky/bili_danmu/Json"
        "github.com/skratchdot/open-golang/open"
+       "golang.org/x/exp/slices"
 
        p "github.com/qydysky/part"
        file "github.com/qydysky/part/file"
@@ -23,6 +25,7 @@ import (
        g "github.com/qydysky/part/get"
        limit "github.com/qydysky/part/limit"
        reqf "github.com/qydysky/part/reqf"
+       psync "github.com/qydysky/part/sync"
        sys "github.com/qydysky/part/sys"
 
        "github.com/mdp/qrterminal/v3"
@@ -34,7 +37,13 @@ var api_limit = limit.New(2, "1s", "30s") //频率限制2次/s,最大等待时
 
 type GetFunc struct {
        *c.Common
-       l sync.RWMutex
+       cache psync.Map
+       l     sync.RWMutex
+}
+
+type cacheItem struct {
+       data     any
+       exceeded time.Time
 }
 
 func Get(c *c.Common) *GetFunc {
@@ -1116,66 +1125,85 @@ func (c *GetFunc) Get_guardNum() (missKey []string) {
 //     return
 // }
 
-func Info(UpUid int) (info J.Info) {
+func (c *GetFunc) Info(UpUid int) (J.Info, error) {
+       fkey := `Info`
+
+       if v, ok := c.cache.LoadV(fkey).(cacheItem); ok && v.exceeded.Before(time.Now()) {
+               return (v.data).(J.Info), nil
+       }
+
+       // 超额请求阻塞,超时将取消
        apilog := apilog.Base_add(`Info`)
        if api_limit.TO() {
-               return
-       } //超额请求阻塞,超时将取消
+               return J.Info{}, os.ErrDeadlineExceeded
+       }
 
-       //html
+       query := fmt.Sprintf("mid=%d&token=&platform=web&web_location=1550101", UpUid)
+       // wbi
+       {
+               v, e := c.GetNav()
+               if e != nil {
+                       return J.Info{}, e
+               }
+               wrid, wts := c.getWridWts(query, v.Data.WbiImg.ImgURL, v.Data.WbiImg.SubURL)
+               query += "&w_rid=" + wrid + "&wts=" + wts
+       }
+
+       // html
        {
                Cookie := make(map[string]string)
-               c.C.Cookie.Range(func(k, v interface{}) bool {
+               c.Cookie.Range(func(k, v interface{}) bool {
                        Cookie[k.(string)] = v.(string)
                        return true
                })
-               req := c.C.ReqPool.Get()
-               defer c.C.ReqPool.Put(req)
+               req := c.ReqPool.Get()
+               defer c.ReqPool.Put(req)
+
                if err := req.Reqf(reqf.Rval{
-                       Url:     `https://api.bilibili.com/x/space/acc/info?mid=` + strconv.Itoa(UpUid) + `&token=&platform=web&jsonp=jsonp`,
-                       Proxy:   c.C.Proxy,
+                       Url:     `https://api.bilibili.com/x/space/wbi/acc/info?` + query,
+                       Proxy:   c.Proxy,
                        Timeout: 10 * 1000,
                        Retry:   2,
                        Header: map[string]string{
+                               `Accept`: "application/json, text/plain, */*",
                                `Cookie`: reqf.Map_2_Cookies_String(Cookie),
                        },
                }); err != nil {
                        apilog.L(`E: `, err)
-                       return
+                       return J.Info{}, err
                }
 
+               var info J.Info
+
                //Info
-               {
-                       if e := json.Unmarshal(req.Respon, &info); e != nil {
-                               apilog.L(`E: `, e)
-                               return
-                       } else if info.Code != 0 {
-                               apilog.L(`E: `, info.Message)
-                               return
-                       }
+               if e := json.Unmarshal(req.Respon, &info); e != nil {
+                       apilog.L(`E: `, e)
+                       return J.Info{}, e
                }
+
+               c.cache.Store(fkey, cacheItem{
+                       data:     info,
+                       exceeded: time.Now().Add(time.Hour),
+               })
+               return info, nil
        }
-       return
 }
 
 // 调用记录
 var boot_Get_cookie funcCtrl.FlashFunc //新的替代旧的
 
 // 是否登录
-func (c *GetFunc) IsLogin() (isLogin bool) {
-       apilog := apilog.Base_add(`是否登录`)
-       //验证cookie
-       if missKey := CookieCheck([]string{
-               `bili_jct`,
-               `DedeUserID`,
-               `LIVE_BUVID`,
-       }); len(missKey) != 0 {
-               apilog.L(`T: `, `Cookie无Key:`, missKey)
-               return
+func (c *GetFunc) GetNav() (J.Nav, error) {
+       fkey := `GetNav`
+
+       if v, ok := c.cache.LoadV(fkey).(cacheItem); ok && v.exceeded.Before(time.Now()) {
+               return (v.data).(J.Nav), nil
        }
+
+       apilog := apilog.Base_add(`是否登录`)
        if api_limit.TO() {
                apilog.L(`E: `, `超时!`)
-               return
+               return J.Nav{}, os.ErrDeadlineExceeded
        } //超额请求阻塞,超时将取消
 
        Cookie := make(map[string]string)
@@ -1206,22 +1234,22 @@ func (c *GetFunc) IsLogin() (isLogin bool) {
                Retry:   2,
        }); err != nil {
                apilog.L(`E: `, err)
-               return
+               return J.Nav{}, err
        }
 
        var res J.Nav
 
        if e := json.Unmarshal(req.Respon, &res); e != nil {
                apilog.L(`E: `, e)
-               return
+               return J.Nav{}, e
        }
 
-       if res.Code != 0 {
-               apilog.L(`E: `, res.Message)
-               return
-       }
+       c.cache.Store(fkey, cacheItem{
+               data:     res,
+               exceeded: time.Now().Add(time.Hour),
+       })
 
-       return res.Data.IsLogin
+       return res, nil
 }
 
 // 扫码登录
@@ -1236,13 +1264,16 @@ func (c *GetFunc) Get_cookie() (missKey []string) {
                        if miss := CookieCheck([]string{
                                `bili_jct`,
                                `DedeUserID`,
-                       }); len(miss) == 0 && c.IsLogin() {
-
-                               //获取其他Cookie
-                               c.Get_other_cookie()
+                       }); len(miss) == 0 {
+                               if v, e := c.GetNav(); e != nil {
+                                       apilog.L(`E: `, e)
+                               } else if v.Data.IsLogin {
+                                       //获取其他Cookie
+                                       c.Get_other_cookie()
 
-                               apilog.L(`I: `, `已登录`)
-                               return
+                                       apilog.L(`I: `, `已登录`)
+                                       return
+                               }
                        }
                }
        }
@@ -2561,3 +2592,44 @@ func IsConnected() bool {
        apilog.L(`T: `, `已连接`)
        return true
 }
+
+// bilibili wrid wts 计算
+func (c *GetFunc) getWridWts(query string, imgURL, subURL string, customWts ...string) (w_rid, wts string) {
+       wbi := imgURL[strings.LastIndex(imgURL, "/")+1:strings.LastIndex(imgURL, ".")] +
+               subURL[strings.LastIndex(subURL, "/")+1:strings.LastIndex(subURL, ".")]
+
+       code := []int{46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5,
+               49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55,
+               40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57,
+               62, 11, 36, 20, 34, 44, 52}
+
+       s := []byte{}
+
+       for i := 0; i < len(code); i++ {
+               if code[i] < len(wbi) {
+                       s = append(s, wbi[code[i]])
+                       if len(s) >= 32 {
+                               break
+                       }
+               }
+       }
+
+       object := strings.Split(query, "&")
+
+       if len(customWts) == 0 {
+               wts = fmt.Sprintf("%d", time.Now().Unix())
+       } else {
+               wts = customWts[0]
+       }
+       object = append(object, "wts="+wts)
+
+       slices.Sort(object)
+
+       for i := 0; i < len(object); i++ {
+               object[i] = url.PathEscape(object[i])
+       }
+
+       w_rid = fmt.Sprintf("%x", md5.Sum([]byte(strings.Join(object, "&")+string(s))))
+
+       return
+}
diff --git a/F/api_test.go b/F/api_test.go
new file mode 100644 (file)
index 0000000..24b236f
--- /dev/null
@@ -0,0 +1,15 @@
+package F
+
+import "testing"
+
+func Test_getWridWts(t *testing.T) {
+       w_rid, _ := new(GetFunc).getWridWts(
+               "mid=11280430&token=&platform=web&web_location=1550101",
+               "https://i0.hdslb.com/bfs/wbi/e1be084baf3b4663b2465fca5bf1d889.png",
+               "https://i0.hdslb.com/bfs/wbi/0ae7d656b8114fe1901717dd092b7ee9.png",
+               "1682105747",
+       )
+       if w_rid != "766c2091b69102edb391bf16ef917d6c" {
+               t.Fatal()
+       }
+}
index 81deb92aacb609900e9787b6a1f1077dd82310b7..3443546094cd230fa16c798523e348e1d3bc2d18 100644 (file)
@@ -5,6 +5,104 @@ type Nav struct {
        Message string `json:"message"`
        TTL     int    `json:"ttl"`
        Data    struct {
-               IsLogin bool `json:"isLogin"`
+               IsLogin       bool   `json:"isLogin"`
+               EmailVerified int    `json:"email_verified"`
+               Face          string `json:"face"`
+               FaceNft       int    `json:"face_nft"`
+               FaceNftType   int    `json:"face_nft_type"`
+               LevelInfo     struct {
+                       CurrentLevel int    `json:"current_level"`
+                       CurrentMin   int    `json:"current_min"`
+                       CurrentExp   int    `json:"current_exp"`
+                       NextExp      string `json:"next_exp"`
+               } `json:"level_info"`
+               Mid            int     `json:"mid"`
+               MobileVerified int     `json:"mobile_verified"`
+               Money          float64 `json:"money"`
+               Moral          int     `json:"moral"`
+               Official       struct {
+                       Role  int    `json:"role"`
+                       Title string `json:"title"`
+                       Desc  string `json:"desc"`
+                       Type  int    `json:"type"`
+               } `json:"official"`
+               OfficialVerify struct {
+                       Type int    `json:"type"`
+                       Desc string `json:"desc"`
+               } `json:"officialVerify"`
+               Pendant struct {
+                       Pid               int    `json:"pid"`
+                       Name              string `json:"name"`
+                       Image             string `json:"image"`
+                       Expire            int    `json:"expire"`
+                       ImageEnhance      string `json:"image_enhance"`
+                       ImageEnhanceFrame string `json:"image_enhance_frame"`
+               } `json:"pendant"`
+               Scores       int    `json:"scores"`
+               Uname        string `json:"uname"`
+               VipDueDate   int64  `json:"vipDueDate"`
+               VipStatus    int    `json:"vipStatus"`
+               VipType      int    `json:"vipType"`
+               VipPayType   int    `json:"vip_pay_type"`
+               VipThemeType int    `json:"vip_theme_type"`
+               VipLabel     struct {
+                       Path                  string `json:"path"`
+                       Text                  string `json:"text"`
+                       LabelTheme            string `json:"label_theme"`
+                       TextColor             string `json:"text_color"`
+                       BgStyle               int    `json:"bg_style"`
+                       BgColor               string `json:"bg_color"`
+                       BorderColor           string `json:"border_color"`
+                       UseImgLabel           bool   `json:"use_img_label"`
+                       ImgLabelURIHans       string `json:"img_label_uri_hans"`
+                       ImgLabelURIHant       string `json:"img_label_uri_hant"`
+                       ImgLabelURIHansStatic string `json:"img_label_uri_hans_static"`
+                       ImgLabelURIHantStatic string `json:"img_label_uri_hant_static"`
+               } `json:"vip_label"`
+               VipAvatarSubscript int    `json:"vip_avatar_subscript"`
+               VipNicknameColor   string `json:"vip_nickname_color"`
+               Vip                struct {
+                       Type       int   `json:"type"`
+                       Status     int   `json:"status"`
+                       DueDate    int64 `json:"due_date"`
+                       VipPayType int   `json:"vip_pay_type"`
+                       ThemeType  int   `json:"theme_type"`
+                       Label      struct {
+                               Path                  string `json:"path"`
+                               Text                  string `json:"text"`
+                               LabelTheme            string `json:"label_theme"`
+                               TextColor             string `json:"text_color"`
+                               BgStyle               int    `json:"bg_style"`
+                               BgColor               string `json:"bg_color"`
+                               BorderColor           string `json:"border_color"`
+                               UseImgLabel           bool   `json:"use_img_label"`
+                               ImgLabelURIHans       string `json:"img_label_uri_hans"`
+                               ImgLabelURIHant       string `json:"img_label_uri_hant"`
+                               ImgLabelURIHansStatic string `json:"img_label_uri_hans_static"`
+                               ImgLabelURIHantStatic string `json:"img_label_uri_hant_static"`
+                       } `json:"label"`
+                       AvatarSubscript    int    `json:"avatar_subscript"`
+                       NicknameColor      string `json:"nickname_color"`
+                       Role               int    `json:"role"`
+                       AvatarSubscriptURL string `json:"avatar_subscript_url"`
+                       TvVipStatus        int    `json:"tv_vip_status"`
+                       TvVipPayType       int    `json:"tv_vip_pay_type"`
+               } `json:"vip"`
+               Wallet struct {
+                       Mid           int `json:"mid"`
+                       BcoinBalance  int `json:"bcoin_balance"`
+                       CouponBalance int `json:"coupon_balance"`
+                       CouponDueTime int `json:"coupon_due_time"`
+               } `json:"wallet"`
+               HasShop        bool   `json:"has_shop"`
+               ShopURL        string `json:"shop_url"`
+               AllowanceCount int    `json:"allowance_count"`
+               AnswerStatus   int    `json:"answer_status"`
+               IsSeniorMember int    `json:"is_senior_member"`
+               WbiImg         struct {
+                       ImgURL string `json:"img_url"`
+                       SubURL string `json:"sub_url"`
+               } `json:"wbi_img"`
+               IsJury bool `json:"is_jury"`
        } `json:"data"`
 }
index f6d42ae85d660d4de68320b526a2820849fea560..40c971a4025996061d9358900e136bc3e4ad9e76 100644 (file)
@@ -1013,7 +1013,13 @@ func Keep_medal_light() {
                        continue
                } //点亮状态
 
-               cacheInfo[v.TargetID] = F.Info(v.TargetID)
+               if info, e := F.Get(c.C).Info(v.TargetID); e != nil {
+                       flog.L(`E: `, e)
+                       return
+               } else {
+                       cacheInfo[v.TargetID] = info
+               }
+
                //两天内到期,发弹幕续期
                rand := p.Rand().MixRandom(0, int64(len(array)-1))
                send.Danmu_s(array[rand].(string), cacheInfo[v.TargetID].Data.LiveRoom.Roomid)
diff --git a/go.mod b/go.mod
index 437e201477d2a94549628547e21bf56564d73283..a0d8f393b6b8f049cda7a056e5e699000127be48 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -12,6 +12,8 @@ require (
        golang.org/x/text v0.9.0
 )
 
+require golang.org/x/exp v0.0.0-20230420155640-133eef4313cb
+
 require (
        github.com/andybalholm/brotli v1.0.5
        github.com/davecgh/go-spew v1.1.1 // indirect
diff --git a/go.sum b/go.sum
index 25c741106fe47f79fe4d3e61a79b3f2456d81458..f993bb07d7c2f7d6f3c7f37d0243461d02a321d7 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -40,6 +40,8 @@ github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYm
 github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
 github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
 github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+golang.org/x/exp v0.0.0-20230420155640-133eef4313cb h1:rhjz/8Mbfa8xROFiH+MQphmAmgqRM0bOMnytznhWEXk=
+golang.org/x/exp v0.0.0-20230420155640-133eef4313cb/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
 golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
 golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=