github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/client/web.go (about)

     1  package client
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/json"
     6  	"fmt"
     7  	"strings"
     8  
     9  	"github.com/pkg/errors"
    10  
    11  	"github.com/Mrs4s/MiraiGo/client/pb/web"
    12  	"github.com/Mrs4s/MiraiGo/internal/proto"
    13  	"github.com/Mrs4s/MiraiGo/utils"
    14  )
    15  
    16  type UnidirectionalFriendInfo struct {
    17  	Uin      int64
    18  	Nickname string
    19  	Age      uint32
    20  	Source   string
    21  }
    22  
    23  func (c *QQClient) GetUnidirectionalFriendList() (ret []*UnidirectionalFriendInfo, err error) {
    24  	webRsp := &struct {
    25  		BlockList []struct {
    26  			Uin         int64  `json:"uint64_uin"`
    27  			NickBytes   string `json:"bytes_nick"`
    28  			Age         uint32 `json:"uint32_age"`
    29  			Sex         uint32 `json:"uint32_sex"`
    30  			SourceBytes string `json:"bytes_source"`
    31  		} `json:"rpt_block_list"`
    32  		ErrorCode int32 `json:"ErrorCode"`
    33  	}{}
    34  	rsp, err := c.webSsoRequest("ti.qq.com", "OidbSvc.0xe17_0", fmt.Sprintf(`{"uint64_uin":%v,"uint64_top":0,"uint32_req_num":99,"bytes_cookies":""}`, c.Uin))
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	if err = json.Unmarshal(utils.S2B(rsp), webRsp); err != nil {
    39  		return nil, errors.Wrap(err, "unmarshal json error")
    40  	}
    41  	if webRsp.ErrorCode != 0 {
    42  		return nil, errors.Errorf("web sso request error: %v", webRsp.ErrorCode)
    43  	}
    44  	for _, block := range webRsp.BlockList {
    45  		decodeBase64String := func(str string) string {
    46  			b, err := base64.StdEncoding.DecodeString(str)
    47  			if err != nil {
    48  				return ""
    49  			}
    50  			return utils.B2S(b)
    51  		}
    52  		ret = append(ret, &UnidirectionalFriendInfo{
    53  			Uin:      block.Uin,
    54  			Nickname: decodeBase64String(block.NickBytes),
    55  			Age:      block.Age,
    56  			Source:   decodeBase64String(block.SourceBytes),
    57  		})
    58  	}
    59  	return
    60  }
    61  
    62  func (c *QQClient) DeleteUnidirectionalFriend(uin int64) error {
    63  	webRsp := &struct {
    64  		ErrorCode int32 `json:"ErrorCode"`
    65  	}{}
    66  	rsp, err := c.webSsoRequest("ti.qq.com", "OidbSvc.0x5d4_0", fmt.Sprintf(`{"uin_list":[%v]}`, uin))
    67  	if err != nil {
    68  		return err
    69  	}
    70  	if err = json.Unmarshal(utils.S2B(rsp), webRsp); err != nil {
    71  		return errors.Wrap(err, "unmarshal json error")
    72  	}
    73  	if webRsp.ErrorCode != 0 {
    74  		return errors.Errorf("web sso request error: %v", webRsp.ErrorCode)
    75  	}
    76  	return nil
    77  }
    78  
    79  func (c *QQClient) webSsoRequest(host, webCmd, data string) (string, error) {
    80  	s := strings.Split(host, `.`)
    81  	sub := ""
    82  	for i := len(s) - 1; i >= 0; i-- {
    83  		sub += s[i]
    84  		if i != 0 {
    85  			sub += "_"
    86  		}
    87  	}
    88  	cmd := "MQUpdateSvc_" + sub + ".web." + webCmd
    89  	req, _ := proto.Marshal(&web.WebSsoRequestBody{
    90  		Type: proto.Uint32(0),
    91  		Data: proto.Some(data),
    92  	})
    93  	rspData, err := c.sendAndWaitDynamic(c.uniPacket(cmd, req))
    94  	if err != nil {
    95  		return "", errors.Wrap(err, "send web sso request error")
    96  	}
    97  	rsp := &web.WebSsoResponseBody{}
    98  	if err = proto.Unmarshal(rspData, rsp); err != nil {
    99  		return "", errors.Wrap(err, "unmarshal response error")
   100  	}
   101  	return rsp.Data.Unwrap(), nil
   102  }