diff --git a/client/builders.go b/client/builders.go
index c6ec02ae..e321b789 100644
--- a/client/builders.go
+++ b/client/builders.go
@@ -550,46 +550,6 @@ func (c *QQClient) buildDeleteOnlinePushPacket(uin int64, seq uint16, delMsg []j
return packets.BuildUniPacket(c.Uin, seq, "OnlinePush.RespPush", 1, c.OutGoingPacketSessionId, []byte{}, c.sigInfo.d2Key, pkt.ToBytes())
}
-// MessageSvc.PbSendMsg
-func (c *QQClient) buildGroupSendingPacket(groupCode int64, r, pkgNum, pkgIndex, pkgDiv int32, forward bool, m []message.IMessageElement) (uint16, []byte) {
- seq := c.nextSeq()
- var ptt *message.GroupVoiceElement
- if len(m) > 0 {
- if p, ok := m[0].(*message.GroupVoiceElement); ok {
- ptt = p
- m = []message.IMessageElement{}
- }
- }
- req := &msg.SendMessageRequest{
- RoutingHead: &msg.RoutingHead{Grp: &msg.Grp{GroupCode: &groupCode}},
- ContentHead: &msg.ContentHead{PkgNum: &pkgNum, PkgIndex: &pkgIndex, DivSeq: &pkgDiv},
- MsgBody: &msg.MessageBody{
- RichText: &msg.RichText{
- Elems: message.ToProtoElems(m, true),
- Ptt: func() *msg.Ptt {
- if ptt != nil {
- return ptt.Ptt
- }
- return nil
- }(),
- },
- },
- MsgSeq: proto.Int32(c.nextGroupSeq()),
- MsgRand: &r,
- SyncCookie: EmptyBytes,
- MsgVia: proto.Int32(1),
- MsgCtrl: func() *msg.MsgCtrl {
- if forward {
- return &msg.MsgCtrl{MsgFlag: proto.Int32(4)}
- }
- return nil
- }(),
- }
- payload, _ := proto.Marshal(req)
- packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbSendMsg", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
- return seq, packet
-}
-
// MessageSvc.PbSendMsg
func (c *QQClient) buildFriendSendingPacket(target int64, msgSeq, r, pkgNum, pkgIndex, pkgDiv int32, time int64, m []message.IMessageElement) (uint16, []byte) {
seq := c.nextSeq()
diff --git a/client/client.go b/client/client.go
index 8e753d7e..1d89bba8 100644
--- a/client/client.go
+++ b/client/client.go
@@ -8,7 +8,6 @@ import (
"fmt"
"image"
"io"
- "math"
"math/rand"
"net"
"runtime/debug"
@@ -21,12 +20,8 @@ import (
"github.com/pkg/errors"
- "github.com/golang/protobuf/proto"
-
"github.com/Mrs4s/MiraiGo/binary"
- "github.com/Mrs4s/MiraiGo/client/pb/longmsg"
"github.com/Mrs4s/MiraiGo/client/pb/msg"
- "github.com/Mrs4s/MiraiGo/client/pb/multimsg"
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/MiraiGo/protocol/packets"
"github.com/Mrs4s/MiraiGo/utils"
@@ -51,7 +46,6 @@ type QQClient struct {
Conn net.Conn
ConnectTime time.Time
- decoders map[string]func(*QQClient, uint16, []byte) (interface{}, error)
handlers sync.Map
servers []*net.TCPAddr
currServerIndex int
@@ -114,6 +108,39 @@ type loginSigInfo struct {
pt4TokenMap map[string][]byte
}
+var decoders = map[string]func(*QQClient, uint16, []byte) (interface{}, error){
+ "wtlogin.login": decodeLoginResponse,
+ "wtlogin.exchange_emp": decodeExchangeEmpResponse,
+ "StatSvc.register": decodeClientRegisterResponse,
+ "StatSvc.ReqMSFOffline": decodeMSFOfflinePacket,
+ "StatSvc.GetDevLoginInfo": decodeDevListResponse,
+ "MessageSvc.PushNotify": decodeSvcNotify,
+ "OnlinePush.ReqPush": decodeOnlinePushReqPacket,
+ "OnlinePush.PbPushTransMsg": decodeOnlinePushTransPacket,
+ "ConfigPushSvc.PushReq": decodePushReqPacket,
+ "MessageSvc.PbGetMsg": decodeMessageSvcPacket,
+ "MessageSvc.PushForceOffline": decodeForceOfflinePacket,
+ "PbMessageSvc.PbMsgWithDraw": decodeMsgWithDrawResponse,
+ "friendlist.getFriendGroupList": decodeFriendGroupListResponse,
+ "friendlist.GetTroopListReqV2": decodeGroupListResponse,
+ "friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse,
+ "group_member_card.get_group_member_card_info": decodeGroupMemberInfoResponse,
+ "ImgStore.GroupPicUp": decodeGroupImageStoreResponse,
+ "PttStore.GroupPttUp": decodeGroupPttStoreResponse,
+ "LongConn.OffPicUp": decodeOffPicUpResponse,
+ "ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
+ "ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket,
+ "MultiMsg.ApplyUp": decodeMultiApplyUpResponse,
+ "MultiMsg.ApplyDown": decodeMultiApplyDownResponse,
+ "OidbSvc.0xe07_0": decodeImageOcrResponse,
+ "OidbSvc.0xd79": decodeWordSegmentation,
+ "OidbSvc.0x990": decodeTranslateResponse,
+ "SummaryCard.ReqSummaryCard": decodeSummaryCardResponse,
+ "PttCenterSvr.ShortVideoDownReq": decodePttShortVideoDownResponse,
+ "LightAppSvc.mini_app_info.GetAppInfoById": decodeAppInfoResponse,
+ "PttCenterSvr.pb_pttCenter_CMD_REQ_APPLY_UPLOAD-500": decodePrivatePttStoreResponse,
+}
+
func init() {
rand.Seed(time.Now().UTC().UnixNano())
}
@@ -130,59 +157,19 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
SequenceId: 0x3635,
RandomKey: make([]byte, 16),
OutGoingPacketSessionId: []byte{0x02, 0xB0, 0x5B, 0x8B},
- decoders: map[string]func(*QQClient, uint16, []byte) (interface{}, error){
- "wtlogin.login": decodeLoginResponse,
- "wtlogin.exchange_emp": decodeExchangeEmpResponse,
- "StatSvc.register": decodeClientRegisterResponse,
- "StatSvc.ReqMSFOffline": decodeMSFOfflinePacket,
- "StatSvc.GetDevLoginInfo": decodeDevListResponse,
- "MessageSvc.PushNotify": decodeSvcNotify,
- "OnlinePush.PbPushGroupMsg": decodeGroupMessagePacket,
- "OnlinePush.ReqPush": decodeOnlinePushReqPacket,
- "OnlinePush.PbPushTransMsg": decodeOnlinePushTransPacket,
- "ConfigPushSvc.PushReq": decodePushReqPacket,
- "MessageSvc.PbGetMsg": decodeMessageSvcPacket,
- "MessageSvc.PbSendMsg": decodeMsgSendResponse,
- "MessageSvc.PushForceOffline": decodeForceOfflinePacket,
- "PbMessageSvc.PbMsgWithDraw": decodeMsgWithDrawResponse,
- "friendlist.getFriendGroupList": decodeFriendGroupListResponse,
- "friendlist.GetTroopListReqV2": decodeGroupListResponse,
- "friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse,
- "group_member_card.get_group_member_card_info": decodeGroupMemberInfoResponse,
- "ImgStore.GroupPicUp": decodeGroupImageStoreResponse,
- "PttStore.GroupPttUp": decodeGroupPttStoreResponse,
- "LongConn.OffPicUp": decodeOffPicUpResponse,
- "ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
- "ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket,
- "MultiMsg.ApplyUp": decodeMultiApplyUpResponse,
- "MultiMsg.ApplyDown": decodeMultiApplyDownResponse,
- "OidbSvc.0x6d6_2": decodeOIDB6d62Response,
- "OidbSvc.0x6d6_3": decodeOIDB6d63Response,
- "OidbSvc.0x6d8_1": decodeOIDB6d81Response,
- "OidbSvc.0x88d_0": decodeGroupInfoResponse,
- "OidbSvc.0xe07_0": decodeImageOcrResponse,
- "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,
- "PttCenterSvr.pb_pttCenter_CMD_REQ_APPLY_UPLOAD-500": decodePrivatePttStoreResponse,
- },
- sigInfo: &loginSigInfo{},
- requestPacketRequestId: 1921334513,
- groupSeq: int32(rand.Intn(20000)),
- friendSeq: 22911,
- highwayApplyUpSeq: 77918,
- ksid: []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", SystemDeviceInfo.IMEI)),
- eventHandlers: &eventHandlers{},
- msgSvcCache: utils.NewCache(time.Second * 15),
- transCache: utils.NewCache(time.Second * 15),
- onlinePushCache: utils.NewCache(time.Second * 15),
- version: genVersionInfo(SystemDeviceInfo.Protocol),
- servers: []*net.TCPAddr{},
- stat: &Statistics{},
+ sigInfo: &loginSigInfo{},
+ requestPacketRequestId: 1921334513,
+ groupSeq: int32(rand.Intn(20000)),
+ friendSeq: 22911,
+ highwayApplyUpSeq: 77918,
+ ksid: []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", SystemDeviceInfo.IMEI)),
+ eventHandlers: &eventHandlers{},
+ msgSvcCache: utils.NewCache(time.Second * 15),
+ transCache: utils.NewCache(time.Second * 15),
+ onlinePushCache: utils.NewCache(time.Second * 15),
+ version: genVersionInfo(SystemDeviceInfo.Protocol),
+ servers: []*net.TCPAddr{},
+ stat: &Statistics{},
}
sso, err := getSSOAddress()
if err == nil && len(sso) > 0 {
@@ -425,84 +412,6 @@ func (c *QQClient) GetShortVideoUrl(uuid, md5 []byte) string {
return i.(string)
}
-func (c *QQClient) SendGroupMessage(groupCode int64, m *message.SendingMessage, f ...bool) *message.GroupMessage {
- useFram := false
- if len(f) > 0 {
- useFram = f[0]
- }
- imgCount := m.Count(func(e message.IMessageElement) bool { return e.Type() == message.Image })
- if useFram {
- if m.Any(func(e message.IMessageElement) bool { return e.Type() == message.Reply }) {
- useFram = false
- }
- }
- msgLen := message.EstimateLength(m.Elements, 703)
- if msgLen > 5000 || imgCount > 50 {
- return nil
- }
- if (msgLen > 200 || imgCount > 1) && !useFram {
- ret := c.sendGroupLongOrForwardMessage(groupCode, true, &message.ForwardMessage{Nodes: []*message.ForwardNode{
- {
- SenderId: c.Uin,
- SenderName: c.Nickname,
- Time: int32(time.Now().Unix()),
- Message: m.Elements,
- },
- }})
- return ret
- }
- return c.sendGroupMessage(groupCode, false, m)
-}
-
-func (c *QQClient) sendGroupMessage(groupCode int64, forward bool, m *message.SendingMessage) *message.GroupMessage {
- eid := utils.RandomString(6)
- mr := int32(rand.Uint32())
- ch := make(chan int32)
- c.onGroupMessageReceipt(eid, func(c *QQClient, e *groupMessageReceiptEvent) {
- if e.Rand == mr {
- ch <- e.Seq
- }
- })
- defer c.onGroupMessageReceipt(eid)
- imgCount := m.Count(func(e message.IMessageElement) bool { return e.Type() == message.Image })
- msgLen := message.EstimateLength(m.Elements, 703)
- if (msgLen > 200 || imgCount > 1) && !forward && !m.Any(func(e message.IMessageElement) bool {
- _, ok := e.(*message.GroupVoiceElement)
- _, ok2 := e.(*message.ServiceElement)
- return ok || ok2
- }) {
- div := int32(rand.Uint32())
- fragmented := m.ToFragmented()
- for i, elems := range fragmented {
- _, pkt := c.buildGroupSendingPacket(groupCode, mr, int32(len(fragmented)), int32(i), div, forward, elems)
- _ = c.send(pkt)
- }
- } else {
- _, pkt := c.buildGroupSendingPacket(groupCode, mr, 1, 0, 0, forward, m.Elements)
- _ = c.send(pkt)
- }
- var mid int32
- ret := &message.GroupMessage{
- Id: -1,
- InternalId: mr,
- GroupCode: groupCode,
- Sender: &message.Sender{
- Uin: c.Uin,
- Nickname: c.Nickname,
- IsFriend: true,
- },
- Time: int32(time.Now().Unix()),
- Elements: m.Elements,
- }
- select {
- case mid = <-ch:
- case <-time.After(time.Second * 5):
- return ret
- }
- ret.Id = mid
- return ret
-}
-
func (c *QQClient) SendPrivateMessage(target int64, m *message.SendingMessage) *message.PrivateMessage {
mr := int32(rand.Uint32())
seq := c.nextFriendSeq()
@@ -595,68 +504,6 @@ func (c *QQClient) GetForwardMessage(resId string) *message.ForwardMessage {
return ret
}
-func (c *QQClient) SendGroupForwardMessage(groupCode int64, m *message.ForwardMessage) *message.GroupMessage {
- return c.sendGroupLongOrForwardMessage(groupCode, false, m)
-}
-
-func (c *QQClient) sendGroupLongOrForwardMessage(groupCode int64, isLong bool, m *message.ForwardMessage) *message.GroupMessage {
- if len(m.Nodes) >= 200 {
- return nil
- }
- ts := time.Now().Unix()
- seq := c.nextGroupSeq()
- data, hash := m.CalculateValidationData(seq, rand.Int31(), groupCode)
- i, err := c.sendAndWait(c.buildMultiApplyUpPacket(data, hash, func() int32 {
- if isLong {
- return 1
- } else {
- return 2
- }
- }(), utils.ToGroupUin(groupCode)))
- if err != nil {
- return nil
- }
- rsp := i.(*multimsg.MultiMsgApplyUpRsp)
- body, _ := proto.Marshal(&longmsg.LongReqBody{
- Subcmd: 1,
- TermType: 5,
- PlatformType: 9,
- MsgUpReq: []*longmsg.LongMsgUpReq{
- {
- MsgType: 3,
- DstUin: utils.ToGroupUin(groupCode),
- MsgContent: data,
- StoreType: 2,
- MsgUkey: rsp.MsgUkey,
- },
- },
- })
- for i, ip := range rsp.Uint32UpIp {
- err := c.highwayUpload(uint32(ip), int(rsp.Uint32UpPort[i]), rsp.MsgSig, body, 27)
- if err == nil {
- if !isLong {
- var pv string
- for i := 0; i < int(math.Min(4, float64(len(m.Nodes)))); i++ {
- pv += fmt.Sprintf(`
%s: %s`, m.Nodes[i].SenderName, message.ToReadableString(m.Nodes[i].Message))
- }
- return c.sendGroupMessage(groupCode, true, genForwardTemplate(rsp.MsgResid, pv, "群聊的聊天记录", "[聊天记录]", "聊天记录", fmt.Sprintf("查看 %d 条转发消息", len(m.Nodes)), ts))
- }
- bri := func() string {
- var r string
- for _, n := range m.Nodes {
- r += message.ToReadableString(n.Message)
- if len(r) >= 27 {
- break
- }
- }
- return r
- }()
- return c.sendGroupMessage(groupCode, false, genLongTemplate(rsp.MsgResid, bri, ts))
- }
- }
- return nil
-}
-
func (c *QQClient) sendGroupPoke(groupCode, target int64) {
_, _ = c.sendAndWait(c.buildGroupPokePacket(groupCode, target))
}
@@ -1163,7 +1010,7 @@ func (c *QQClient) netLoop() {
}
}()
- if decoder, ok := c.decoders[pkt.CommandName]; ok {
+ if decoder, ok := decoders[pkt.CommandName]; ok {
// found predefined decoder
rsp, err := decoder(c, pkt.SequenceId, payload)
if err != nil {
diff --git a/client/decoders.go b/client/decoders.go
index 9b3ac41e..b0c576a5 100644
--- a/client/decoders.go
+++ b/client/decoders.go
@@ -378,53 +378,6 @@ func decodeMessageSvcPacket(c *QQClient, _ uint16, payload []byte) (interface{},
return nil, err
}
-// OnlinePush.PbPushGroupMsg
-func decodeGroupMessagePacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
- pkt := msg.PushMessagePacket{}
- err := proto.Unmarshal(payload, &pkt)
- if err != nil {
- return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
- }
- if pkt.Message.Head.GetFromUin() == c.Uin {
- c.dispatchGroupMessageReceiptEvent(&groupMessageReceiptEvent{
- Rand: pkt.Message.Body.RichText.Attr.GetRandom(),
- Seq: pkt.Message.Head.GetMsgSeq(),
- Msg: c.parseGroupMessage(pkt.Message),
- })
- return nil, nil
- }
- if pkt.Message.Content != nil && pkt.Message.Content.GetPkgNum() > 1 {
- var builder *groupMessageBuilder // TODO: 支持多SEQ
- i, ok := c.groupMsgBuilders.Load(pkt.Message.Content.DivSeq)
- if !ok {
- builder = &groupMessageBuilder{}
- c.groupMsgBuilders.Store(pkt.Message.Content.DivSeq, builder)
- } else {
- builder = i.(*groupMessageBuilder)
- }
- builder.MessageSlices = append(builder.MessageSlices, pkt.Message)
- if int32(len(builder.MessageSlices)) >= pkt.Message.Content.GetPkgNum() {
- c.groupMsgBuilders.Delete(pkt.Message.Content.DivSeq)
- c.dispatchGroupMessage(c.parseGroupMessage(builder.build()))
- }
- return nil, nil
- }
- c.dispatchGroupMessage(c.parseGroupMessage(pkt.Message))
- return nil, nil
-}
-
-// MessageSvc.PbSendMsg
-func decodeMsgSendResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
- rsp := msg.SendMessageResponse{}
- if err := proto.Unmarshal(payload, &rsp); err != nil {
- return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
- }
- if rsp.GetResult() != 0 {
- c.Error("send msg error: %v %v", rsp.GetResult(), rsp.GetErrMsg())
- }
- return nil, nil
-}
-
// MessageSvc.PushNotify
func decodeSvcNotify(c *QQClient, _ uint16, _ []byte) (interface{}, error) {
_, err := c.sendAndWait(c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix()))
diff --git a/client/group_file.go b/client/group_file.go
index 3c323d3b..183eee18 100644
--- a/client/group_file.go
+++ b/client/group_file.go
@@ -47,6 +47,12 @@ type (
}
)
+func init() {
+ decoders["OidbSvc.0x6d8_1"] = decodeOIDB6d81Response
+ decoders["OidbSvc.0x6d6_2"] = decodeOIDB6d62Response
+ decoders["OidbSvc.0x6d6_3"] = decodeOIDB6d63Response
+}
+
func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err error) {
defer func() {
if pan := recover(); pan != nil {
diff --git a/client/group_info.go b/client/group_info.go
index f10d8957..9c6e01c4 100644
--- a/client/group_info.go
+++ b/client/group_info.go
@@ -9,6 +9,11 @@ import (
"google.golang.org/protobuf/proto"
)
+func init() {
+ decoders["SummaryCard.ReqSearch"] = decodeGroupSearchResponse
+ decoders["OidbSvc.0x88d_0"] = decodeGroupInfoResponse
+}
+
func (c *QQClient) GetGroupInfo(groupCode int64) (*GroupInfo, error) {
i, err := c.sendAndWait(c.buildGroupInfoRequestPacket(groupCode))
if err != nil {
diff --git a/client/group_msg.go b/client/group_msg.go
new file mode 100644
index 00000000..f7e6cb9d
--- /dev/null
+++ b/client/group_msg.go
@@ -0,0 +1,291 @@
+package client
+
+import (
+ "fmt"
+ "github.com/Mrs4s/MiraiGo/client/pb/longmsg"
+ "github.com/Mrs4s/MiraiGo/client/pb/msg"
+ "github.com/Mrs4s/MiraiGo/client/pb/multimsg"
+ "github.com/Mrs4s/MiraiGo/message"
+ "github.com/Mrs4s/MiraiGo/protocol/packets"
+ "github.com/Mrs4s/MiraiGo/utils"
+ "github.com/pkg/errors"
+ "google.golang.org/protobuf/proto"
+ "math"
+ "math/rand"
+ "time"
+)
+
+func init() {
+ decoders["OnlinePush.PbPushGroupMsg"] = decodeGroupMessagePacket
+ decoders["MessageSvc.PbSendMsg"] = decodeMsgSendResponse
+ decoders["MessageSvc.PbGetGroupMsg"] = decodeGetGroupMsgResponse
+}
+
+// SendGroupMessage 发送群消息
+func (c *QQClient) SendGroupMessage(groupCode int64, m *message.SendingMessage, f ...bool) *message.GroupMessage {
+ useFram := false
+ if len(f) > 0 {
+ useFram = f[0]
+ }
+ imgCount := m.Count(func(e message.IMessageElement) bool { return e.Type() == message.Image })
+ if useFram {
+ if m.Any(func(e message.IMessageElement) bool { return e.Type() == message.Reply }) {
+ useFram = false
+ }
+ }
+ msgLen := message.EstimateLength(m.Elements, 703)
+ if msgLen > 5000 || imgCount > 50 {
+ return nil
+ }
+ if (msgLen > 200 || imgCount > 1) && !useFram {
+ ret := c.sendGroupLongOrForwardMessage(groupCode, true, &message.ForwardMessage{Nodes: []*message.ForwardNode{
+ {
+ SenderId: c.Uin,
+ SenderName: c.Nickname,
+ Time: int32(time.Now().Unix()),
+ Message: m.Elements,
+ },
+ }})
+ return ret
+ }
+ return c.sendGroupMessage(groupCode, false, m)
+}
+
+// SendGroupForwardMessage 发送群合并转发消息
+func (c *QQClient) SendGroupForwardMessage(groupCode int64, m *message.ForwardMessage) *message.GroupMessage {
+ return c.sendGroupLongOrForwardMessage(groupCode, false, m)
+}
+
+// GetGroupMessages 从服务器获取历史信息
+func (c *QQClient) GetGroupMessages(groupCode, beginSeq, endSeq int64) ([]*message.GroupMessage, error) {
+ i, err := c.sendAndWait(c.buildGetGroupMsgRequest(groupCode, beginSeq, endSeq))
+ if err != nil {
+ return nil, err
+ }
+ return i.([]*message.GroupMessage), nil
+}
+
+func (c *QQClient) sendGroupMessage(groupCode int64, forward bool, m *message.SendingMessage) *message.GroupMessage {
+ eid := utils.RandomString(6)
+ mr := int32(rand.Uint32())
+ ch := make(chan int32)
+ c.onGroupMessageReceipt(eid, func(c *QQClient, e *groupMessageReceiptEvent) {
+ if e.Rand == mr {
+ ch <- e.Seq
+ }
+ })
+ defer c.onGroupMessageReceipt(eid)
+ imgCount := m.Count(func(e message.IMessageElement) bool { return e.Type() == message.Image })
+ msgLen := message.EstimateLength(m.Elements, 703)
+ if (msgLen > 200 || imgCount > 1) && !forward && !m.Any(func(e message.IMessageElement) bool {
+ _, ok := e.(*message.GroupVoiceElement)
+ _, ok2 := e.(*message.ServiceElement)
+ return ok || ok2
+ }) {
+ div := int32(rand.Uint32())
+ fragmented := m.ToFragmented()
+ for i, elems := range fragmented {
+ _, pkt := c.buildGroupSendingPacket(groupCode, mr, int32(len(fragmented)), int32(i), div, forward, elems)
+ _ = c.send(pkt)
+ }
+ } else {
+ _, pkt := c.buildGroupSendingPacket(groupCode, mr, 1, 0, 0, forward, m.Elements)
+ _ = c.send(pkt)
+ }
+ var mid int32
+ ret := &message.GroupMessage{
+ Id: -1,
+ InternalId: mr,
+ GroupCode: groupCode,
+ Sender: &message.Sender{
+ Uin: c.Uin,
+ Nickname: c.Nickname,
+ IsFriend: true,
+ },
+ Time: int32(time.Now().Unix()),
+ Elements: m.Elements,
+ }
+ select {
+ case mid = <-ch:
+ case <-time.After(time.Second * 5):
+ return ret
+ }
+ ret.Id = mid
+ return ret
+}
+
+func (c *QQClient) sendGroupLongOrForwardMessage(groupCode int64, isLong bool, m *message.ForwardMessage) *message.GroupMessage {
+ if len(m.Nodes) >= 200 {
+ return nil
+ }
+ ts := time.Now().Unix()
+ seq := c.nextGroupSeq()
+ data, hash := m.CalculateValidationData(seq, rand.Int31(), groupCode)
+ i, err := c.sendAndWait(c.buildMultiApplyUpPacket(data, hash, func() int32 {
+ if isLong {
+ return 1
+ } else {
+ return 2
+ }
+ }(), utils.ToGroupUin(groupCode)))
+ if err != nil {
+ return nil
+ }
+ rsp := i.(*multimsg.MultiMsgApplyUpRsp)
+ body, _ := proto.Marshal(&longmsg.LongReqBody{
+ Subcmd: 1,
+ TermType: 5,
+ PlatformType: 9,
+ MsgUpReq: []*longmsg.LongMsgUpReq{
+ {
+ MsgType: 3,
+ DstUin: utils.ToGroupUin(groupCode),
+ MsgContent: data,
+ StoreType: 2,
+ MsgUkey: rsp.MsgUkey,
+ },
+ },
+ })
+ for i, ip := range rsp.Uint32UpIp {
+ err := c.highwayUpload(uint32(ip), int(rsp.Uint32UpPort[i]), rsp.MsgSig, body, 27)
+ if err == nil {
+ if !isLong {
+ var pv string
+ for i := 0; i < int(math.Min(4, float64(len(m.Nodes)))); i++ {
+ pv += fmt.Sprintf(`%s: %s`, m.Nodes[i].SenderName, message.ToReadableString(m.Nodes[i].Message))
+ }
+ return c.sendGroupMessage(groupCode, true, genForwardTemplate(rsp.MsgResid, pv, "群聊的聊天记录", "[聊天记录]", "聊天记录", fmt.Sprintf("查看 %d 条转发消息", len(m.Nodes)), ts))
+ }
+ bri := func() string {
+ var r string
+ for _, n := range m.Nodes {
+ r += message.ToReadableString(n.Message)
+ if len(r) >= 27 {
+ break
+ }
+ }
+ return r
+ }()
+ return c.sendGroupMessage(groupCode, false, genLongTemplate(rsp.MsgResid, bri, ts))
+ }
+ }
+ return nil
+}
+
+// MessageSvc.PbSendMsg
+func (c *QQClient) buildGroupSendingPacket(groupCode int64, r, pkgNum, pkgIndex, pkgDiv int32, forward bool, m []message.IMessageElement) (uint16, []byte) {
+ seq := c.nextSeq()
+ var ptt *message.GroupVoiceElement
+ if len(m) > 0 {
+ if p, ok := m[0].(*message.GroupVoiceElement); ok {
+ ptt = p
+ m = []message.IMessageElement{}
+ }
+ }
+ req := &msg.SendMessageRequest{
+ RoutingHead: &msg.RoutingHead{Grp: &msg.Grp{GroupCode: &groupCode}},
+ ContentHead: &msg.ContentHead{PkgNum: &pkgNum, PkgIndex: &pkgIndex, DivSeq: &pkgDiv},
+ MsgBody: &msg.MessageBody{
+ RichText: &msg.RichText{
+ Elems: message.ToProtoElems(m, true),
+ Ptt: func() *msg.Ptt {
+ if ptt != nil {
+ return ptt.Ptt
+ }
+ return nil
+ }(),
+ },
+ },
+ MsgSeq: proto.Int32(c.nextGroupSeq()),
+ MsgRand: &r,
+ SyncCookie: EmptyBytes,
+ MsgVia: proto.Int32(1),
+ MsgCtrl: func() *msg.MsgCtrl {
+ if forward {
+ return &msg.MsgCtrl{MsgFlag: proto.Int32(4)}
+ }
+ return nil
+ }(),
+ }
+ payload, _ := proto.Marshal(req)
+ packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbSendMsg", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
+ return seq, packet
+}
+
+func (c *QQClient) buildGetGroupMsgRequest(groupCode, beginSeq, endSeq int64) (uint16, []byte) {
+ seq := c.nextSeq()
+ req := &msg.GetGroupMsgReq{
+ GroupCode: proto.Uint64(uint64(groupCode)),
+ BeginSeq: proto.Uint64(uint64(beginSeq)),
+ EndSeq: proto.Uint64(uint64(endSeq)),
+ PublicGroup: proto.Bool(false),
+ }
+ payload, _ := proto.Marshal(req)
+ packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbGetGroupMsg", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
+ return seq, packet
+}
+
+// OnlinePush.PbPushGroupMsg
+func decodeGroupMessagePacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
+ pkt := msg.PushMessagePacket{}
+ err := proto.Unmarshal(payload, &pkt)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
+ }
+ if pkt.Message.Head.GetFromUin() == c.Uin {
+ c.dispatchGroupMessageReceiptEvent(&groupMessageReceiptEvent{
+ Rand: pkt.Message.Body.RichText.Attr.GetRandom(),
+ Seq: pkt.Message.Head.GetMsgSeq(),
+ Msg: c.parseGroupMessage(pkt.Message),
+ })
+ return nil, nil
+ }
+ if pkt.Message.Content != nil && pkt.Message.Content.GetPkgNum() > 1 {
+ var builder *groupMessageBuilder // TODO: 支持多SEQ
+ i, ok := c.groupMsgBuilders.Load(pkt.Message.Content.DivSeq)
+ if !ok {
+ builder = &groupMessageBuilder{}
+ c.groupMsgBuilders.Store(pkt.Message.Content.DivSeq, builder)
+ } else {
+ builder = i.(*groupMessageBuilder)
+ }
+ builder.MessageSlices = append(builder.MessageSlices, pkt.Message)
+ if int32(len(builder.MessageSlices)) >= pkt.Message.Content.GetPkgNum() {
+ c.groupMsgBuilders.Delete(pkt.Message.Content.DivSeq)
+ c.dispatchGroupMessage(c.parseGroupMessage(builder.build()))
+ }
+ return nil, nil
+ }
+ c.dispatchGroupMessage(c.parseGroupMessage(pkt.Message))
+ return nil, nil
+}
+
+func decodeMsgSendResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
+ rsp := msg.SendMessageResponse{}
+ if err := proto.Unmarshal(payload, &rsp); err != nil {
+ return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
+ }
+ if rsp.GetResult() != 0 {
+ c.Error("send msg error: %v %v", rsp.GetResult(), rsp.GetErrMsg())
+ }
+ return nil, nil
+}
+
+func decodeGetGroupMsgResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
+ rsp := msg.GetGroupMsgResp{}
+ if err := proto.Unmarshal(payload, &rsp); err != nil {
+ return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
+ }
+ if rsp.GetResult() != 0 {
+ c.Error("get msg error: %v %v", rsp.GetResult(), rsp.GetErrmsg())
+ return nil, errors.Errorf("get msg error: %v msg: %v", rsp.GetResult(), rsp.GetErrmsg())
+ }
+ var ret []*message.GroupMessage
+ for _, m := range rsp.Msg {
+ if m.Head.FromUin == nil {
+ continue
+ }
+ ret = append(ret, c.parseGroupMessage(m))
+ }
+ return ret, nil
+}
diff --git a/client/offline_file.go b/client/offline_file.go
index 1f172978..63d2db09 100644
--- a/client/offline_file.go
+++ b/client/offline_file.go
@@ -7,6 +7,10 @@ import (
"google.golang.org/protobuf/proto"
)
+func init() {
+ decoders["OfflineFilleHandleSvr.pb_ftn_CMD_REQ_APPLY_DOWNLOAD-1200"] = decodeOfflineFileDownloadResponse
+}
+
func (c *QQClient) buildOfflineFileDownloadRequestPacket(uuid []byte) (uint16, []byte) {
seq := c.nextSeq()
req := &cmd0x346.C346ReqBody{
diff --git a/client/pb/msg/msg.pb.go b/client/pb/msg/msg.pb.go
index 1819e3b2..409b42f6 100644
--- a/client/pb/msg/msg.pb.go
+++ b/client/pb/msg/msg.pb.go
@@ -6547,6 +6547,196 @@ func (x *UinTypeUserDef) GetFileUuid() string {
return ""
}
+type GetGroupMsgReq struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ GroupCode *uint64 `protobuf:"varint,1,opt,name=groupCode" json:"groupCode,omitempty"`
+ BeginSeq *uint64 `protobuf:"varint,2,opt,name=beginSeq" json:"beginSeq,omitempty"`
+ EndSeq *uint64 `protobuf:"varint,3,opt,name=endSeq" json:"endSeq,omitempty"`
+ Filter *uint32 `protobuf:"varint,4,opt,name=filter" json:"filter,omitempty"`
+ MemberSeq *uint64 `protobuf:"varint,5,opt,name=memberSeq" json:"memberSeq,omitempty"`
+ PublicGroup *bool `protobuf:"varint,6,opt,name=publicGroup" json:"publicGroup,omitempty"`
+ ShieldFlag *uint32 `protobuf:"varint,7,opt,name=shieldFlag" json:"shieldFlag,omitempty"`
+ SaveTrafficFlag *uint32 `protobuf:"varint,8,opt,name=saveTrafficFlag" json:"saveTrafficFlag,omitempty"`
+}
+
+func (x *GetGroupMsgReq) Reset() {
+ *x = GetGroupMsgReq{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_msg_proto_msgTypes[65]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetGroupMsgReq) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetGroupMsgReq) ProtoMessage() {}
+
+func (x *GetGroupMsgReq) ProtoReflect() protoreflect.Message {
+ mi := &file_msg_proto_msgTypes[65]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetGroupMsgReq.ProtoReflect.Descriptor instead.
+func (*GetGroupMsgReq) Descriptor() ([]byte, []int) {
+ return file_msg_proto_rawDescGZIP(), []int{65}
+}
+
+func (x *GetGroupMsgReq) GetGroupCode() uint64 {
+ if x != nil && x.GroupCode != nil {
+ return *x.GroupCode
+ }
+ return 0
+}
+
+func (x *GetGroupMsgReq) GetBeginSeq() uint64 {
+ if x != nil && x.BeginSeq != nil {
+ return *x.BeginSeq
+ }
+ return 0
+}
+
+func (x *GetGroupMsgReq) GetEndSeq() uint64 {
+ if x != nil && x.EndSeq != nil {
+ return *x.EndSeq
+ }
+ return 0
+}
+
+func (x *GetGroupMsgReq) GetFilter() uint32 {
+ if x != nil && x.Filter != nil {
+ return *x.Filter
+ }
+ return 0
+}
+
+func (x *GetGroupMsgReq) GetMemberSeq() uint64 {
+ if x != nil && x.MemberSeq != nil {
+ return *x.MemberSeq
+ }
+ return 0
+}
+
+func (x *GetGroupMsgReq) GetPublicGroup() bool {
+ if x != nil && x.PublicGroup != nil {
+ return *x.PublicGroup
+ }
+ return false
+}
+
+func (x *GetGroupMsgReq) GetShieldFlag() uint32 {
+ if x != nil && x.ShieldFlag != nil {
+ return *x.ShieldFlag
+ }
+ return 0
+}
+
+func (x *GetGroupMsgReq) GetSaveTrafficFlag() uint32 {
+ if x != nil && x.SaveTrafficFlag != nil {
+ return *x.SaveTrafficFlag
+ }
+ return 0
+}
+
+type GetGroupMsgResp struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Result *uint32 `protobuf:"varint,1,opt,name=result" json:"result,omitempty"`
+ Errmsg *string `protobuf:"bytes,2,opt,name=errmsg" json:"errmsg,omitempty"`
+ GroupCode *uint64 `protobuf:"varint,3,opt,name=groupCode" json:"groupCode,omitempty"`
+ ReturnBeginSeq *uint64 `protobuf:"varint,4,opt,name=returnBeginSeq" json:"returnBeginSeq,omitempty"`
+ ReturnEndSeq *uint64 `protobuf:"varint,5,opt,name=returnEndSeq" json:"returnEndSeq,omitempty"`
+ Msg []*Message `protobuf:"bytes,6,rep,name=msg" json:"msg,omitempty"`
+}
+
+func (x *GetGroupMsgResp) Reset() {
+ *x = GetGroupMsgResp{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_msg_proto_msgTypes[66]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetGroupMsgResp) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetGroupMsgResp) ProtoMessage() {}
+
+func (x *GetGroupMsgResp) ProtoReflect() protoreflect.Message {
+ mi := &file_msg_proto_msgTypes[66]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetGroupMsgResp.ProtoReflect.Descriptor instead.
+func (*GetGroupMsgResp) Descriptor() ([]byte, []int) {
+ return file_msg_proto_rawDescGZIP(), []int{66}
+}
+
+func (x *GetGroupMsgResp) GetResult() uint32 {
+ if x != nil && x.Result != nil {
+ return *x.Result
+ }
+ return 0
+}
+
+func (x *GetGroupMsgResp) GetErrmsg() string {
+ if x != nil && x.Errmsg != nil {
+ return *x.Errmsg
+ }
+ return ""
+}
+
+func (x *GetGroupMsgResp) GetGroupCode() uint64 {
+ if x != nil && x.GroupCode != nil {
+ return *x.GroupCode
+ }
+ return 0
+}
+
+func (x *GetGroupMsgResp) GetReturnBeginSeq() uint64 {
+ if x != nil && x.ReturnBeginSeq != nil {
+ return *x.ReturnBeginSeq
+ }
+ return 0
+}
+
+func (x *GetGroupMsgResp) GetReturnEndSeq() uint64 {
+ if x != nil && x.ReturnEndSeq != nil {
+ return *x.ReturnEndSeq
+ }
+ return 0
+}
+
+func (x *GetGroupMsgResp) GetMsg() []*Message {
+ if x != nil {
+ return x.Msg
+ }
+ return nil
+}
+
var File_msg_proto protoreflect.FileDescriptor
var file_msg_proto_rawDesc = []byte{
@@ -7558,11 +7748,40 @@ var file_msg_proto_rawDesc = []byte{
0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12,
0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x2a, 0x2e, 0x0a, 0x08, 0x53,
- 0x79, 0x6e, 0x63, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54,
- 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4e, 0x54, 0x49, 0x4e, 0x55, 0x4d, 0x45, 0x10,
- 0x01, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x02, 0x42, 0x07, 0x5a, 0x05, 0x2e,
- 0x3b, 0x6d, 0x73, 0x67,
+ 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x22, 0x84, 0x02, 0x0a, 0x0e,
+ 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d, 0x73, 0x67, 0x52, 0x65, 0x71, 0x12, 0x1c,
+ 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x04, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08,
+ 0x62, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x71, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08,
+ 0x62, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x64, 0x53,
+ 0x65, 0x71, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x65, 0x6e, 0x64, 0x53, 0x65, 0x71,
+ 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62,
+ 0x65, 0x72, 0x53, 0x65, 0x71, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x6d, 0x65, 0x6d,
+ 0x62, 0x65, 0x72, 0x53, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
+ 0x47, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x70, 0x75, 0x62,
+ 0x6c, 0x69, 0x63, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x68, 0x69, 0x65,
+ 0x6c, 0x64, 0x46, 0x6c, 0x61, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x73, 0x68,
+ 0x69, 0x65, 0x6c, 0x64, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x61, 0x76, 0x65,
+ 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x46, 0x6c, 0x61, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28,
+ 0x0d, 0x52, 0x0f, 0x73, 0x61, 0x76, 0x65, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x46, 0x6c,
+ 0x61, 0x67, 0x22, 0xc7, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x4d,
+ 0x73, 0x67, 0x52, 0x65, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16,
+ 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
+ 0x65, 0x72, 0x72, 0x6d, 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x43,
+ 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70,
+ 0x43, 0x6f, 0x64, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x42, 0x65,
+ 0x67, 0x69, 0x6e, 0x53, 0x65, 0x71, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x53, 0x65, 0x71, 0x12, 0x22, 0x0a, 0x0c,
+ 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x45, 0x6e, 0x64, 0x53, 0x65, 0x71, 0x18, 0x05, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x45, 0x6e, 0x64, 0x53, 0x65, 0x71,
+ 0x12, 0x1a, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x2a, 0x2e, 0x0a, 0x08,
+ 0x53, 0x79, 0x6e, 0x63, 0x46, 0x6c, 0x61, 0x67, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52,
+ 0x54, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4e, 0x54, 0x49, 0x4e, 0x55, 0x4d, 0x45,
+ 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x02, 0x42, 0x07, 0x5a, 0x05,
+ 0x2e, 0x3b, 0x6d, 0x73, 0x67,
}
var (
@@ -7578,7 +7797,7 @@ func file_msg_proto_rawDescGZIP() []byte {
}
var file_msg_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 65)
+var file_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 67)
var file_msg_proto_goTypes = []interface{}{
(SyncFlag)(0), // 0: SyncFlag
(*GetMessageRequest)(nil), // 1: GetMessageRequest
@@ -7646,6 +7865,8 @@ var file_msg_proto_goTypes = []interface{}{
(*ResvAttr)(nil), // 63: ResvAttr
(*AnimationImageShow)(nil), // 64: AnimationImageShow
(*UinTypeUserDef)(nil), // 65: UinTypeUserDef
+ (*GetGroupMsgReq)(nil), // 66: GetGroupMsgReq
+ (*GetGroupMsgResp)(nil), // 67: GetGroupMsgResp
}
var file_msg_proto_depIdxs = []int32{
0, // 0: GetMessageRequest.syncFlag:type_name -> SyncFlag
@@ -7713,11 +7934,12 @@ var file_msg_proto_depIdxs = []int32{
34, // 62: MsgElemInfo_servtype3.flash_c2c_pic:type_name -> NotOnlineImage
35, // 63: SubMsgType0x4Body.notOnlineFile:type_name -> NotOnlineFile
64, // 64: ResvAttr.image_show:type_name -> AnimationImageShow
- 65, // [65:65] is the sub-list for method output_type
- 65, // [65:65] is the sub-list for method input_type
- 65, // [65:65] is the sub-list for extension type_name
- 65, // [65:65] is the sub-list for extension extendee
- 0, // [0:65] is the sub-list for field type_name
+ 20, // 65: GetGroupMsgResp.msg:type_name -> Message
+ 66, // [66:66] is the sub-list for method output_type
+ 66, // [66:66] is the sub-list for method input_type
+ 66, // [66:66] is the sub-list for extension type_name
+ 66, // [66:66] is the sub-list for extension extendee
+ 0, // [0:66] is the sub-list for field type_name
}
func init() { file_msg_proto_init() }
@@ -8506,6 +8728,30 @@ func file_msg_proto_init() {
return nil
}
}
+ file_msg_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetGroupMsgReq); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_msg_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetGroupMsgResp); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
}
type x struct{}
out := protoimpl.TypeBuilder{
@@ -8513,7 +8759,7 @@ func file_msg_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_msg_proto_rawDesc,
NumEnums: 1,
- NumMessages: 65,
+ NumMessages: 67,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/client/pb/msg/msg.proto b/client/pb/msg/msg.proto
index 1dc4ef57..01757128 100644
--- a/client/pb/msg/msg.proto
+++ b/client/pb/msg/msg.proto
@@ -748,4 +748,24 @@ message UinTypeUserDef {
optional int32 fromUinType = 1;
optional int64 fromGroupCode = 2;
optional string fileUuid = 3;
+}
+
+message GetGroupMsgReq {
+ optional uint64 groupCode = 1;
+ optional uint64 beginSeq = 2;
+ optional uint64 endSeq = 3;
+ optional uint32 filter = 4;
+ optional uint64 memberSeq = 5;
+ optional bool publicGroup = 6;
+ optional uint32 shieldFlag = 7;
+ optional uint32 saveTrafficFlag = 8;
+}
+
+message GetGroupMsgResp {
+ optional uint32 result = 1;
+ optional string errmsg = 2;
+ optional uint64 groupCode = 3;
+ optional uint64 returnBeginSeq = 4;
+ optional uint64 returnEndSeq = 5;
+ repeated Message msg = 6;
}
\ No newline at end of file