mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
feat search group
This commit is contained in:
parent
2d334747a2
commit
7aa30f1de7
@ -5,11 +5,15 @@ import (
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/profilecard"
|
||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
@ -45,6 +49,12 @@ type (
|
||||
SpecialTitleExpireTime int64
|
||||
Permission MemberPermission
|
||||
}
|
||||
|
||||
// GroupSearchInfo 通过搜索得到的群信息
|
||||
GroupSearchInfo struct {
|
||||
Code int64 // 群号
|
||||
Name string // 群名
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -109,14 +119,51 @@ func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) (uint16, []byte)
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
// SearchGroupByKeyword 通过关键词搜索陌生群组
|
||||
func (c *QQClient) SearchGroupByKeyword(keyword string) ([]GroupSearchInfo, error) {
|
||||
rsp, err := c.sendAndWait(c.buildGroupSearchPacket(keyword))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "group search failed")
|
||||
}
|
||||
return rsp.([]GroupSearchInfo), nil
|
||||
}
|
||||
|
||||
// SummaryCard.ReqSearch
|
||||
func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
comm, _ := proto.Marshal(&profilecard.BusiComm{
|
||||
Ver: proto.Int32(1),
|
||||
Seq: proto.Int32(rand.Int31()),
|
||||
Service: proto.Int32(80000001),
|
||||
Platform: proto.Int32(2),
|
||||
Qqver: proto.String("8.5.0.5025"),
|
||||
Build: proto.Int32(5025),
|
||||
})
|
||||
search, _ := proto.Marshal(&profilecard.AccountSearch{
|
||||
Start: proto.Int32(0),
|
||||
End: proto.Uint32(4),
|
||||
Keyword: &keyword,
|
||||
Highlight: []string{keyword},
|
||||
UserLocation: &profilecard.Location{
|
||||
Latitude: proto.Float64(0),
|
||||
Longitude: proto.Float64(0),
|
||||
},
|
||||
Filtertype: proto.Int32(0),
|
||||
})
|
||||
req := &jce.SummaryCardReqSearch{
|
||||
Keyword: keyword,
|
||||
CountryCode: "+86",
|
||||
Version: 3,
|
||||
ReqServices: [][]byte{},
|
||||
ReqServices: [][]byte{
|
||||
binary.NewWriterF(func(w *binary.Writer) {
|
||||
w.WriteByte(0x28)
|
||||
w.WriteUInt32(uint32(len(comm)))
|
||||
w.WriteUInt32(uint32(len(search)))
|
||||
w.Write(comm)
|
||||
w.Write(search)
|
||||
w.WriteByte(0x29)
|
||||
}),
|
||||
},
|
||||
}
|
||||
head := jce.NewJceWriter()
|
||||
head.WriteInt32(2, 0)
|
||||
@ -137,11 +184,12 @@ func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
|
||||
}
|
||||
|
||||
// SummaryCard.ReqSearch
|
||||
func decodeGroupSearchResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||
func decodeGroupSearchResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||
request := &jce.RequestPacket{}
|
||||
request.ReadFrom(jce.NewJceReader(payload))
|
||||
data := &jce.RequestDataVersion2{}
|
||||
data.ReadFrom(jce.NewJceReader(request.SBuffer))
|
||||
_ = ioutil.WriteFile("payload", payload, os.ModePerm)
|
||||
if len(data.Map["RespHead"]["SummaryCard.RespHead"]) > 20 {
|
||||
return nil, errors.New("not found")
|
||||
}
|
||||
@ -154,7 +202,23 @@ func decodeGroupSearchResponse(c *QQClient, _ uint16, payload []byte) (interface
|
||||
ld2 := sr.ReadInt32()
|
||||
if ld1 > 0 && ld2+9 < int32(len(rspService)) {
|
||||
sr.ReadBytes(int(ld1)) // busi comm
|
||||
//searchPb := sr.ReadBytes(int(ld2)) //TODO: search pb decode
|
||||
searchPb := sr.ReadBytes(int(ld2))
|
||||
searchRsp := profilecard.AccountSearch{}
|
||||
err := proto.Unmarshal(searchPb, &searchRsp)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get search result failed")
|
||||
}
|
||||
var ret []GroupSearchInfo
|
||||
for _, g := range searchRsp.GetList() {
|
||||
ret = append(ret, GroupSearchInfo{
|
||||
Code: int64(g.GetCode()),
|
||||
Name: g.GetName(),
|
||||
})
|
||||
}
|
||||
for _, fp := range ret {
|
||||
fmt.Println(fp.Name, ":", fp.Code)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
1038
client/pb/profilecard/accountsearch.pb.go
Normal file
1038
client/pb/profilecard/accountsearch.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
105
client/pb/profilecard/accountsearch.proto
Normal file
105
client/pb/profilecard/accountsearch.proto
Normal file
@ -0,0 +1,105 @@
|
||||
syntax = "proto2";
|
||||
|
||||
option go_package = ".;profilecard";
|
||||
|
||||
/*
|
||||
message Color {
|
||||
optional uint32 r = 1;
|
||||
optional uint32 g = 2;
|
||||
optional uint32 b = 3;
|
||||
}
|
||||
|
||||
message Label {
|
||||
optional bytes name = 1;
|
||||
optional Color textColor = 3;
|
||||
optional Color edgingColor = 4;
|
||||
optional uint32 labelAttr = 5;
|
||||
optional uint32 labelType = 6;
|
||||
}
|
||||
*/
|
||||
|
||||
message Location {
|
||||
optional double latitude = 1;
|
||||
optional double longitude = 2;
|
||||
}
|
||||
|
||||
message ResultItem {
|
||||
optional bytes feedId = 1;
|
||||
optional bytes name = 2;
|
||||
optional bytes picUrl = 3;
|
||||
optional bytes jmpUrl = 4;
|
||||
optional bytes feedType = 5;
|
||||
optional bytes summary = 6;
|
||||
optional bytes hasVideo = 7;
|
||||
optional bytes phtotUpdate = 8;
|
||||
optional uint64 uin = 9;
|
||||
optional bytes resultId = 10;
|
||||
optional uint32 ftime = 11;
|
||||
optional bytes nickName = 12;
|
||||
repeated bytes picUrlList = 13;
|
||||
optional uint32 totalPicNum = 14;
|
||||
}
|
||||
|
||||
message hotwordrecord {
|
||||
optional string hotword = 1;
|
||||
optional uint32 hotwordType = 2;
|
||||
optional string hotwordCoverUrl = 3;
|
||||
optional string hotwordTitle = 4;
|
||||
optional string hotwordDescription = 5;
|
||||
}
|
||||
|
||||
message AccountSearchRecord {
|
||||
optional uint64 uin = 1;
|
||||
optional uint64 code = 2;
|
||||
optional uint32 source = 3;
|
||||
optional string name = 4;
|
||||
optional uint32 sex = 5;
|
||||
optional uint32 age = 6;
|
||||
optional string accout = 7;
|
||||
optional string brief = 8;
|
||||
optional uint32 number = 9;
|
||||
optional uint64 flag = 10;
|
||||
optional uint64 relation = 11;
|
||||
optional string mobile = 12;
|
||||
optional bytes sign = 13;
|
||||
optional uint32 country = 14;
|
||||
optional uint32 province = 15;
|
||||
optional uint32 city = 16;
|
||||
optional uint32 classIndex = 17;
|
||||
optional string className = 18;
|
||||
optional string countryName = 19;
|
||||
optional string provinceName = 20;
|
||||
optional string cityName = 21;
|
||||
optional uint32 accountFlag = 22;
|
||||
optional string titleImage = 23;
|
||||
optional string articleShortUrl = 24;
|
||||
optional string articleCreateTime = 25;
|
||||
optional string articleAuthor = 26;
|
||||
optional uint64 accountId = 27;
|
||||
//repeated Label groupLabels = 30;
|
||||
optional uint32 videoAccount = 31;
|
||||
optional uint32 videoArticle = 32;
|
||||
optional int32 uinPrivilege = 33;
|
||||
optional bytes joinGroupAuth = 34;
|
||||
optional bytes token = 500;
|
||||
optional uint32 richflag1_59 = 40603;
|
||||
optional uint32 richflag4_409 = 42409;
|
||||
}
|
||||
|
||||
message AccountSearch {
|
||||
optional int32 start = 1;
|
||||
optional uint32 count = 2;
|
||||
optional uint32 end = 3;
|
||||
optional string keyword = 4;
|
||||
repeated AccountSearchRecord list = 5;
|
||||
repeated string highlight = 6;
|
||||
optional Location userLocation = 10;
|
||||
optional bool locationGroup = 11;
|
||||
optional int32 filtertype = 12;
|
||||
//repeated C33304record recommendList = 13;
|
||||
optional hotwordrecord hotwordRecord = 14;
|
||||
optional string articleMoreUrl = 15;
|
||||
repeated ResultItem resultItems = 16;
|
||||
optional bool keywordSuicide = 17;
|
||||
optional bool exactSearch = 18;
|
||||
}
|
@ -38,7 +38,7 @@ func (c *QQClient) GetAllowedClients() ([]*OtherClientInfo, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// RefreshClientStatus 刷新客户端状态
|
||||
// RefreshStatus 刷新客户端状态
|
||||
func (c *QQClient) RefreshStatus() error {
|
||||
_, err := c.sendAndWait(c.buildGetOfflineMsgRequest())
|
||||
return err
|
||||
|
Loading…
x
Reference in New Issue
Block a user