From 274c4a329a1bc29275d8b3ed245530a160d4546e Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 2 Oct 2020 16:27:05 +0800 Subject: [PATCH 1/6] fix bug. --- client/builders.go | 4 ++-- message/message.go | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/client/builders.go b/client/builders.go index fd10ca02..de540f1a 100644 --- a/client/builders.go +++ b/client/builders.go @@ -753,8 +753,8 @@ func (c *QQClient) buildGroupPttStorePacket(groupCode int64, md5 []byte, size, c func (c *QQClient) buildSystemMsgNewGroupPacket() (uint16, []byte) { seq := c.nextSeq() req := &structmsg.ReqSystemMsgNew{ - MsgNum: 10, - Version: 100, + MsgNum: 100, + Version: 1000, Checktype: 3, Flag: &structmsg.FlagInfo{ GrpMsgKickAdmin: 1, diff --git a/message/message.go b/message/message.go index f1856b8d..6fd9fd09 100644 --- a/message/message.go +++ b/message/message.go @@ -306,20 +306,18 @@ func ToProtoElems(elems []IMessageElement, generalFlags bool) (r []*msg.Elem) { CustomFace: &msg.CustomFace{ FilePath: e.Filename, Md5: e.Md5, - //Size: e.Size, - Flag: make([]byte, 4), - OldData: imgOld, + Flag: make([]byte, 4), + OldData: imgOld, }, }) case *GroupImageElement: r = append(r, &msg.Elem{ CustomFace: &msg.CustomFace{ - //FileType: 66, + FileType: 66, Useful: 1, Origin: 1, FileId: int32(e.FileId), FilePath: e.ImageId, - Size: e.Size, Md5: e.Md5[:], Flag: make([]byte, 4), //OldData: imgOld, From 383954dc11e2914df4bec76bf6cf4e2f3be96844 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 2 Oct 2020 16:36:53 +0800 Subject: [PATCH 2/6] fix android client image error. --- client/decoders.go | 2 +- message/message.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/client/decoders.go b/client/decoders.go index cece7b27..ac98d575 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -566,7 +566,7 @@ func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (inter } if rsp.BoolFileExit { if rsp.MsgImgInfo != nil { - return imageUploadResponse{IsExists: true, FileId: rsp.FileId, Width: rsp.MsgImgInfo.FileWidth, Height: rsp.MsgImgInfo.FileHeight}, nil + return imageUploadResponse{IsExists: true, FileId: rsp.Fid, Width: rsp.MsgImgInfo.FileWidth, Height: rsp.MsgImgInfo.FileHeight}, nil } return imageUploadResponse{IsExists: true, FileId: rsp.Fid}, nil } diff --git a/message/message.go b/message/message.go index 6fd9fd09..a6827c6a 100644 --- a/message/message.go +++ b/message/message.go @@ -306,6 +306,7 @@ func ToProtoElems(elems []IMessageElement, generalFlags bool) (r []*msg.Elem) { CustomFace: &msg.CustomFace{ FilePath: e.Filename, Md5: e.Md5, + Size: e.Size, Flag: make([]byte, 4), OldData: imgOld, }, @@ -318,6 +319,7 @@ func ToProtoElems(elems []IMessageElement, generalFlags bool) (r []*msg.Elem) { Origin: 1, FileId: int32(e.FileId), FilePath: e.ImageId, + Size: e.Size, Md5: e.Md5[:], Flag: make([]byte, 4), //OldData: imgOld, From ef17b3a30d3afa7f9d50adf27b8eb1ac76e4d03d Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 2 Oct 2020 16:47:08 +0800 Subject: [PATCH 3/6] fix typo. --- client/client.go | 4 ++-- client/highway.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/client.go b/client/client.go index 6065f786..13f7efcb 100644 --- a/client/client.go +++ b/client/client.go @@ -564,7 +564,7 @@ func (c *QQClient) sendGroupLongOrForwardMessage(groupCode int64, isLong bool, m }, }) for i, ip := range rsp.Uint32UpIp { - err := c.highwayUploadImage(uint32(ip), int(rsp.Uint32UpPort[i]), rsp.MsgSig, body, 27) + err := c.highwayUpload(uint32(ip), int(rsp.Uint32UpPort[i]), rsp.MsgSig, body, 27) if err == nil { if !isLong { var pv string @@ -613,7 +613,7 @@ func (c *QQClient) UploadGroupImage(groupCode int64, img []byte) (*message.Group goto ok } for i, ip := range rsp.UploadIp { - err := c.highwayUploadImage(uint32(ip), int(rsp.UploadPort[i]), rsp.UploadKey, img, 2) + err := c.highwayUpload(uint32(ip), int(rsp.UploadPort[i]), rsp.UploadKey, img, 2) if err != nil { continue } diff --git a/client/highway.go b/client/highway.go index 9e794aa0..2183c342 100644 --- a/client/highway.go +++ b/client/highway.go @@ -16,7 +16,7 @@ import ( "strconv" ) -func (c *QQClient) highwayUploadImage(ip uint32, port int, updKey, img []byte, cmdId int32) error { +func (c *QQClient) highwayUpload(ip uint32, port int, updKey, data []byte, cmdId int32) error { addr := net.TCPAddr{ IP: make([]byte, 4), Port: port, @@ -27,8 +27,8 @@ func (c *QQClient) highwayUploadImage(ip uint32, port int, updKey, img []byte, c return err } defer conn.Close() - h := md5.Sum(img) - pkt := c.buildImageUploadPacket(img, updKey, cmdId, h) + h := md5.Sum(data) + pkt := c.buildImageUploadPacket(data, updKey, cmdId, h) r := binary.NewNetworkReader(conn) for _, p := range pkt { _, err = conn.Write(p) From 9ac5ce958c6afdb6fa8fdf22120d720daf40a708 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 2 Oct 2020 17:14:26 +0800 Subject: [PATCH 4/6] supported group msg multi seq. --- client/client.go | 6 +++--- client/decoders.go | 12 ++++++------ client/global.go | 39 ++++++++++++++++++++++++++++----------- message/elements.go | 2 +- message/message.go | 2 +- 5 files changed, 39 insertions(+), 22 deletions(-) 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 From afe4132a38d56c47a297eb18dea6ab1b8afaeb50 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 2 Oct 2020 17:29:40 +0800 Subject: [PATCH 5/6] Revert "supported group msg multi seq." This reverts commit 9ac5ce95 --- client/client.go | 6 +++--- client/decoders.go | 12 ++++++------ client/global.go | 39 +++++++++++---------------------------- message/elements.go | 2 +- message/message.go | 2 +- 5 files changed, 22 insertions(+), 39 deletions(-) diff --git a/client/client.go b/client/client.go index 5edb42d9..13f7efcb 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.Sources[0] == -1 { + if ret != nil && ret.Id == -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{ - Sources: []int32{-1}, + Id: -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.Sources = []int32{mid} + ret.Id = mid return ret } diff --git a/client/decoders.go b/client/decoders.go index 13de90de..ac98d575 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 + var builder *groupMessageBuilder // TODO: 支持多SEQ i, ok := c.groupMsgBuilders.Load(pkt.Message.Content.DivSeq) if !ok { builder = &groupMessageBuilder{ - SliceSeq: pkt.Message.Content.DivSeq, - SliceCount: pkt.Message.Content.PkgNum, + MessageSeq: pkt.Message.Content.DivSeq, + MessageCount: 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.SliceCount { + if int32(len(builder.MessageSlices)) >= builder.MessageCount { c.groupMsgBuilders.Delete(pkt.Message.Content.DivSeq) - c.dispatchGroupMessage(c.parseGroupMessage(builder.build(), builder.seqs())) + c.dispatchGroupMessage(c.parseGroupMessage(builder.build())) } return nil, nil } - c.dispatchGroupMessage(c.parseGroupMessage(pkt.Message, nil)) + c.dispatchGroupMessage(c.parseGroupMessage(pkt.Message)) return nil, nil } diff --git a/client/global.go b/client/global.go index 6c641211..c474d90e 100644 --- a/client/global.go +++ b/client/global.go @@ -63,9 +63,8 @@ type DeviceInfoFile struct { } type groupMessageBuilder struct { - SliceSeq int32 - SliceCount int32 - + MessageSeq int32 + MessageCount int32 MessageSlices []*msg.Message } @@ -244,11 +243,11 @@ func (c *QQClient) parsePrivateMessage(msg *msg.Message) *message.PrivateMessage return ret } -func (c *QQClient) parseTempMessage(m *msg.Message) *message.TempMessage { - group := c.FindGroupByUin(m.Head.C2CTmpMsgHead.GroupUin) - mem := group.FindMember(m.Head.FromUin) +func (c *QQClient) parseTempMessage(msg *msg.Message) *message.TempMessage { + group := c.FindGroupByUin(msg.Head.C2CTmpMsgHead.GroupUin) + mem := group.FindMember(msg.Head.FromUin) sender := &message.Sender{ - Uin: m.Head.FromUin, + Uin: msg.Head.FromUin, Nickname: "Unknown", IsFriend: false, } @@ -257,15 +256,15 @@ func (c *QQClient) parseTempMessage(m *msg.Message) *message.TempMessage { sender.CardName = mem.CardName } return &message.TempMessage{ - Id: m.Head.MsgSeq, + Id: msg.Head.MsgSeq, GroupCode: group.Code, GroupName: group.Name, Sender: sender, - Elements: message.ParseMessageElems(m.Body.RichText.Elems), + Elements: message.ParseMessageElems(msg.Body.RichText.Elems), } } -func (c *QQClient) parseGroupMessage(m *msg.Message, seqs []int32) *message.GroupMessage { +func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage { group := c.FindGroup(m.Head.GroupInfo.GroupCode) if group == nil { c.Debug("sync group %v.", m.Head.GroupInfo.GroupCode) @@ -320,14 +319,8 @@ func (c *QQClient) parseGroupMessage(m *msg.Message, seqs []int32) *message.Grou } } var g *message.GroupMessage - seq := func() []int32 { - if len(seqs) == 0 { - return []int32{m.Head.MsgSeq} - } - return seqs - }() g = &message.GroupMessage{ - Sources: seq, + Id: m.Head.MsgSeq, GroupCode: group.Code, GroupName: string(m.Head.GroupInfo.GroupName), Sender: sender, @@ -340,7 +333,7 @@ func (c *QQClient) parseGroupMessage(m *msg.Message, seqs []int32) *message.Grou if elem.GeneralFlags != nil && elem.GeneralFlags.LongTextResid != "" { if f := c.GetForwardMessage(elem.GeneralFlags.LongTextResid); f != nil && len(f.Nodes) == 1 { g = &message.GroupMessage{ - Sources: seq, + Id: m.Head.MsgSeq, GroupCode: group.Code, GroupName: string(m.Head.GroupInfo.GroupName), Sender: sender, @@ -377,16 +370,6 @@ 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 3f5a07f5..a6466e0a 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.Sources[0], + ReplySeq: m.Id, Sender: m.Sender.Uin, Time: m.Time, //original: m.OriginalElements, diff --git a/message/message.go b/message/message.go index 573f2fc0..a6827c6a 100644 --- a/message/message.go +++ b/message/message.go @@ -33,7 +33,7 @@ type ( } GroupMessage struct { - Sources []int32 + Id int32 InternalId int32 GroupCode int64 GroupName string From 2050e45664949ec10885e438f90a3a7500247377 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Fri, 2 Oct 2020 17:53:27 +0800 Subject: [PATCH 6/6] add: GroupMemberInfo.Gender --- binary/jce/structs.go | 1 + client/decoders.go | 2 ++ client/entities.go | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/binary/jce/structs.go b/binary/jce/structs.go index 30e648e7..273e3d48 100644 --- a/binary/jce/structs.go +++ b/binary/jce/structs.go @@ -472,6 +472,7 @@ func (pkt *TroopMemberListRequest) ToBytes() []byte { func (pkt *TroopMemberInfo) ReadFrom(r *JceReader) { pkt.MemberUin = r.ReadInt64(0) pkt.FaceId = r.ReadInt16(1) + pkt.Gender = r.ReadByte(3) pkt.Nick = r.ReadString(4) pkt.ShowName = r.ReadString(6) pkt.Name = r.ReadString(8) diff --git a/client/decoders.go b/client/decoders.go index ac98d575..c01e585a 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -498,6 +498,7 @@ func decodeGroupMemberListResponse(_ *QQClient, _ uint16, payload []byte) (inter l = append(l, &GroupMemberInfo{ Uin: m.MemberUin, Nickname: m.Nick, + Gender: m.Gender, CardName: m.Name, Level: uint16(m.MemberLevel), JoinTime: m.JoinTime, @@ -531,6 +532,7 @@ func decodeGroupMemberInfoResponse(c *QQClient, _ uint16, payload []byte) (inter return &GroupMemberInfo{ Group: group, Uin: rsp.MemInfo.Uin, + Gender: byte(rsp.MemInfo.Sex), Nickname: string(rsp.MemInfo.Nick), CardName: string(rsp.MemInfo.Card), Level: uint16(rsp.MemInfo.Level), diff --git a/client/entities.go b/client/entities.go index 2be8d755..dac40505 100644 --- a/client/entities.go +++ b/client/entities.go @@ -77,6 +77,7 @@ type ( GroupMemberInfo struct { Group *GroupInfo Uin int64 + Gender byte Nickname string CardName string Level uint16 @@ -251,7 +252,6 @@ const ( AndroidPhone ClientProtocol = 537062845 AndroidPad ClientProtocol = 537062409 AndroidWatch ClientProtocol = 537061176 - ) func (g *GroupInfo) UpdateName(newName string) {