diff --git a/client/client.go b/client/client.go index 13f7efcb..5edb42d9 100644 --- a/client/client.go +++ b/client/client.go @@ -379,7 +379,7 @@ func (c *QQClient) SendGroupMessage(groupCode int64, m *message.SendingMessage, Message: m.Elements, }, }}) - if ret != nil && ret.Id == -1 { + if ret != nil && ret.Sources[0] == -1 { c.Error("long message send error. trying fragmented sending...") return c.SendGroupMessage(groupCode, m, true) } @@ -417,7 +417,7 @@ func (c *QQClient) sendGroupMessage(groupCode int64, forward bool, m *message.Se } var mid int32 ret := &message.GroupMessage{ - Id: -1, + Sources: []int32{-1}, InternalId: mr, GroupCode: groupCode, Sender: &message.Sender{ @@ -433,7 +433,7 @@ func (c *QQClient) sendGroupMessage(groupCode int64, forward bool, m *message.Se case <-time.After(time.Second * 5): return ret } - ret.Id = mid + ret.Sources = []int32{mid} return ret } diff --git a/client/decoders.go b/client/decoders.go index ac98d575..13de90de 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -316,25 +316,25 @@ func decodeGroupMessagePacket(c *QQClient, _ uint16, payload []byte) (interface{ return nil, nil } if pkt.Message.Content != nil && pkt.Message.Content.PkgNum > 1 { - var builder *groupMessageBuilder // TODO: 支持多SEQ + var builder *groupMessageBuilder i, ok := c.groupMsgBuilders.Load(pkt.Message.Content.DivSeq) if !ok { builder = &groupMessageBuilder{ - MessageSeq: pkt.Message.Content.DivSeq, - MessageCount: pkt.Message.Content.PkgNum, + SliceSeq: pkt.Message.Content.DivSeq, + SliceCount: pkt.Message.Content.PkgNum, } c.groupMsgBuilders.Store(pkt.Message.Content.DivSeq, builder) } else { builder = i.(*groupMessageBuilder) } builder.MessageSlices = append(builder.MessageSlices, pkt.Message) - if int32(len(builder.MessageSlices)) >= builder.MessageCount { + if int32(len(builder.MessageSlices)) >= builder.SliceCount { c.groupMsgBuilders.Delete(pkt.Message.Content.DivSeq) - c.dispatchGroupMessage(c.parseGroupMessage(builder.build())) + c.dispatchGroupMessage(c.parseGroupMessage(builder.build(), builder.seqs())) } return nil, nil } - c.dispatchGroupMessage(c.parseGroupMessage(pkt.Message)) + c.dispatchGroupMessage(c.parseGroupMessage(pkt.Message, nil)) return nil, nil } diff --git a/client/global.go b/client/global.go index c474d90e..6c641211 100644 --- a/client/global.go +++ b/client/global.go @@ -63,8 +63,9 @@ type DeviceInfoFile struct { } type groupMessageBuilder struct { - MessageSeq int32 - MessageCount int32 + SliceSeq int32 + SliceCount int32 + MessageSlices []*msg.Message } @@ -243,11 +244,11 @@ func (c *QQClient) parsePrivateMessage(msg *msg.Message) *message.PrivateMessage return ret } -func (c *QQClient) parseTempMessage(msg *msg.Message) *message.TempMessage { - group := c.FindGroupByUin(msg.Head.C2CTmpMsgHead.GroupUin) - mem := group.FindMember(msg.Head.FromUin) +func (c *QQClient) parseTempMessage(m *msg.Message) *message.TempMessage { + group := c.FindGroupByUin(m.Head.C2CTmpMsgHead.GroupUin) + mem := group.FindMember(m.Head.FromUin) sender := &message.Sender{ - Uin: msg.Head.FromUin, + Uin: m.Head.FromUin, Nickname: "Unknown", IsFriend: false, } @@ -256,15 +257,15 @@ func (c *QQClient) parseTempMessage(msg *msg.Message) *message.TempMessage { sender.CardName = mem.CardName } return &message.TempMessage{ - Id: msg.Head.MsgSeq, + Id: m.Head.MsgSeq, GroupCode: group.Code, GroupName: group.Name, Sender: sender, - Elements: message.ParseMessageElems(msg.Body.RichText.Elems), + Elements: message.ParseMessageElems(m.Body.RichText.Elems), } } -func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage { +func (c *QQClient) parseGroupMessage(m *msg.Message, seqs []int32) *message.GroupMessage { group := c.FindGroup(m.Head.GroupInfo.GroupCode) if group == nil { c.Debug("sync group %v.", m.Head.GroupInfo.GroupCode) @@ -319,8 +320,14 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage { } } var g *message.GroupMessage + seq := func() []int32 { + if len(seqs) == 0 { + return []int32{m.Head.MsgSeq} + } + return seqs + }() g = &message.GroupMessage{ - Id: m.Head.MsgSeq, + Sources: seq, GroupCode: group.Code, GroupName: string(m.Head.GroupInfo.GroupName), Sender: sender, @@ -333,7 +340,7 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage { if elem.GeneralFlags != nil && elem.GeneralFlags.LongTextResid != "" { if f := c.GetForwardMessage(elem.GeneralFlags.LongTextResid); f != nil && len(f.Nodes) == 1 { g = &message.GroupMessage{ - Id: m.Head.MsgSeq, + Sources: seq, GroupCode: group.Code, GroupName: string(m.Head.GroupInfo.GroupName), Sender: sender, @@ -370,6 +377,16 @@ func (b *groupMessageBuilder) build() *msg.Message { return base } +func (b *groupMessageBuilder) seqs() (r []int32) { + sort.Slice(b.MessageSlices, func(i, j int) bool { + return b.MessageSlices[i].Content.PkgIndex < b.MessageSlices[i].Content.PkgIndex + }) + for _, m := range b.MessageSlices { + r = append(r, m.Head.MsgSeq) + } + return +} + func packRequestDataV3(data []byte) (r []byte) { r = append([]byte{0x0A}, data...) r = append(r, 0x0B) diff --git a/message/elements.go b/message/elements.go index a6466e0a..3f5a07f5 100644 --- a/message/elements.go +++ b/message/elements.go @@ -168,7 +168,7 @@ func AtAll() *AtElement { func NewReply(m *GroupMessage) *ReplyElement { return &ReplyElement{ - ReplySeq: m.Id, + ReplySeq: m.Sources[0], Sender: m.Sender.Uin, Time: m.Time, //original: m.OriginalElements, diff --git a/message/message.go b/message/message.go index a6827c6a..573f2fc0 100644 --- a/message/message.go +++ b/message/message.go @@ -33,7 +33,7 @@ type ( } GroupMessage struct { - Id int32 + Sources []int32 InternalId int32 GroupCode int64 GroupName string