1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

rf(message): refactor image & flash image [break-change].

This commit is contained in:
wdvxdr 2021-07-18 11:32:51 +08:00
parent 36f8422812
commit b93c02e18e
No known key found for this signature in database
GPG Key ID: 55FF1414A69CEBA6
5 changed files with 176 additions and 286 deletions

View File

@ -150,19 +150,6 @@ func (c *QQClient) ImageOcr(img interface{}) (*OcrResponse, error) {
return nil, err
}
return rsp.(*OcrResponse), nil
case *message.ImageElement:
url = e.Url
if b, err := utils.HTTPGetReadCloser(e.Url, ""); err == nil {
if url, err = c.uploadOcrImage(b, int64(e.Size), e.Md5); err != nil {
url = e.Url
}
_ = b.Close()
}
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height))
if err != nil {
return nil, err
}
return rsp.(*OcrResponse), nil
}
return nil, errors.New("image error")
}

View File

@ -3,9 +3,7 @@ package message
import (
"fmt"
"strconv"
"strings"
"github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/client/pb/msg"
)
@ -15,27 +13,6 @@ type TextElement struct {
Content string
}
type ImageElement struct {
Filename string
Size int32
Width int32
Height int32
Url string
Md5 []byte
Data []byte
}
type GroupImageElement struct {
ImageId string
FileId int64
ImageType int32
Size int32
Width int32
Height int32
Md5 []byte
Url string
}
type VoiceElement struct {
Name string
Md5 []byte
@ -56,12 +33,6 @@ type PrivateVoiceElement struct {
Ptt *msg.Ptt
}
type FriendImageElement struct {
ImageId string
Md5 []byte
Url string
}
type FaceElement struct {
Index int32
Name string
@ -127,29 +98,6 @@ type MusicShareElement struct {
MusicUrl string // 音乐播放链接
}
// TODO: 总之就是非常傻逼
type GroupFlashImgElement struct {
ImageElement
}
type GroupFlashPicElement struct {
GroupImageElement
}
type GroupShowPicElement struct {
GroupImageElement
EffectId int32
}
type FriendFlashImgElement struct {
ImageElement
}
type FriendFlashPicElement struct {
FriendImageElement
}
type RedBagMessageType int
// /com/tencent/mobileqq/data/MessageForQQWalletMsg.java
@ -180,25 +128,6 @@ func NewText(s string) *TextElement {
return &TextElement{Content: s}
}
func NewImage(data []byte) *ImageElement {
return &ImageElement{
Data: data,
}
}
func NewGroupImage(id string, md5 []byte, fid int64, size, width, height, imageType int32) *GroupImageElement {
return &GroupImageElement{
ImageId: id,
FileId: fid,
Md5: md5,
Size: size,
ImageType: imageType,
Width: width,
Height: height,
Url: "https://gchat.qpic.cn/gchatpic_new/1/0-0-" + strings.ReplaceAll(binary.CalculateImageResourceId(md5)[1:37], "-", "") + "/0?term=2",
}
}
func NewFace(index int32) *FaceElement {
name := faceMap[int(index)]
if name == "" {
@ -291,30 +220,10 @@ func (e *TextElement) Type() ElementType {
return Text
}
func (e *ImageElement) Type() ElementType {
return Image
}
func (e *GroupFlashImgElement) Type() ElementType {
return Image
}
func (e *FriendFlashImgElement) Type() ElementType {
return Image
}
func (e *FaceElement) Type() ElementType {
return Face
}
func (e *GroupImageElement) Type() ElementType {
return Image
}
func (e *FriendImageElement) Type() ElementType {
return Image
}
func (e *AtElement) Type() ElementType {
return At
}

138
message/image.go Normal file
View File

@ -0,0 +1,138 @@
package message
import (
"strings"
"google.golang.org/protobuf/proto"
"github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/client/pb/msg"
)
/* -------- Definitions -------- */
type GroupImageElement struct {
ImageId string
FileId int64
ImageType int32
Size int32
Width int32
Height int32
Md5 []byte
Url string
// EffectID show pic effect id.
EffectID int32
Flash bool
}
type FriendImageElement struct {
ImageId string
Md5 []byte
Size int32
Url string
Flash bool
}
/* ------ Implementations ------ */
func NewGroupImage(id string, md5 []byte, fid int64, size, width, height, imageType int32) *GroupImageElement {
return &GroupImageElement{
ImageId: id,
FileId: fid,
Md5: md5,
Size: size,
ImageType: imageType,
Width: width,
Height: height,
Url: "https://gchat.qpic.cn/gchatpic_new/1/0-0-" + strings.ReplaceAll(binary.CalculateImageResourceId(md5)[1:37], "-", "") + "/0?term=2",
}
}
func (e *GroupImageElement) Type() ElementType {
return Image
}
func (e *FriendImageElement) Type() ElementType {
return Image
}
func (e *GroupImageElement) Pack() (r []*msg.Elem) {
cface := &msg.CustomFace{
FileType: proto.Int32(66),
Useful: proto.Int32(1),
// Origin: 1,
BizType: proto.Int32(5),
Width: &e.Width,
Height: &e.Height,
FileId: proto.Int32(int32(e.FileId)),
FilePath: &e.ImageId,
ImageType: &e.ImageType,
Size: &e.Size,
Md5: e.Md5,
Flag: make([]byte, 4),
// OldData: imgOld,
}
if e.Flash { // resolve flash pic
flash := &msg.MsgElemInfoServtype3{FlashTroopPic: cface}
data, _ := proto.Marshal(flash)
flashElem := &msg.Elem{
CommonElem: &msg.CommonElem{
ServiceType: proto.Int32(3),
PbElem: data,
},
}
textHint := &msg.Elem{
Text: &msg.Text{
Str: proto.String("[闪照]请使用新版手机QQ查看闪照。"),
},
}
return []*msg.Elem{flashElem, textHint}
}
if e.EffectID != 0 { // resolve show pic
res := &msg.ResvAttr{ImageShow: &msg.AnimationImageShow{
EffectId: &e.EffectID,
AnimationParam: []byte("{}"),
}}
cface.PbReserve, _ = proto.Marshal(res)
cface.Flag = []byte{0x11, 0x00, 0x00, 0x00}
}
elem := &msg.Elem{CustomFace: cface}
return []*msg.Elem{elem}
}
func (e *FriendImageElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
image := &msg.NotOnlineImage{
FilePath: &e.ImageId,
ResId: &e.ImageId,
OldPicMd5: proto.Bool(false),
PicMd5: e.Md5,
DownloadPath: &e.ImageId,
Original: proto.Int32(1),
PbReserve: []byte{0x78, 0x02},
}
if e.Flash {
flash := &msg.MsgElemInfoServtype3{FlashC2CPic: image}
data, _ := proto.Marshal(flash)
flashElem := &msg.Elem{
CommonElem: &msg.CommonElem{
ServiceType: proto.Int32(3),
PbElem: data,
},
}
textHint := &msg.Elem{
Text: &msg.Text{
Str: proto.String("[闪照]请使用新版手机QQ查看闪照。"),
},
}
return []*msg.Elem{flashElem, textHint}
}
elem := &msg.Elem{NotOnlineImage: image}
return []*msg.Elem{elem}
}

View File

@ -131,11 +131,6 @@ func (msg *PrivateMessage) ToString() (res string) {
switch e := elem.(type) {
case *TextElement:
res += e.Content
case *ImageElement:
res += "[Image:" + e.Filename + "]"
case *FriendFlashImgElement:
// NOTE: ignore other components
return "[Image (flash):" + e.Filename + "]"
case *FaceElement:
res += "[" + e.Name + "]"
case *AtElement:
@ -150,8 +145,6 @@ func (msg *TempMessage) ToString() (res string) {
switch e := elem.(type) {
case *TextElement:
res += e.Content
case *ImageElement:
res += "[Image:" + e.Filename + "]"
case *FaceElement:
res += "[" + e.Name + "]"
case *AtElement:
@ -166,15 +159,10 @@ func (msg *GroupMessage) ToString() (res string) {
switch e := elem.(type) {
case *TextElement:
res += e.Content
case *ImageElement:
res += "[Image:" + e.Filename + "]"
case *FaceElement:
res += "[" + e.Name + "]"
case *GroupImageElement:
res += "[Image: " + e.ImageId + "]"
case *GroupFlashImgElement:
// NOTE: ignore other components
return "[Image (flash):" + e.Filename + "]"
case *AtElement:
res += e.Display
case *RedBagElement:
@ -246,7 +234,7 @@ func EstimateLength(elems []IMessageElement) int {
sum += len(e.Display)
case *ReplyElement:
sum += 444 + EstimateLength(e.Elements)
case *ImageElement, *GroupImageElement, *FriendImageElement:
case *GroupImageElement, *FriendImageElement:
sum += 100
default:
sum += len(ToReadableString([]IMessageElement{elem}))
@ -332,15 +320,15 @@ func ToProtoElems(elems []IMessageElement, generalFlags bool) (r []*msg.Elem) {
func ToSrcProtoElems(elems []IMessageElement) (r []*msg.Elem) {
for _, elem := range elems {
switch e := elem.(type) {
case *ImageElement, *GroupImageElement, *FriendImageElement:
switch elem.Type() {
case Image:
r = append(r, &msg.Elem{
Text: &msg.Text{
Str: proto.String("[图片]"),
},
})
default:
r = append(r, ToProtoElems([]IMessageElement{e}, false)...)
r = append(r, ToProtoElems([]IMessageElement{elem}, false)...)
}
}
return
@ -456,11 +444,11 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement {
if len(elem.CustomFace.Md5) == 0 {
continue
}
res = append(res, &ImageElement{
Filename: elem.CustomFace.GetFilePath(),
Size: elem.CustomFace.GetSize(),
Width: elem.CustomFace.GetWidth(),
Height: elem.CustomFace.GetHeight(),
res = append(res, &GroupImageElement{
ImageId: elem.CustomFace.GetFilePath(),
Size: elem.CustomFace.GetSize(),
Width: elem.CustomFace.GetWidth(),
Height: elem.CustomFace.GetHeight(),
Url: func() string {
if elem.CustomFace.GetOrigUrl() == "" {
return "https://gchat.qpic.cn/gchatpic_new/0/0-0-" + strings.ReplaceAll(binary.CalculateImageResourceId(elem.CustomFace.Md5)[1:37], "-", "") + "/0?term=2"
@ -477,11 +465,11 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement {
} else {
img = "https://c2cpicdw.qpic.cn/offpic_new/0/" + elem.NotOnlineImage.GetResId() + "/0?term=2"
}
res = append(res, &ImageElement{
Filename: elem.NotOnlineImage.GetFilePath(),
Size: elem.NotOnlineImage.GetFileLen(),
Url: img,
Md5: elem.NotOnlineImage.PicMd5,
res = append(res, &FriendImageElement{
ImageId: elem.NotOnlineImage.GetFilePath(),
Size: elem.NotOnlineImage.GetFileLen(),
Url: img,
Md5: elem.NotOnlineImage.PicMd5,
})
}
if elem.QQWalletMsg != nil && elem.QQWalletMsg.AioBody != nil {
@ -505,24 +493,22 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement {
flash := &msg.MsgElemInfoServtype3{}
_ = proto.Unmarshal(elem.CommonElem.PbElem, flash)
if flash.FlashTroopPic != nil {
res = append(res, &GroupFlashImgElement{
ImageElement{
Filename: flash.FlashTroopPic.GetFilePath(),
Size: flash.FlashTroopPic.GetSize(),
Width: flash.FlashTroopPic.GetWidth(),
Height: flash.FlashTroopPic.GetHeight(),
Md5: flash.FlashTroopPic.Md5,
},
res = append(res, &GroupImageElement{
ImageId: flash.FlashTroopPic.GetFilePath(),
Size: flash.FlashTroopPic.GetSize(),
Width: flash.FlashTroopPic.GetWidth(),
Height: flash.FlashTroopPic.GetHeight(),
Md5: flash.FlashTroopPic.Md5,
Flash: true,
})
return res
}
if flash.FlashC2CPic != nil {
res = append(res, &GroupFlashImgElement{
ImageElement{
Filename: flash.FlashC2CPic.GetFilePath(),
Size: flash.FlashC2CPic.GetFileLen(),
Md5: flash.FlashC2CPic.PicMd5,
},
res = append(res, &FriendImageElement{
ImageId: flash.FlashC2CPic.GetFilePath(),
Size: flash.FlashC2CPic.GetFileLen(),
Md5: flash.FlashC2CPic.PicMd5,
Flash: true,
})
return res
}
@ -536,19 +522,19 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement {
return res
}
func ToReadableString(m []IMessageElement) (r string) {
func ToReadableString(m []IMessageElement) string {
sb := new(strings.Builder)
for _, elem := range m {
switch e := elem.(type) {
case *TextElement:
r += e.Content
case *ImageElement:
r += "[图片]"
sb.WriteString(e.Content)
case *GroupImageElement, *FriendImageElement:
sb.WriteString("[图片]")
case *FaceElement:
r += "/" + e.Name
case *GroupImageElement:
r += "[图片]"
sb.WriteByte('/')
sb.WriteString(e.Name)
case *ForwardElement:
r += "[聊天记录]"
sb.WriteString("[聊天记录]")
// NOTE: flash pic is singular
// To be clarified
// case *GroupFlashImgElement:
@ -556,10 +542,10 @@ func ToReadableString(m []IMessageElement) (r string) {
// case *FriendFlashImgElement:
// return "[闪照]"
case *AtElement:
r += e.Display
sb.WriteString(e.Display)
}
}
return
return sb.String()
}
func FaceNameById(id int) string {

View File

@ -9,11 +9,13 @@ import (
"github.com/Mrs4s/MiraiGo/client/pb/msg"
)
/*
var imgOld = []byte{
0x15, 0x36, 0x20, 0x39, 0x32, 0x6B, 0x41, 0x31, 0x00, 0x38, 0x37, 0x32, 0x66, 0x30, 0x36, 0x36, 0x30, 0x33, 0x61, 0x65, 0x31, 0x30, 0x33, 0x62, 0x37, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x35, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7B, 0x30, 0x31, 0x45, 0x39, 0x34, 0x35, 0x31, 0x42, 0x2D, 0x37, 0x30, 0x45, 0x44,
0x2D, 0x45, 0x41, 0x45, 0x33, 0x2D, 0x42, 0x33, 0x37, 0x43, 0x2D, 0x31, 0x30, 0x31, 0x46, 0x31, 0x45, 0x45, 0x42, 0x46, 0x35, 0x42, 0x35, 0x7D, 0x2E, 0x70, 0x6E, 0x67, 0x41,
}
*/
func (e *TextElement) Pack() (r []*msg.Elem) {
r = append(r, &msg.Elem{
@ -76,58 +78,6 @@ func (e *AtElement) Pack() (r []*msg.Elem) {
return
}
func (e *ImageElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
r = append(r, &msg.Elem{
CustomFace: &msg.CustomFace{
FilePath: &e.Filename,
Md5: e.Md5,
Size: &e.Size,
Flag: make([]byte, 4),
OldData: imgOld,
},
})
return
}
func (e *GroupImageElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
r = append(r, &msg.Elem{
CustomFace: &msg.CustomFace{
FileType: proto.Int32(66),
Useful: proto.Int32(1),
// Origin: 1,
BizType: proto.Int32(5),
Width: &e.Width,
Height: &e.Height,
FileId: proto.Int32(int32(e.FileId)),
FilePath: &e.ImageId,
ImageType: &e.ImageType,
Size: &e.Size,
Md5: e.Md5,
Flag: make([]byte, 4),
// OldData: imgOld,
},
})
return
}
func (e *FriendImageElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
r = append(r, &msg.Elem{
NotOnlineImage: &msg.NotOnlineImage{
FilePath: &e.ImageId,
ResId: &e.ImageId,
OldPicMd5: proto.Bool(false),
PicMd5: e.Md5,
DownloadPath: &e.ImageId,
Original: proto.Int32(1),
PbReserve: []byte{0x78, 0x02},
},
})
return
}
func (e *ServiceElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
// id =35 已移至 ForwardElement
@ -156,86 +106,6 @@ func (e *LightAppElement) Pack() (r []*msg.Elem) {
return
}
func (e *FriendFlashPicElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
flash := &msg.MsgElemInfoServtype3{
FlashC2CPic: &msg.NotOnlineImage{
FilePath: &e.ImageId,
ResId: &e.ImageId,
OldPicMd5: proto.Bool(false),
PicMd5: e.Md5,
DownloadPath: &e.ImageId,
Original: proto.Int32(1),
PbReserve: []byte{0x78, 0x02},
},
}
data, _ := proto.Marshal(flash)
r = append(r, &msg.Elem{
CommonElem: &msg.CommonElem{
ServiceType: proto.Int32(3),
PbElem: data,
},
})
r = append(r, &msg.Elem{
Text: &msg.Text{
Str: proto.String("[闪照]请使用新版手机QQ查看闪照。"),
},
})
return
}
func (e *GroupFlashPicElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
flash := &msg.MsgElemInfoServtype3{
FlashTroopPic: &msg.CustomFace{
FileType: proto.Int32(66),
Useful: proto.Int32(1),
Origin: proto.Int32(1),
FileId: proto.Int32(int32(e.FileId)),
FilePath: &e.ImageId,
Size: &e.Size,
Md5: e.Md5,
Flag: make([]byte, 4),
},
}
data, _ := proto.Marshal(flash)
r = append(r, &msg.Elem{
CommonElem: &msg.CommonElem{
ServiceType: proto.Int32(3),
PbElem: data,
},
})
r = append(r, &msg.Elem{
Text: &msg.Text{
Str: proto.String("[闪照]请使用新版手机QQ查看闪照。"),
},
})
return
}
func (e *GroupShowPicElement) Pack() (r []*msg.Elem) {
r = []*msg.Elem{}
res := &msg.ResvAttr{ImageShow: &msg.AnimationImageShow{
EffectId: &e.EffectId,
AnimationParam: []byte("{}"),
}}
reserve, _ := proto.Marshal(res)
r = append(r, &msg.Elem{
CustomFace: &msg.CustomFace{
FileType: proto.Int32(0),
Useful: proto.Int32(1),
ImageType: proto.Int32(1001),
FileId: proto.Int32(int32(e.FileId)),
FilePath: &e.ImageId,
Size: &e.Size,
Md5: e.Md5,
Flag: []byte{0x11, 0x00, 0x00, 0x00},
PbReserve: reserve,
},
})
return
}
func (e *ShortVideoElement) Pack() (r []*msg.Elem) {
r = append(r, &msg.Elem{
Text: &msg.Text{