Skip to content

Commit

Permalink
fix: 修复新协议接收图片相关问题(#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
Redmomn committed Aug 6, 2024
1 parent 4195ca5 commit 7f2a302
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 110 deletions.
17 changes: 13 additions & 4 deletions client/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,14 @@ func decodeKickNTPacket(c *QQClient, pkt *network.Packet) (any, error) {
func (c *QQClient) PreprocessGroupMessageEvent(msg *msgConverter.GroupMessage) error {
for _, elem := range msg.Elements {
switch e := elem.(type) {
case *msgConverter.VoiceElement:
url, err := c.GetGroupRecordUrl(msg.GroupUin, e.Node)
if err != nil {
return err
case *msgConverter.ImageElement:
if e.Url != "" {
continue
}
url, _ := c.GetGroupImageUrl(msg.GroupUin, e.MsgInfo.MsgInfoBody[0].Index)
e.Url = url
case *msgConverter.VoiceElement:
url, _ := c.GetGroupRecordUrl(msg.GroupUin, e.Node)
e.Url = url
}
}
Expand All @@ -335,6 +338,12 @@ func (c *QQClient) PreprocessPrivateMessageEvent(msg *msgConverter.PrivateMessag
}
for _, elem := range msg.Elements {
switch e := elem.(type) {
case *msgConverter.ImageElement:
if e.Url != "" {
continue
}
url, _ := c.GetPrivateImageUrl(e.MsgInfo.MsgInfoBody[0].Index)
e.Url = url
case *msgConverter.VoiceElement:
url, err := c.GetPrivateRecordUrl(e.Node)
if err != nil {
Expand Down
28 changes: 27 additions & 1 deletion client/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,33 @@ func (c *QQClient) RecallGroupMessage(GrpUin, seq uint32) error {
return nil
}

// GetPrivateRecordUrl 获取私聊语言下载url
// GetPrivateImageUrl 获取私聊图片下载url
func (c *QQClient) GetPrivateImageUrl(node *oidb.IndexNode) (string, error) {
pkt, err := oidb2.BuildPrivateImageDownloadReq(c.GetUid(c.Uin), node)
if err != nil {
return "", err
}
resp, err := c.sendOidbPacketAndWait(pkt)
if err != nil {
return "", err
}
return oidb2.ParsePrivateImageDownloadResp(resp)
}

// GetGroupImageUrl 获取群聊图片下载url
func (c *QQClient) GetGroupImageUrl(groupUin uint32, node *oidb.IndexNode) (string, error) {
pkt, err := oidb2.BuildGroupImageDownloadReq(groupUin, node)
if err != nil {
return "", err
}
resp, err := c.sendOidbPacketAndWait(pkt)
if err != nil {
return "", err
}
return oidb2.ParseGroupImageDownloadResp(resp)
}

// GetPrivateRecordUrl 获取私聊语音下载url
func (c *QQClient) GetPrivateRecordUrl(node *oidb.IndexNode) (string, error) {
pkt, err := oidb2.BuildPrivateRecordDownloadReq(c.GetUid(c.Uin), node)
if err != nil {
Expand Down
44 changes: 44 additions & 0 deletions client/packets/oidb/GroupImageDownload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package oidb

import (
"fmt"

oidb2 "github.com/LagrangeDev/LagrangeGo/client/packets/pb/service/oidb"
)

func BuildGroupImageDownloadReq(groupUin uint32, node *oidb2.IndexNode) (*OidbPacket, error) {
body := &oidb2.NTV2RichMediaReq{
ReqHead: &oidb2.MultiMediaReqHead{
Common: &oidb2.CommonHead{
RequestId: 1,
Command: 200,
},
Scene: &oidb2.SceneInfo{
RequestType: 2,
BusinessType: 1,
SceneType: 2,
Group: &oidb2.NTGroupInfo{GroupUin: groupUin},
},
Client: &oidb2.ClientMeta{AgentType: 2},
},
Download: &oidb2.DownloadReq{
Node: node,
Download: &oidb2.DownloadExt{
Video: &oidb2.VideoDownloadExt{
BusiType: 0,
SceneType: 0,
},
},
},
}
return BuildOidbPacket(0x11C4, 200, body, false, true)
}

func ParseGroupImageDownloadResp(data []byte) (string, error) {
resp, err := ParseTypedError[oidb2.NTV2RichMediaResp](data)
if err != nil {
return "", err
}
body := resp.Download
return fmt.Sprintf("https://%s%s%s", body.Info.Domain, body.Info.UrlPath, body.RKeyParam), nil
}
47 changes: 47 additions & 0 deletions client/packets/oidb/PrivateImageDownload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package oidb

import (
"fmt"

oidb2 "github.com/LagrangeDev/LagrangeGo/client/packets/pb/service/oidb"
)

func BuildPrivateImageDownloadReq(selfUid string, node *oidb2.IndexNode) (*OidbPacket, error) {
body := &oidb2.NTV2RichMediaReq{
ReqHead: &oidb2.MultiMediaReqHead{
Common: &oidb2.CommonHead{
RequestId: 1,
Command: 200,
},
Scene: &oidb2.SceneInfo{
RequestType: 2,
BusinessType: 1,
SceneType: 1,
C2C: &oidb2.C2CUserInfo{
AccountType: 2,
TargetUid: selfUid,
},
},
Client: &oidb2.ClientMeta{AgentType: 2},
},
Download: &oidb2.DownloadReq{
Node: node,
Download: &oidb2.DownloadExt{
Video: &oidb2.VideoDownloadExt{
BusiType: 0,
SceneType: 0,
},
},
},
}
return BuildOidbPacket(0x11C5, 200, body, false, true)
}

func ParsePrivateImageDownloadResp(data []byte) (string, error) {
resp, err := ParseTypedError[oidb2.NTV2RichMediaResp](data)
if err != nil {
return "", err
}
body := resp.Download
return fmt.Sprintf("https://%s%s%s", body.Info.Domain, body.Info.UrlPath, body.RKeyParam), nil
}
52 changes: 0 additions & 52 deletions client/packets/pb/message/element.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 0 additions & 46 deletions client/packets/pb/message/element.proto
Original file line number Diff line number Diff line change
Expand Up @@ -391,49 +391,3 @@ message QSmallFaceExtra {
string Preview = 2;
string Preview2 = 3;
}

message CommonElemImagePb {
CommonImage1 Field1 = 1;
CommonImage2 Field2 = 2;
}

message CommonImage1 {
CommonImageExtra Extra = 1;
ImageUrl Url = 2;
}

message CommonImage2 {
ImageDownloadInfo DownloadInfo = 1;
}

message CommonImageExtra {
CommonImageInfo Info = 1;
string FileUuid = 2;
uint32 Timestamp = 4;
}

message ImageDownloadInfo {
ImageDownloadInfoField12 Info = 12;
}

message ImageDownloadInfoField12 {
string PathWithRkey = 30;
}

message CommonImageInfo {
uint32 Size = 1;
string Md5 = 2;
string Sha1 = 3;
string FileName = 4;
uint32 Width = 6;
uint32 Height = 7;
uint32 Field8 = 8;
uint32 Field9 = 9;
}

message ImageUrl {
string Path = 1;
string Host = 3;
}


16 changes: 9 additions & 7 deletions message/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,17 +262,19 @@ func parseMessageElements(msg []*message.Elem) []IMessageElement {
}

// new protocol image
if elem.CommonElem != nil && elem.CommonElem.ServiceType == 48 && elem.CommonElem.BusinessType == 20 {
pb := message.CommonElemImagePb{}
err := proto.Unmarshal(elem.CommonElem.PbElem, &pb)
if elem.CommonElem != nil && (elem.CommonElem.BusinessType == 20 || elem.CommonElem.BusinessType == 10) {
extra := &oidb2.MsgInfo{}
err := proto.Unmarshal(elem.CommonElem.PbElem, extra)
if err != nil {
continue
}
index := extra.MsgInfoBody[0].Index
res = append(res, &ImageElement{
ImageId: pb.Field1.Extra.FileUuid,
Size: pb.Field1.Extra.Info.Size,
Url: "https://multimedia.nt.qq.com.cn" + pb.Field2.DownloadInfo.Info.PathWithRkey,
Md5: utils.MustParseHexStr(pb.Field1.Extra.Info.Md5),
Width: index.Info.Width,
Height: index.Info.Height,
ImageId: index.Info.FileName,
Size: index.Info.FileSize,
MsgInfo: extra,
})
}

Expand Down

0 comments on commit 7f2a302

Please sign in to comment.