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:
parent
84519e0a17
commit
a45bbd6364
@ -362,6 +362,14 @@ type (
|
|||||||
ReqNearbyGodInfo byte `jceId:"20"`
|
ReqNearbyGodInfo byte `jceId:"20"`
|
||||||
ReqExtendCard byte `jceId:"22"`
|
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 {
|
func (pkt *RequestPacket) ToBytes() []byte {
|
||||||
@ -433,6 +441,12 @@ func (pkt *SummaryCardReq) ToBytes() []byte {
|
|||||||
return w.Bytes()
|
return w.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pkt *SummaryCardReqSearch) ToBytes() []byte {
|
||||||
|
w := NewJceWriter()
|
||||||
|
w.WriteJceStructRaw(pkt)
|
||||||
|
return w.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
func (pkt *FriendInfo) ReadFrom(r *JceReader) {
|
func (pkt *FriendInfo) ReadFrom(r *JceReader) {
|
||||||
pkt.FriendUin = r.ReadInt64(0)
|
pkt.FriendUin = r.ReadInt64(0)
|
||||||
pkt.GroupId = r.ReadByte(1)
|
pkt.GroupId = r.ReadByte(1)
|
||||||
|
@ -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) {
|
func (w *JceWriter) WriteJceStructSlice(l []IJceStruct, tag int) {
|
||||||
w.writeHead(9, tag)
|
w.writeHead(9, tag)
|
||||||
if len(l) == 0 {
|
if len(l) == 0 {
|
||||||
@ -149,6 +166,10 @@ func (w *JceWriter) WriteObject(i interface{}, tag int) {
|
|||||||
w.WriteMap(i, tag)
|
w.WriteMap(i, tag)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if t.Kind() == reflect.Slice {
|
||||||
|
w.WriteSlice(i, tag)
|
||||||
|
return
|
||||||
|
}
|
||||||
switch o := i.(type) {
|
switch o := i.(type) {
|
||||||
case byte:
|
case byte:
|
||||||
w.WriteByte(o, tag)
|
w.WriteByte(o, tag)
|
||||||
@ -166,14 +187,8 @@ func (w *JceWriter) WriteObject(i interface{}, tag int) {
|
|||||||
w.WriteFloat64(o, tag)
|
w.WriteFloat64(o, tag)
|
||||||
case string:
|
case string:
|
||||||
w.WriteString(o, tag)
|
w.WriteString(o, tag)
|
||||||
case []byte:
|
|
||||||
w.WriteBytes(o, tag)
|
|
||||||
case []int64:
|
|
||||||
w.WriteInt64Slice(o, tag)
|
|
||||||
case IJceStruct:
|
case IJceStruct:
|
||||||
w.WriteJceStruct(o, tag)
|
w.WriteJceStruct(o, tag)
|
||||||
case []IJceStruct:
|
|
||||||
w.WriteJceStructSlice(o, tag)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1041,54 +1041,6 @@ func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool)
|
|||||||
return seq, packet
|
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
|
// ProfileService.GroupMngReq
|
||||||
func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
|
func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
|
@ -158,6 +158,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
|||||||
"OidbSvc.0xd79": decodeWordSegmentation,
|
"OidbSvc.0xd79": decodeWordSegmentation,
|
||||||
"OidbSvc.0x990": decodeTranslateResponse,
|
"OidbSvc.0x990": decodeTranslateResponse,
|
||||||
"SummaryCard.ReqSummaryCard": decodeSummaryCardResponse,
|
"SummaryCard.ReqSummaryCard": decodeSummaryCardResponse,
|
||||||
|
"SummaryCard.ReqSearch": decodeGroupSearchResponse,
|
||||||
"PttCenterSvr.ShortVideoDownReq": decodePttShortVideoDownResponse,
|
"PttCenterSvr.ShortVideoDownReq": decodePttShortVideoDownResponse,
|
||||||
"LightAppSvc.mini_app_info.GetAppInfoById": decodeAppInfoResponse,
|
"LightAppSvc.mini_app_info.GetAppInfoById": decodeAppInfoResponse,
|
||||||
"OfflineFilleHandleSvr.pb_ftn_CMD_REQ_APPLY_DOWNLOAD-1200": decodeOfflineFileDownloadResponse,
|
"OfflineFilleHandleSvr.pb_ftn_CMD_REQ_APPLY_DOWNLOAD-1200": decodeOfflineFileDownloadResponse,
|
||||||
@ -372,14 +373,6 @@ func (c *QQClient) GetShortVideoUrl(uuid, md5 []byte) string {
|
|||||||
return i.(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 {
|
func (c *QQClient) SendGroupMessage(groupCode int64, m *message.SendingMessage, f ...bool) *message.GroupMessage {
|
||||||
useFram := false
|
useFram := false
|
||||||
if len(f) > 0 {
|
if len(f) > 0 {
|
||||||
|
@ -517,33 +517,6 @@ func decodeGroupListResponse(c *QQClient, _ uint16, payload []byte) (interface{}
|
|||||||
return l, nil
|
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
|
// friendlist.GetTroopMemberListReq
|
||||||
func decodeGroupMemberListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeGroupMemberListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
request := &jce.RequestPacket{}
|
request := &jce.RequestPacket{}
|
||||||
|
148
client/group_info.go
Normal file
148
client/group_info.go
Normal 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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user