mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
Merge pull request #114 from wdvxdr1123/patch/group_search
feat search group
This commit is contained in:
commit
8ff4c89539
@ -5,10 +5,12 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/profilecard"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
"math/rand"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -45,6 +47,12 @@ type (
|
|||||||
SpecialTitleExpireTime int64
|
SpecialTitleExpireTime int64
|
||||||
Permission MemberPermission
|
Permission MemberPermission
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GroupSearchInfo 通过搜索得到的群信息
|
||||||
|
GroupSearchInfo struct {
|
||||||
|
Code int64 // 群号
|
||||||
|
Name string // 群名
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -109,14 +117,51 @@ func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) (uint16, []byte)
|
|||||||
return seq, packet
|
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
|
// SummaryCard.ReqSearch
|
||||||
func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
|
func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
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{
|
req := &jce.SummaryCardReqSearch{
|
||||||
Keyword: keyword,
|
Keyword: keyword,
|
||||||
CountryCode: "+86",
|
CountryCode: "+86",
|
||||||
Version: 3,
|
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 := jce.NewJceWriter()
|
||||||
head.WriteInt32(2, 0)
|
head.WriteInt32(2, 0)
|
||||||
@ -137,7 +182,7 @@ func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SummaryCard.ReqSearch
|
// SummaryCard.ReqSearch
|
||||||
func decodeGroupSearchResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeGroupSearchResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
request := &jce.RequestPacket{}
|
request := &jce.RequestPacket{}
|
||||||
request.ReadFrom(jce.NewJceReader(payload))
|
request.ReadFrom(jce.NewJceReader(payload))
|
||||||
data := &jce.RequestDataVersion2{}
|
data := &jce.RequestDataVersion2{}
|
||||||
@ -154,7 +199,20 @@ func decodeGroupSearchResponse(c *QQClient, _ uint16, payload []byte) (interface
|
|||||||
ld2 := sr.ReadInt32()
|
ld2 := sr.ReadInt32()
|
||||||
if ld1 > 0 && ld2+9 < int32(len(rspService)) {
|
if ld1 > 0 && ld2+9 < int32(len(rspService)) {
|
||||||
sr.ReadBytes(int(ld1)) // busi comm
|
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(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
}
|
}
|
||||||
return nil, 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
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshClientStatus 刷新客户端状态
|
// RefreshStatus 刷新客户端状态
|
||||||
func (c *QQClient) RefreshStatus() error {
|
func (c *QQClient) RefreshStatus() error {
|
||||||
_, err := c.sendAndWait(c.buildGetOfflineMsgRequest())
|
_, err := c.sendAndWait(c.buildGetOfflineMsgRequest())
|
||||||
return err
|
return err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user