1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

fix GetGroupInfo() panic.

This commit is contained in:
Mrs4s 2020-11-04 01:46:31 +08:00
parent 84519e0a17
commit a45bbd6364
6 changed files with 184 additions and 89 deletions

View File

@ -362,6 +362,14 @@ type (
ReqNearbyGodInfo byte `jceId:"20"`
ReqExtendCard byte `jceId:"22"`
}
SummaryCardReqSearch struct {
IJceStruct
Keyword string `jceId:"0"`
CountryCode string `jceId:"1"`
Version int32 `jceId:"2"`
ReqServices [][]byte `jceId:"3"` // busi
}
)
func (pkt *RequestPacket) ToBytes() []byte {
@ -433,6 +441,12 @@ func (pkt *SummaryCardReq) ToBytes() []byte {
return w.Bytes()
}
func (pkt *SummaryCardReqSearch) ToBytes() []byte {
w := NewJceWriter()
w.WriteJceStructRaw(pkt)
return w.Bytes()
}
func (pkt *FriendInfo) ReadFrom(r *JceReader) {
pkt.FriendUin = r.ReadInt64(0)
pkt.GroupId = r.ReadByte(1)

View File

@ -112,6 +112,23 @@ func (w *JceWriter) WriteInt64Slice(l []int64, tag int) {
}
}
func (w *JceWriter) WriteSlice(i interface{}, tag int) {
va := reflect.ValueOf(i)
if va.Kind() != reflect.Slice {
return
}
w.writeHead(9, tag)
if va.Len() == 0 {
w.WriteInt32(0, 0)
return
}
w.WriteInt32(int32(va.Len()), 0)
for i := 0; i < va.Len(); i++ {
v := va.Index(i)
w.WriteObject(v.Interface(), 0)
}
}
func (w *JceWriter) WriteJceStructSlice(l []IJceStruct, tag int) {
w.writeHead(9, tag)
if len(l) == 0 {
@ -149,6 +166,10 @@ func (w *JceWriter) WriteObject(i interface{}, tag int) {
w.WriteMap(i, tag)
return
}
if t.Kind() == reflect.Slice {
w.WriteSlice(i, tag)
return
}
switch o := i.(type) {
case byte:
w.WriteByte(o, tag)
@ -166,14 +187,8 @@ func (w *JceWriter) WriteObject(i interface{}, tag int) {
w.WriteFloat64(o, tag)
case string:
w.WriteString(o, tag)
case []byte:
w.WriteBytes(o, tag)
case []int64:
w.WriteInt64Slice(o, tag)
case IJceStruct:
w.WriteJceStruct(o, tag)
case []IJceStruct:
w.WriteJceStructSlice(o, tag)
}
}

View File

@ -1041,54 +1041,6 @@ func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool)
return seq, packet
}
// OidbSvc.0x88d_0
func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) (uint16, []byte) {
seq := c.nextSeq()
body := &oidb.D88DReqBody{
AppId: proto.Uint32(c.version.AppId),
ReqGroupInfo: []*oidb.ReqGroupInfo{
{
GroupCode: proto.Uint64(uint64(groupCode)),
Stgroupinfo: &oidb.D88DGroupInfo{
GroupOwner: proto.Uint64(0),
GroupUin: proto.Uint64(0),
GroupCreateTime: proto.Uint32(0),
GroupFlag: proto.Uint32(0),
GroupMemberMaxNum: proto.Uint32(0),
GroupMemberNum: proto.Uint32(0),
GroupOption: proto.Uint32(0),
GroupLevel: proto.Uint32(0),
GroupFace: proto.Uint32(0),
GroupName: EmptyBytes,
GroupMemo: EmptyBytes,
GroupFingerMemo: EmptyBytes,
GroupLastMsgTime: proto.Uint32(0),
GroupQuestion: EmptyBytes,
GroupAnswer: EmptyBytes,
GroupGrade: proto.Uint32(0),
ActiveMemberNum: proto.Uint32(0),
HeadPortraitSeq: proto.Uint32(0),
MsgHeadPortrait: &oidb.D88DGroupHeadPortrait{},
StGroupExInfo: &oidb.D88DGroupExInfoOnly{},
GroupSecLevel: proto.Uint32(0),
CmduinPrivilege: proto.Uint32(0),
NoFingerOpenFlag: proto.Uint32(0),
NoCodeFingerOpenFlag: proto.Uint32(0),
},
},
},
PcClientVersion: proto.Uint32(0),
}
b, _ := proto.Marshal(body)
req := &oidb.OIDBSSOPkg{
Command: 2189,
Bodybuffer: b,
}
payload, _ := proto.Marshal(req)
packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0x88d_0", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}
// ProfileService.GroupMngReq
func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
seq := c.nextSeq()

View File

@ -158,6 +158,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
"OidbSvc.0xd79": decodeWordSegmentation,
"OidbSvc.0x990": decodeTranslateResponse,
"SummaryCard.ReqSummaryCard": decodeSummaryCardResponse,
"SummaryCard.ReqSearch": decodeGroupSearchResponse,
"PttCenterSvr.ShortVideoDownReq": decodePttShortVideoDownResponse,
"LightAppSvc.mini_app_info.GetAppInfoById": decodeAppInfoResponse,
"OfflineFilleHandleSvr.pb_ftn_CMD_REQ_APPLY_DOWNLOAD-1200": decodeOfflineFileDownloadResponse,
@ -372,14 +373,6 @@ func (c *QQClient) GetShortVideoUrl(uuid, md5 []byte) string {
return i.(string)
}
func (c *QQClient) GetGroupInfo(groupCode int64) (*GroupInfo, error) {
i, err := c.sendAndWait(c.buildGroupInfoRequestPacket(groupCode))
if err != nil {
return nil, err
}
return i.(*GroupInfo), nil
}
func (c *QQClient) SendGroupMessage(groupCode int64, m *message.SendingMessage, f ...bool) *message.GroupMessage {
useFram := false
if len(f) > 0 {

View File

@ -517,33 +517,6 @@ func decodeGroupListResponse(c *QQClient, _ uint16, payload []byte) (interface{}
return l, nil
}
// OidbSvc.0x88d_0
func decodeGroupInfoResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
pkg := oidb.OIDBSSOPkg{}
rsp := oidb.D88DRspBody{}
if err := proto.Unmarshal(payload, &pkg); err != nil {
return nil, err
}
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
return nil, err
}
if len(rsp.RspGroupInfo) == 0 {
return nil, errors.New(string(rsp.StrErrorInfo))
}
info := rsp.RspGroupInfo[0]
return &GroupInfo{
Uin: int64(*info.GroupInfo.GroupUin),
Code: int64(*info.GroupCode),
Name: string(info.GroupInfo.GroupName),
Memo: string(info.GroupInfo.GroupMemo),
OwnerUin: int64(*info.GroupInfo.GroupOwner),
MemberCount: uint16(*info.GroupInfo.GroupMemberNum),
MaxMemberCount: uint16(*info.GroupInfo.GroupMemberMaxNum),
Members: []*GroupMemberInfo{},
client: c,
}, nil
}
// friendlist.GetTroopMemberListReq
func decodeGroupMemberListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
request := &jce.RequestPacket{}

148
client/group_info.go Normal file
View File

@ -0,0 +1,148 @@
package client
import (
"encoding/hex"
"errors"
"github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/binary/jce"
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
"github.com/Mrs4s/MiraiGo/protocol/packets"
"google.golang.org/protobuf/proto"
)
func (c *QQClient) GetGroupInfo(groupCode int64) (*GroupInfo, error) {
i, err := c.sendAndWait(c.buildGroupInfoRequestPacket(groupCode))
if err != nil {
return nil, err
}
return i.(*GroupInfo), nil
}
// OidbSvc.0x88d_0
func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) (uint16, []byte) {
seq := c.nextSeq()
body := &oidb.D88DReqBody{
AppId: proto.Uint32(c.version.AppId),
ReqGroupInfo: []*oidb.ReqGroupInfo{
{
GroupCode: proto.Uint64(uint64(groupCode)),
Stgroupinfo: &oidb.D88DGroupInfo{
GroupOwner: proto.Uint64(0),
GroupUin: proto.Uint64(0),
GroupCreateTime: proto.Uint32(0),
GroupFlag: proto.Uint32(0),
GroupMemberMaxNum: proto.Uint32(0),
GroupMemberNum: proto.Uint32(0),
GroupOption: proto.Uint32(0),
GroupLevel: proto.Uint32(0),
GroupFace: proto.Uint32(0),
GroupName: EmptyBytes,
GroupMemo: EmptyBytes,
GroupFingerMemo: EmptyBytes,
GroupLastMsgTime: proto.Uint32(0),
GroupQuestion: EmptyBytes,
GroupAnswer: EmptyBytes,
GroupGrade: proto.Uint32(0),
ActiveMemberNum: proto.Uint32(0),
HeadPortraitSeq: proto.Uint32(0),
MsgHeadPortrait: &oidb.D88DGroupHeadPortrait{},
StGroupExInfo: &oidb.D88DGroupExInfoOnly{},
GroupSecLevel: proto.Uint32(0),
CmduinPrivilege: proto.Uint32(0),
NoFingerOpenFlag: proto.Uint32(0),
NoCodeFingerOpenFlag: proto.Uint32(0),
},
},
},
PcClientVersion: proto.Uint32(0),
}
b, _ := proto.Marshal(body)
req := &oidb.OIDBSSOPkg{
Command: 2189,
Bodybuffer: b,
}
payload, _ := proto.Marshal(req)
packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0x88d_0", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}
// SummaryCard.ReqSearch
func (c *QQClient) buildGroupSearchPacket(keyword string) (uint16, []byte) {
seq := c.nextSeq()
s, _ := hex.DecodeString(`280000001e00000030080110ffffffff0f2881e8922660026a0a382e342e382e3438313070ca2508001004220935393737393631323232093539373739363132325212090000000000000000110000000000000000600029`)
req := &jce.SummaryCardReqSearch{
Keyword: keyword,
CountryCode: "+86",
Version: 3,
ReqServices: [][]byte{s},
}
head := jce.NewJceWriter()
head.WriteInt32(2, 0)
buf := &jce.RequestDataVersion3{Map: map[string][]byte{
"ReqHead": packRequestDataV3(head.Bytes()),
"ReqSearch": packRequestDataV3(req.ToBytes()),
}}
pkt := &jce.RequestPacket{
IVersion: 3,
SServantName: "SummaryCardServantObj",
SFuncName: "ReqSearch",
SBuffer: buf.ToBytes(),
Context: make(map[string]string),
Status: make(map[string]string),
}
packet := packets.BuildUniPacket(c.Uin, seq, "SummaryCard.ReqSearch", 1, c.OutGoingPacketSessionId, []byte{}, c.sigInfo.d2Key, pkt.ToBytes())
return seq, packet
}
// SummaryCard.ReqSearch
func decodeGroupSearchResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
request := &jce.RequestPacket{}
request.ReadFrom(jce.NewJceReader(payload))
data := &jce.RequestDataVersion2{}
data.ReadFrom(jce.NewJceReader(request.SBuffer))
if len(data.Map["RespHead"]["SummaryCard.RespHead"]) > 20 {
return nil, errors.New("not found")
}
rsp := data.Map["RespSearch"]["SummaryCard.RespSearch"][1:]
r := jce.NewJceReader(rsp)
rspService := r.ReadAny(2).([]interface{})[0].([]byte)
sr := binary.NewReader(rspService)
sr.ReadByte()
ld1 := sr.ReadInt32()
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
}
return nil, nil
}
// OidbSvc.0x88d_0
func decodeGroupInfoResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
pkg := oidb.OIDBSSOPkg{}
rsp := oidb.D88DRspBody{}
if err := proto.Unmarshal(payload, &pkg); err != nil {
return nil, err
}
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
return nil, err
}
if len(rsp.RspGroupInfo) == 0 {
return nil, errors.New(string(rsp.StrErrorInfo))
}
info := rsp.RspGroupInfo[0]
if info.GroupInfo == nil {
return nil, errors.New("group info not found")
}
return &GroupInfo{
Uin: int64(*info.GroupInfo.GroupUin),
Code: int64(*info.GroupCode),
Name: string(info.GroupInfo.GroupName),
Memo: string(info.GroupInfo.GroupMemo),
OwnerUin: int64(*info.GroupInfo.GroupOwner),
MemberCount: uint16(*info.GroupInfo.GroupMemberNum),
MaxMemberCount: uint16(*info.GroupInfo.GroupMemberMaxNum),
Members: []*GroupMemberInfo{},
client: c,
}, nil
}