From 806ecc3697610f79ed2723db23bb92229314d6e7 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Mon, 20 Jul 2020 16:13:37 +0800 Subject: [PATCH] update func SendPrivateMessage(). add func QueryFriendImage(). --- client/builders.go | 7 +++--- client/client.go | 59 +++++++++++++++++++++++++++++++++------------- client/decoders.go | 13 ++++++++++ client/global.go | 10 ++++++-- message/message.go | 13 ++++++---- 5 files changed, 75 insertions(+), 27 deletions(-) diff --git a/client/builders.go b/client/builders.go index 9deee8d9..df03fb36 100644 --- a/client/builders.go +++ b/client/builders.go @@ -17,7 +17,6 @@ import ( "github.com/golang/protobuf/proto" "math/rand" "strconv" - "time" ) var ( @@ -404,7 +403,7 @@ func (c *QQClient) buildGroupSendingPacket(groupCode int64, r int32, m *message. } // MessageSvc.PbSendMsg -func (c *QQClient) buildFriendSendingPacket(target int64, r int32, m *message.SendingMessage) (uint16, []byte) { +func (c *QQClient) buildFriendSendingPacket(target int64, msgSeq, r int32, time int64, m *message.SendingMessage) (uint16, []byte) { seq := c.nextSeq() req := &msg.SendMessageRequest{ RoutingHead: &msg.RoutingHead{C2C: &msg.C2C{ToUin: target}}, @@ -414,11 +413,11 @@ func (c *QQClient) buildFriendSendingPacket(target int64, r int32, m *message.Se Elems: message.ToProtoElems(m.Elements), }, }, - MsgSeq: c.nextFriendSeq(), + MsgSeq: msgSeq, MsgRand: r, SyncCookie: func() []byte { cookie := &msg.SyncCookie{ - Time: time.Now().Unix(), + Time: time, Ran1: rand.Int63(), Ran2: rand.Int63(), Const1: syncConst1, diff --git a/client/client.go b/client/client.go index f64eae74..47663294 100644 --- a/client/client.go +++ b/client/client.go @@ -4,6 +4,7 @@ import ( "crypto/md5" "errors" "github.com/Mrs4s/MiraiGo/binary" + "github.com/Mrs4s/MiraiGo/client/pb/msg" "github.com/Mrs4s/MiraiGo/message" "github.com/Mrs4s/MiraiGo/protocol/packets" "github.com/Mrs4s/MiraiGo/utils" @@ -144,6 +145,7 @@ func (c *QQClient) Login() (*LoginResponse, error) { if l.Success { c.registerClient() go c.heartbeat() + _, _ = c.sendAndWait(c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix())) } return &l, nil } @@ -227,10 +229,24 @@ func (c *QQClient) SendGroupMessage(groupCode int64, m *message.SendingMessage) return ret } -func (c *QQClient) SendPrivateMessage(target int64, m *message.SendingMessage) { +func (c *QQClient) SendPrivateMessage(target int64, m *message.SendingMessage) *message.PrivateMessage { mr := int32(rand.Uint32()) - _, pkt := c.buildFriendSendingPacket(target, mr, m) + seq := c.nextFriendSeq() + t := time.Now().Unix() + _, pkt := c.buildFriendSendingPacket(target, seq, mr, t, m) _ = c.send(pkt) + return &message.PrivateMessage{ + Id: seq, + InternalId: mr, + Target: target, + Time: int32(t), + Sender: &message.Sender{ + Uin: c.Uin, + Nickname: c.Nickname, + IsFriend: true, + }, + Elements: m.Elements, + } } func (c *QQClient) RecallGroupMessage(groupCode int64, msgId, msgInternalId int32) { @@ -256,7 +272,7 @@ func (c *QQClient) UploadGroupImage(groupCode int64, img []byte) (*message.Group updServer := binary.UInt32ToIPV4Address(uint32(ip)) err := c.highwayUploadImage(updServer+":"+strconv.FormatInt(int64(rsp.UploadPort[i]), 10), rsp.UploadKey, img) if err != nil { - return nil, err + continue } return message.NewGroupImage(binary.CalculateImageResourceId(h[:]), h[:]), nil } @@ -270,16 +286,10 @@ func (c *QQClient) UploadPrivateImage(target int64, img []byte) (*message.Friend func (c *QQClient) uploadPrivateImage(target int64, img []byte, count int) (*message.FriendImageElement, error) { count++ h := md5.Sum(img) - i, err := c.sendAndWait(c.buildOffPicUpPacket(target, h[:], int32(len(img)))) + e, err := c.QueryFriendImage(target, h[:], int32(len(img))) if err != nil { - return nil, err - } - rsp := i.(imageUploadResponse) - if rsp.ResultCode != 0 { - return nil, errors.New(rsp.Message) - } - if !rsp.IsExists { - if _, err = c.UploadGroupImage(0, img); err != nil { + // use group highway upload and query again for image id. + if _, err = c.UploadGroupImage(target, img); err != nil { return nil, err } // safe @@ -288,10 +298,7 @@ func (c *QQClient) uploadPrivateImage(target int64, img []byte, count int) (*mes } return c.uploadPrivateImage(target, img, count) } - return &message.FriendImageElement{ - ImageId: rsp.ResourceId, - Md5: h[:], - }, nil + return e, nil } func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*message.GroupImageElement, error) { @@ -309,6 +316,24 @@ func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*m return nil, errors.New("image not exists") } +func (c *QQClient) QueryFriendImage(target int64, hash []byte, size int32) (*message.FriendImageElement, error) { + i, err := c.sendAndWait(c.buildOffPicUpPacket(target, hash, size)) + if err != nil { + return nil, err + } + rsp := i.(imageUploadResponse) + if rsp.ResultCode != 0 { + return nil, errors.New(rsp.Message) + } + if !rsp.IsExists { + return nil, errors.New("image not exists") + } + return &message.FriendImageElement{ + ImageId: rsp.ResourceId, + Md5: hash, + }, nil +} + func (c *QQClient) ReloadGroupList() error { c.groupListLock.Lock() defer c.groupListLock.Unlock() @@ -467,7 +492,7 @@ func (c *QQClient) nextGroupSeq() int32 { func (c *QQClient) nextFriendSeq() int32 { s := atomic.LoadInt32(&c.friendSeq) - atomic.AddInt32(&c.friendSeq, 2) + atomic.AddInt32(&c.friendSeq, 1) return s } diff --git a/client/decoders.go b/client/decoders.go index e7b6ae00..5c608b4e 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -10,6 +10,7 @@ import ( "github.com/Mrs4s/MiraiGo/client/pb/structmsg" "github.com/golang/protobuf/proto" "sync" + "sync/atomic" "time" ) @@ -208,6 +209,18 @@ func decodeMessageSvcPacket(c *QQClient, _ uint16, payload []byte) (interface{}, c.dispatchTempMessage(c.parseTempMessage(message)) } case 166: // 好友消息 + if message.Head.FromUin == c.Uin { + for { + frdSeq := atomic.LoadInt32(&c.friendSeq) + if frdSeq < message.Head.MsgSeq { + if atomic.CompareAndSwapInt32(&c.friendSeq, frdSeq, message.Head.MsgSeq) { + break + } + } else { + break + } + } + } if message.Body.RichText == nil || message.Body.RichText.Elems == nil { continue } diff --git a/client/global.go b/client/global.go index 4e8d89a1..cffec4c4 100644 --- a/client/global.go +++ b/client/global.go @@ -183,14 +183,20 @@ func (c *QQClient) parsePrivateMessage(msg *msg.Message) *message.PrivateMessage if friend == nil { return nil } - return &message.PrivateMessage{ - Id: msg.Head.MsgSeq, + ret := &message.PrivateMessage{ + Id: msg.Head.MsgSeq, + Target: c.Uin, + Time: msg.Head.MsgTime, Sender: &message.Sender{ Uin: friend.Uin, Nickname: friend.Nickname, }, Elements: message.ParseMessageElems(msg.Body.RichText.Elems), } + if msg.Body.RichText.Attr != nil { + ret.InternalId = msg.Body.RichText.Attr.Random + } + return ret } func (c *QQClient) parseTempMessage(msg *msg.Message) *message.TempMessage { diff --git a/message/message.go b/message/message.go index ce04e3b6..503f487e 100644 --- a/message/message.go +++ b/message/message.go @@ -8,9 +8,12 @@ import ( ) type PrivateMessage struct { - Id int32 - Sender *Sender - Elements []IMessageElement + Id int32 + InternalId int32 + Target int64 + Time int32 + Sender *Sender + Elements []IMessageElement } type TempMessage struct { @@ -118,7 +121,9 @@ func (msg *GroupMessage) ToString() (res string) { } func (msg *SendingMessage) Append(e IMessageElement) *SendingMessage { - msg.Elements = append(msg.Elements, e) + if e != nil { + msg.Elements = append(msg.Elements, e) + } return msg }