mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
move func.
This commit is contained in:
parent
507d218433
commit
36ed2b3902
@ -22,7 +22,6 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/protocol/crypto"
|
"github.com/Mrs4s/MiraiGo/protocol/crypto"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/tlv"
|
"github.com/Mrs4s/MiraiGo/protocol/tlv"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -667,37 +666,6 @@ func (c *QQClient) buildOffPicUpPacket(target int64, md5 []byte, size int32) (ui
|
|||||||
return seq, packet
|
return seq, packet
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImgStore.GroupPicUp
|
|
||||||
func (c *QQClient) buildGroupImageStorePacket(groupCode int64, md5 []byte, size int32) (uint16, []byte) {
|
|
||||||
seq := c.nextSeq()
|
|
||||||
name := utils.RandomString(16) + ".gif"
|
|
||||||
req := &pb.D388ReqBody{
|
|
||||||
NetType: 3,
|
|
||||||
Subcmd: 1,
|
|
||||||
MsgTryUpImgReq: []*pb.TryUpImgReq{
|
|
||||||
{
|
|
||||||
GroupCode: groupCode,
|
|
||||||
SrcUin: c.Uin,
|
|
||||||
FileMd5: md5,
|
|
||||||
FileSize: int64(size),
|
|
||||||
FileName: name,
|
|
||||||
SrcTerm: 5,
|
|
||||||
PlatformType: 9,
|
|
||||||
BuType: 1,
|
|
||||||
PicType: 1000,
|
|
||||||
BuildVer: "8.2.7.4410",
|
|
||||||
AppPicType: 1006,
|
|
||||||
FileIndex: EmptyBytes,
|
|
||||||
TransferUrl: EmptyBytes,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Extension: EmptyBytes,
|
|
||||||
}
|
|
||||||
payload, _ := proto.Marshal(req)
|
|
||||||
packet := packets.BuildUniPacket(c.Uin, seq, "ImgStore.GroupPicUp", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
|
||||||
return seq, packet
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProfileService.Pb.ReqSystemMsgNew.Friend
|
// ProfileService.Pb.ReqSystemMsgNew.Friend
|
||||||
func (c *QQClient) buildSystemMsgNewFriendPacket() (uint16, []byte) {
|
func (c *QQClient) buildSystemMsgNewFriendPacket() (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
|
165
client/client.go
165
client/client.go
@ -3,16 +3,13 @@ package client
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
"image"
|
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -134,7 +131,6 @@ var decoders = map[string]func(*QQClient, uint16, []byte) (interface{}, error){
|
|||||||
"friendlist.GetTroopListReqV2": decodeGroupListResponse,
|
"friendlist.GetTroopListReqV2": decodeGroupListResponse,
|
||||||
"friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse,
|
"friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse,
|
||||||
"group_member_card.get_group_member_card_info": decodeGroupMemberInfoResponse,
|
"group_member_card.get_group_member_card_info": decodeGroupMemberInfoResponse,
|
||||||
"ImgStore.GroupPicUp": decodeGroupImageStoreResponse,
|
|
||||||
"PttStore.GroupPttUp": decodeGroupPttStoreResponse,
|
"PttStore.GroupPttUp": decodeGroupPttStoreResponse,
|
||||||
"LongConn.OffPicUp": decodeOffPicUpResponse,
|
"LongConn.OffPicUp": decodeOffPicUpResponse,
|
||||||
"ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
|
"ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
|
||||||
@ -575,167 +571,6 @@ func (c *QQClient) SendFriendPoke(target int64) {
|
|||||||
_, _ = c.sendAndWait(c.buildFriendPokePacket(target))
|
_, _ = c.sendAndWait(c.buildFriendPokePacket(target))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) UploadGroupImage(groupCode int64, img io.ReadSeeker) (*message.GroupImageElement, error) {
|
|
||||||
h := md5.New()
|
|
||||||
length, _ := io.Copy(h, img)
|
|
||||||
fh := h.Sum(nil)
|
|
||||||
seq, pkt := c.buildGroupImageStorePacket(groupCode, fh[:], int32(length))
|
|
||||||
r, err := c.sendAndWait(seq, pkt)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rsp := r.(imageUploadResponse)
|
|
||||||
if rsp.ResultCode != 0 {
|
|
||||||
return nil, errors.New(rsp.Message)
|
|
||||||
}
|
|
||||||
if rsp.IsExists {
|
|
||||||
goto ok
|
|
||||||
}
|
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
|
||||||
if len(c.srvSsoAddrs) == 0 {
|
|
||||||
for i, addr := range rsp.UploadIp {
|
|
||||||
c.srvSsoAddrs = append(c.srvSsoAddrs, fmt.Sprintf("%v:%v", binary.UInt32ToIPV4Address(uint32(addr)), rsp.UploadPort[i]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, err = c.highwayUploadByBDH(img, 2, rsp.UploadKey, EmptyBytes); err == nil {
|
|
||||||
goto ok
|
|
||||||
}
|
|
||||||
return nil, errors.New("upload failed")
|
|
||||||
ok:
|
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
|
||||||
i, _, _ := image.DecodeConfig(img)
|
|
||||||
var imageType int32 = 1000
|
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
|
||||||
tmp := make([]byte, 4)
|
|
||||||
_, _ = img.Read(tmp)
|
|
||||||
if bytes.Equal(tmp, []byte{0x47, 0x49, 0x46, 0x38}) {
|
|
||||||
imageType = 2000
|
|
||||||
}
|
|
||||||
return message.NewGroupImage(binary.CalculateImageResourceId(fh[:]), fh[:], rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *QQClient) UploadGroupImageByFile(groupCode int64, path string) (*message.GroupImageElement, error) {
|
|
||||||
img, err := os.OpenFile(path, os.O_RDONLY, 0666)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
h := md5.New()
|
|
||||||
length, _ := io.Copy(h, img)
|
|
||||||
fh := h.Sum(nil)
|
|
||||||
seq, pkt := c.buildGroupImageStorePacket(groupCode, fh[:], int32(length))
|
|
||||||
r, err := c.sendAndWait(seq, pkt)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rsp := r.(imageUploadResponse)
|
|
||||||
if rsp.ResultCode != 0 {
|
|
||||||
return nil, errors.New(rsp.Message)
|
|
||||||
}
|
|
||||||
if rsp.IsExists {
|
|
||||||
goto ok
|
|
||||||
}
|
|
||||||
if len(c.srvSsoAddrs) == 0 {
|
|
||||||
for i, addr := range rsp.UploadIp {
|
|
||||||
c.srvSsoAddrs = append(c.srvSsoAddrs, fmt.Sprintf("%v:%v", binary.UInt32ToIPV4Address(uint32(addr)), rsp.UploadPort[i]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, err = c.highwayUploadFileMultiThreadingByBDH(path, 2, 4, rsp.UploadKey, EmptyBytes); err == nil {
|
|
||||||
goto ok
|
|
||||||
}
|
|
||||||
return nil, errors.New("upload failed")
|
|
||||||
ok:
|
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
|
||||||
i, _, _ := image.DecodeConfig(img)
|
|
||||||
var imageType int32 = 1000
|
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
|
||||||
tmp := make([]byte, 4)
|
|
||||||
_, _ = img.Read(tmp)
|
|
||||||
if bytes.Equal(tmp, []byte{0x47, 0x49, 0x46, 0x38}) {
|
|
||||||
imageType = 2000
|
|
||||||
}
|
|
||||||
return message.NewGroupImage(binary.CalculateImageResourceId(fh[:]), fh[:], rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *QQClient) UploadPrivateImage(target int64, img io.ReadSeeker) (*message.FriendImageElement, error) {
|
|
||||||
return c.uploadPrivateImage(target, img, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *QQClient) uploadPrivateImage(target int64, img io.ReadSeeker, count int) (*message.FriendImageElement, error) {
|
|
||||||
count++
|
|
||||||
h := md5.New()
|
|
||||||
length, _ := io.Copy(h, img)
|
|
||||||
fh := h.Sum(nil)
|
|
||||||
e, err := c.QueryFriendImage(target, fh[:], int32(length))
|
|
||||||
if errors.Is(err, ErrNotExists) {
|
|
||||||
// use group highway upload and query again for image id.
|
|
||||||
if _, err = c.UploadGroupImage(target, img); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if count >= 5 {
|
|
||||||
return e, nil
|
|
||||||
}
|
|
||||||
return c.uploadPrivateImage(target, img, count)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return e, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *QQClient) ImageOcr(img interface{}) (*OcrResponse, error) {
|
|
||||||
switch e := img.(type) {
|
|
||||||
case *message.GroupImageElement:
|
|
||||||
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(e.Url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return rsp.(*OcrResponse), nil
|
|
||||||
case *message.ImageElement:
|
|
||||||
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(e.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")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*message.GroupImageElement, error) {
|
|
||||||
r, err := c.sendAndWait(c.buildGroupImageStorePacket(groupCode, hash, size))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
rsp := r.(imageUploadResponse)
|
|
||||||
if rsp.ResultCode != 0 {
|
|
||||||
return nil, errors.New(rsp.Message)
|
|
||||||
}
|
|
||||||
if rsp.IsExists {
|
|
||||||
return message.NewGroupImage(binary.CalculateImageResourceId(hash), hash, rsp.FileId, size, rsp.Width, rsp.Height, 1000), nil
|
|
||||||
}
|
|
||||||
return nil, errors.New("image does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
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 &message.FriendImageElement{
|
|
||||||
ImageId: rsp.ResourceId,
|
|
||||||
Md5: hash,
|
|
||||||
}, errors.WithStack(ErrNotExists)
|
|
||||||
}
|
|
||||||
return &message.FriendImageElement{
|
|
||||||
ImageId: rsp.ResourceId,
|
|
||||||
Md5: hash,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *QQClient) ReloadGroupList() error {
|
func (c *QQClient) ReloadGroupList() error {
|
||||||
c.groupListLock.Lock()
|
c.groupListLock.Lock()
|
||||||
defer c.groupListLock.Unlock()
|
defer c.groupListLock.Unlock()
|
||||||
|
@ -580,34 +580,6 @@ func decodeGroupMemberInfoResponse(c *QQClient, _ uint16, payload []byte) (inter
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImgStore.GroupPicUp
|
|
||||||
func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
|
||||||
pkt := pb.D388RespBody{}
|
|
||||||
err := proto.Unmarshal(payload, &pkt)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
||||||
}
|
|
||||||
rsp := pkt.MsgTryUpImgRsp[0]
|
|
||||||
if rsp.Result != 0 {
|
|
||||||
return imageUploadResponse{
|
|
||||||
ResultCode: rsp.Result,
|
|
||||||
Message: rsp.FailMsg,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
if rsp.BoolFileExit {
|
|
||||||
if rsp.MsgImgInfo != 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
|
|
||||||
}
|
|
||||||
return imageUploadResponse{
|
|
||||||
FileId: rsp.Fid,
|
|
||||||
UploadKey: rsp.UpUkey,
|
|
||||||
UploadIp: rsp.Uint32UpIp,
|
|
||||||
UploadPort: rsp.Uint32UpPort,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LongConn.OffPicUp
|
// LongConn.OffPicUp
|
||||||
func decodeOffPicUpResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeOffPicUpResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
rsp := cmd0x352.RspBody{}
|
rsp := cmd0x352.RspBody{}
|
||||||
|
243
client/image.go
Normal file
243
client/image.go
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb"
|
||||||
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"image"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
decoders["ImgStore.GroupPicUp"] = decodeGroupImageStoreResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) UploadGroupImage(groupCode int64, img io.ReadSeeker) (*message.GroupImageElement, error) {
|
||||||
|
h := md5.New()
|
||||||
|
length, _ := io.Copy(h, img)
|
||||||
|
fh := h.Sum(nil)
|
||||||
|
seq, pkt := c.buildGroupImageStorePacket(groupCode, fh[:], int32(length))
|
||||||
|
r, err := c.sendAndWait(seq, pkt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rsp := r.(imageUploadResponse)
|
||||||
|
if rsp.ResultCode != 0 {
|
||||||
|
return nil, errors.New(rsp.Message)
|
||||||
|
}
|
||||||
|
if rsp.IsExists {
|
||||||
|
goto ok
|
||||||
|
}
|
||||||
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
|
if len(c.srvSsoAddrs) == 0 {
|
||||||
|
for i, addr := range rsp.UploadIp {
|
||||||
|
c.srvSsoAddrs = append(c.srvSsoAddrs, fmt.Sprintf("%v:%v", binary.UInt32ToIPV4Address(uint32(addr)), rsp.UploadPort[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = c.highwayUploadByBDH(img, 2, rsp.UploadKey, EmptyBytes); err == nil {
|
||||||
|
goto ok
|
||||||
|
}
|
||||||
|
return nil, errors.New("upload failed")
|
||||||
|
ok:
|
||||||
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
|
i, _, _ := image.DecodeConfig(img)
|
||||||
|
var imageType int32 = 1000
|
||||||
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
|
tmp := make([]byte, 4)
|
||||||
|
_, _ = img.Read(tmp)
|
||||||
|
if bytes.Equal(tmp, []byte{0x47, 0x49, 0x46, 0x38}) {
|
||||||
|
imageType = 2000
|
||||||
|
}
|
||||||
|
return message.NewGroupImage(binary.CalculateImageResourceId(fh[:]), fh[:], rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) UploadGroupImageByFile(groupCode int64, path string) (*message.GroupImageElement, error) {
|
||||||
|
img, err := os.OpenFile(path, os.O_RDONLY, 0666)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
h := md5.New()
|
||||||
|
length, _ := io.Copy(h, img)
|
||||||
|
fh := h.Sum(nil)
|
||||||
|
seq, pkt := c.buildGroupImageStorePacket(groupCode, fh[:], int32(length))
|
||||||
|
r, err := c.sendAndWait(seq, pkt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rsp := r.(imageUploadResponse)
|
||||||
|
if rsp.ResultCode != 0 {
|
||||||
|
return nil, errors.New(rsp.Message)
|
||||||
|
}
|
||||||
|
if rsp.IsExists {
|
||||||
|
goto ok
|
||||||
|
}
|
||||||
|
if len(c.srvSsoAddrs) == 0 {
|
||||||
|
for i, addr := range rsp.UploadIp {
|
||||||
|
c.srvSsoAddrs = append(c.srvSsoAddrs, fmt.Sprintf("%v:%v", binary.UInt32ToIPV4Address(uint32(addr)), rsp.UploadPort[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = c.highwayUploadFileMultiThreadingByBDH(path, 2, 4, rsp.UploadKey, EmptyBytes); err == nil {
|
||||||
|
goto ok
|
||||||
|
}
|
||||||
|
return nil, errors.New("upload failed")
|
||||||
|
ok:
|
||||||
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
|
i, _, _ := image.DecodeConfig(img)
|
||||||
|
var imageType int32 = 1000
|
||||||
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
|
tmp := make([]byte, 4)
|
||||||
|
_, _ = img.Read(tmp)
|
||||||
|
if bytes.Equal(tmp, []byte{0x47, 0x49, 0x46, 0x38}) {
|
||||||
|
imageType = 2000
|
||||||
|
}
|
||||||
|
return message.NewGroupImage(binary.CalculateImageResourceId(fh[:]), fh[:], rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) UploadPrivateImage(target int64, img io.ReadSeeker) (*message.FriendImageElement, error) {
|
||||||
|
return c.uploadPrivateImage(target, img, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) uploadPrivateImage(target int64, img io.ReadSeeker, count int) (*message.FriendImageElement, error) {
|
||||||
|
count++
|
||||||
|
h := md5.New()
|
||||||
|
length, _ := io.Copy(h, img)
|
||||||
|
fh := h.Sum(nil)
|
||||||
|
e, err := c.QueryFriendImage(target, fh[:], int32(length))
|
||||||
|
if errors.Is(err, ErrNotExists) {
|
||||||
|
// use group highway upload and query again for image id.
|
||||||
|
if _, err = c.UploadGroupImage(target, img); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if count >= 5 {
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
return c.uploadPrivateImage(target, img, count)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) ImageOcr(img interface{}) (*OcrResponse, error) {
|
||||||
|
switch e := img.(type) {
|
||||||
|
case *message.GroupImageElement:
|
||||||
|
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(e.Url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rsp.(*OcrResponse), nil
|
||||||
|
case *message.ImageElement:
|
||||||
|
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(e.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")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*message.GroupImageElement, error) {
|
||||||
|
r, err := c.sendAndWait(c.buildGroupImageStorePacket(groupCode, hash, size))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rsp := r.(imageUploadResponse)
|
||||||
|
if rsp.ResultCode != 0 {
|
||||||
|
return nil, errors.New(rsp.Message)
|
||||||
|
}
|
||||||
|
if rsp.IsExists {
|
||||||
|
return message.NewGroupImage(binary.CalculateImageResourceId(hash), hash, rsp.FileId, size, rsp.Width, rsp.Height, 1000), nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("image does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
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 &message.FriendImageElement{
|
||||||
|
ImageId: rsp.ResourceId,
|
||||||
|
Md5: hash,
|
||||||
|
}, errors.WithStack(ErrNotExists)
|
||||||
|
}
|
||||||
|
return &message.FriendImageElement{
|
||||||
|
ImageId: rsp.ResourceId,
|
||||||
|
Md5: hash,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImgStore.GroupPicUp
|
||||||
|
func (c *QQClient) buildGroupImageStorePacket(groupCode int64, md5 []byte, size int32) (uint16, []byte) {
|
||||||
|
seq := c.nextSeq()
|
||||||
|
name := utils.RandomString(16) + ".gif"
|
||||||
|
req := &pb.D388ReqBody{
|
||||||
|
NetType: 3,
|
||||||
|
Subcmd: 1,
|
||||||
|
MsgTryUpImgReq: []*pb.TryUpImgReq{
|
||||||
|
{
|
||||||
|
GroupCode: groupCode,
|
||||||
|
SrcUin: c.Uin,
|
||||||
|
FileMd5: md5,
|
||||||
|
FileSize: int64(size),
|
||||||
|
FileName: name,
|
||||||
|
SrcTerm: 5,
|
||||||
|
PlatformType: 9,
|
||||||
|
BuType: 1,
|
||||||
|
PicType: 1000,
|
||||||
|
BuildVer: "8.2.7.4410",
|
||||||
|
AppPicType: 1006,
|
||||||
|
FileIndex: EmptyBytes,
|
||||||
|
TransferUrl: EmptyBytes,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Extension: EmptyBytes,
|
||||||
|
}
|
||||||
|
payload, _ := proto.Marshal(req)
|
||||||
|
packet := packets.BuildUniPacket(c.Uin, seq, "ImgStore.GroupPicUp", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||||
|
return seq, packet
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImgStore.GroupPicUp
|
||||||
|
func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
|
pkt := pb.D388RespBody{}
|
||||||
|
err := proto.Unmarshal(payload, &pkt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
|
}
|
||||||
|
rsp := pkt.MsgTryUpImgRsp[0]
|
||||||
|
if rsp.Result != 0 {
|
||||||
|
return imageUploadResponse{
|
||||||
|
ResultCode: rsp.Result,
|
||||||
|
Message: rsp.FailMsg,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if rsp.BoolFileExit {
|
||||||
|
if rsp.MsgImgInfo != 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
|
||||||
|
}
|
||||||
|
return imageUploadResponse{
|
||||||
|
FileId: rsp.Fid,
|
||||||
|
UploadKey: rsp.UpUkey,
|
||||||
|
UploadIp: rsp.Uint32UpIp,
|
||||||
|
UploadPort: rsp.Uint32UpPort,
|
||||||
|
}, nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user