mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
147 lines
4.8 KiB
Go
147 lines
4.8 KiB
Go
package client
|
|
|
|
import (
|
|
"github.com/Mrs4s/MiraiGo/binary"
|
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
|
"github.com/pkg/errors"
|
|
"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()
|
|
req := &jce.SummaryCardReqSearch{
|
|
Keyword: keyword,
|
|
CountryCode: "+86",
|
|
Version: 3,
|
|
ReqServices: [][]byte{},
|
|
}
|
|
head := jce.NewJceWriter()
|
|
head.WriteInt32(2, 0)
|
|
buf := &jce.RequestDataVersion3{Map: map[string][]byte{
|
|
"ReqHead": packUniRequestData(head.Bytes()),
|
|
"ReqSearch": packUniRequestData(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, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
}
|
|
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
}
|
|
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
|
|
}
|