mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
use uploaded image to ocr request.
This commit is contained in:
parent
741de4e6e8
commit
0a81b76d23
@ -79,10 +79,6 @@ func AppendUUID(dst []byte, uuid []byte) []byte {
|
||||
return dst
|
||||
}
|
||||
|
||||
func genUUID(uuid []byte, dst []byte) {
|
||||
|
||||
}
|
||||
|
||||
func ToIPV4Address(arr []byte) string {
|
||||
ip := (net.IP)(arr)
|
||||
return ip.String()
|
||||
|
@ -1009,28 +1009,6 @@ func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) {
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
// OidbSvc.0xe07_0
|
||||
func (c *QQClient) buildImageOcrRequestPacket(url, md5 string, size, weight, height int32) (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
body := &oidb.DE07ReqBody{
|
||||
Version: 1,
|
||||
Entrance: 3,
|
||||
OcrReqBody: &oidb.OCRReqBody{
|
||||
ImageUrl: url,
|
||||
OriginMd5: md5,
|
||||
AfterCompressMd5: md5,
|
||||
AfterCompressFileSize: size,
|
||||
AfterCompressWeight: weight,
|
||||
AfterCompressHeight: height,
|
||||
IsCut: false,
|
||||
},
|
||||
}
|
||||
b, _ := proto.Marshal(body)
|
||||
payload := c.packOIDBPackage(3591, 0, b)
|
||||
packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0xe07_0", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
// LightAppSvc.mini_app_info.GetAppInfoById
|
||||
func (c *QQClient) buildAppInfoRequestPacket(id string) (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
|
@ -148,7 +148,6 @@ var decoders = map[string]func(*QQClient, *incomingPacketInfo, []byte) (interfac
|
||||
"LongConn.OffPicUp": decodeOffPicUpResponse,
|
||||
"ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
|
||||
"ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket,
|
||||
"OidbSvc.0xe07_0": decodeImageOcrResponse,
|
||||
"OidbSvc.0xd79": decodeWordSegmentation,
|
||||
"OidbSvc.0x990": decodeTranslateResponse,
|
||||
"SummaryCard.ReqSummaryCard": decodeSummaryCardResponse,
|
||||
|
@ -767,43 +767,6 @@ func decodeWordSegmentation(_ *QQClient, _ *incomingPacketInfo, payload []byte)
|
||||
return nil, errors.New("no word received")
|
||||
}
|
||||
|
||||
// OidbSvc.0xe07_0
|
||||
func decodeImageOcrResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||
pkg := oidb.OIDBSSOPkg{}
|
||||
rsp := oidb.DE07RspBody{}
|
||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||
}
|
||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||
}
|
||||
if rsp.Wording != "" {
|
||||
return nil, errors.New(rsp.Wording)
|
||||
}
|
||||
if rsp.RetCode != 0 {
|
||||
return nil, errors.Errorf("server error, code: %v msg: %v", rsp.RetCode, rsp.ErrMsg)
|
||||
}
|
||||
var texts = make([]*TextDetection, 0, len(rsp.OcrRspBody.TextDetections))
|
||||
for _, text := range rsp.OcrRspBody.TextDetections {
|
||||
var points = make([]*Coordinate, 0, len(text.Polygon.Coordinates))
|
||||
for _, c := range text.Polygon.Coordinates {
|
||||
points = append(points, &Coordinate{
|
||||
X: c.X,
|
||||
Y: c.Y,
|
||||
})
|
||||
}
|
||||
texts = append(texts, &TextDetection{
|
||||
Text: text.DetectedText,
|
||||
Confidence: text.Confidence,
|
||||
Coordinates: points,
|
||||
})
|
||||
}
|
||||
return &OcrResponse{
|
||||
Texts: texts,
|
||||
Language: rsp.OcrRspBody.Language,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// LightAppSvc.mini_app_info.GetAppInfoById
|
||||
func decodeAppInfoResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||
pkg := qweb.QWebRsp{}
|
||||
|
@ -4,8 +4,11 @@ import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/highway"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||
"image"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@ -20,6 +23,7 @@ import (
|
||||
|
||||
func init() {
|
||||
decoders["ImgStore.GroupPicUp"] = decodeGroupImageStoreResponse
|
||||
decoders["OidbSvc.0xe07_0"] = decodeImageOcrResponse
|
||||
}
|
||||
|
||||
func (c *QQClient) UploadGroupImage(groupCode int64, img io.ReadSeeker) (*message.GroupImageElement, error) {
|
||||
@ -128,15 +132,28 @@ func (c *QQClient) uploadPrivateImage(target int64, img io.ReadSeeker, count int
|
||||
}
|
||||
|
||||
func (c *QQClient) ImageOcr(img interface{}) (*OcrResponse, error) {
|
||||
url := ""
|
||||
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))
|
||||
url = e.Url
|
||||
if b, err := utils.HttpGetBytes(e.Url, ""); err == nil {
|
||||
if url, err = c.uploadOcrImage(bytes.NewReader(b)); err != nil {
|
||||
url = e.Url
|
||||
}
|
||||
}
|
||||
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
|
||||
case *message.ImageElement:
|
||||
rsp, err := c.sendAndWait(c.buildImageOcrRequestPacket(e.Url, strings.ToUpper(hex.EncodeToString(e.Md5)), e.Size, e.Width, e.Height))
|
||||
url = e.Url
|
||||
if b, err := utils.HttpGetBytes(e.Url, ""); err == nil {
|
||||
if url, err = c.uploadOcrImage(bytes.NewReader(b)); err != nil {
|
||||
url = e.Url
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
@ -214,6 +231,46 @@ func (c *QQClient) buildGroupImageStorePacket(groupCode int64, md5 []byte, size
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
func (c *QQClient) uploadOcrImage(img io.ReadSeeker) (string, error) {
|
||||
r := make([]byte, 16)
|
||||
rand.Read(r)
|
||||
ext, _ := proto.Marshal(&highway.CommFileExtReq{
|
||||
ActionType: proto.Uint32(0),
|
||||
Uuid: binary.GenUUID(r),
|
||||
})
|
||||
rsp, err := c.highwayUploadByBDH(img, 76, c.highwaySession.SigSession, ext, false)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "upload ocr image error")
|
||||
}
|
||||
rspExt := highway.CommFileExtRsp{}
|
||||
if err = proto.Unmarshal(rsp, &rspExt); err != nil {
|
||||
return "", errors.Wrap(err, "error unmarshal highway resp")
|
||||
}
|
||||
return string(rspExt.GetDownloadUrl()), nil
|
||||
}
|
||||
|
||||
// OidbSvc.0xe07_0
|
||||
func (c *QQClient) buildImageOcrRequestPacket(url, md5 string, size, weight, height int32) (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
body := &oidb.DE07ReqBody{
|
||||
Version: 1,
|
||||
Entrance: 3,
|
||||
OcrReqBody: &oidb.OCRReqBody{
|
||||
ImageUrl: url,
|
||||
OriginMd5: md5,
|
||||
AfterCompressMd5: md5,
|
||||
AfterCompressFileSize: size,
|
||||
AfterCompressWeight: weight,
|
||||
AfterCompressHeight: height,
|
||||
IsCut: false,
|
||||
},
|
||||
}
|
||||
b, _ := proto.Marshal(body)
|
||||
payload := c.packOIDBPackage(3591, 0, b)
|
||||
packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0xe07_0", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
// ImgStore.GroupPicUp
|
||||
func decodeGroupImageStoreResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||
pkt := pb.D388RespBody{}
|
||||
@ -241,3 +298,40 @@ func decodeGroupImageStoreResponse(_ *QQClient, _ *incomingPacketInfo, payload [
|
||||
UploadPort: rsp.Uint32UpPort,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// OidbSvc.0xe07_0
|
||||
func decodeImageOcrResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||
pkg := oidb.OIDBSSOPkg{}
|
||||
rsp := oidb.DE07RspBody{}
|
||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||
}
|
||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||
}
|
||||
if rsp.Wording != "" {
|
||||
return nil, errors.New(rsp.Wording)
|
||||
}
|
||||
if rsp.RetCode != 0 {
|
||||
return nil, errors.Errorf("server error, code: %v msg: %v", rsp.RetCode, rsp.ErrMsg)
|
||||
}
|
||||
var texts = make([]*TextDetection, 0, len(rsp.OcrRspBody.TextDetections))
|
||||
for _, text := range rsp.OcrRspBody.TextDetections {
|
||||
var points = make([]*Coordinate, 0, len(text.Polygon.Coordinates))
|
||||
for _, c := range text.Polygon.Coordinates {
|
||||
points = append(points, &Coordinate{
|
||||
X: c.X,
|
||||
Y: c.Y,
|
||||
})
|
||||
}
|
||||
texts = append(texts, &TextDetection{
|
||||
Text: text.DetectedText,
|
||||
Confidence: text.Confidence,
|
||||
Coordinates: points,
|
||||
})
|
||||
}
|
||||
return &OcrResponse{
|
||||
Texts: texts,
|
||||
Language: rsp.OcrRspBody.Language,
|
||||
}, nil
|
||||
}
|
||||
|
1479
client/pb/highway/bdhExtInfo.pb.go
Normal file
1479
client/pb/highway/bdhExtInfo.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
110
client/pb/highway/bdhExtInfo.proto
Normal file
110
client/pb/highway/bdhExtInfo.proto
Normal file
@ -0,0 +1,110 @@
|
||||
syntax = "proto2";
|
||||
|
||||
option go_package = ".;highway";
|
||||
|
||||
message CommFileExtReq {
|
||||
optional uint32 actionType = 1;
|
||||
optional bytes uuid = 2;
|
||||
}
|
||||
|
||||
message CommFileExtRsp {
|
||||
optional int32 retcode = 1;
|
||||
optional bytes downloadUrl = 2;
|
||||
}
|
||||
|
||||
message PicInfo {
|
||||
optional uint32 idx = 1;
|
||||
optional uint32 size = 2;
|
||||
optional bytes binMd5 = 3;
|
||||
optional uint32 type = 4;
|
||||
}
|
||||
|
||||
message QQVoiceExtReq {
|
||||
optional bytes qid = 1;
|
||||
optional uint32 fmt = 2;
|
||||
optional uint32 rate = 3;
|
||||
optional uint32 bits = 4;
|
||||
optional uint32 channel = 5;
|
||||
optional uint32 pinyin = 6;
|
||||
}
|
||||
|
||||
message QQVoiceExtRsp {
|
||||
optional bytes qid = 1;
|
||||
optional int32 retcode = 2;
|
||||
repeated QQVoiceResult result = 3;
|
||||
}
|
||||
|
||||
message QQVoiceResult {
|
||||
optional bytes text = 1;
|
||||
optional bytes pinyin = 2;
|
||||
optional uint32 source = 3;
|
||||
}
|
||||
|
||||
message ShortVideoReqExtInfo {
|
||||
optional uint32 cmd = 1;
|
||||
optional uint64 sessionId = 2;
|
||||
optional PicInfo thumbinfo = 3;
|
||||
optional VideoInfo videoinfo = 4;
|
||||
optional ShortVideoSureReqInfo shortvideoSureReq = 5;
|
||||
optional bool isMergeCmdBeforeData = 6;
|
||||
}
|
||||
|
||||
message ShortVideoRspExtInfo {
|
||||
optional uint32 cmd = 1;
|
||||
optional uint64 sessionId = 2;
|
||||
optional int32 retcode = 3;
|
||||
optional bytes errinfo = 4;
|
||||
optional PicInfo thumbinfo = 5;
|
||||
optional VideoInfo videoinfo = 6;
|
||||
optional ShortVideoSureRspInfo shortvideoSureRsp = 7;
|
||||
optional uint32 retryFlag = 8;
|
||||
}
|
||||
|
||||
message ShortVideoSureReqInfo {
|
||||
optional uint64 fromuin = 1;
|
||||
optional uint32 chatType = 2;
|
||||
optional uint64 touin = 3;
|
||||
optional uint64 groupCode = 4;
|
||||
optional uint32 clientType = 5;
|
||||
optional PicInfo thumbinfo = 6;
|
||||
repeated VideoInfo mergeVideoinfo = 7;
|
||||
repeated VideoInfo dropVideoinfo = 8;
|
||||
optional uint32 businessType = 9;
|
||||
optional uint32 subBusinessType = 10;
|
||||
}
|
||||
|
||||
message ShortVideoSureRspInfo {
|
||||
optional bytes fileid = 1;
|
||||
optional bytes ukey = 2;
|
||||
optional VideoInfo videoinfo = 3;
|
||||
optional uint32 mergeCost = 4;
|
||||
}
|
||||
|
||||
message StoryVideoExtReq {
|
||||
}
|
||||
|
||||
message StoryVideoExtRsp {
|
||||
optional int32 retcode = 1;
|
||||
optional bytes msg = 2;
|
||||
optional bytes cdnUrl = 3;
|
||||
optional bytes fileKey = 4;
|
||||
optional bytes fileId = 5;
|
||||
}
|
||||
|
||||
message UploadPicExtInfo {
|
||||
optional bytes fileResid = 1;
|
||||
optional bytes downloadUrl = 2;
|
||||
optional bytes thumbDownloadUrl = 3;
|
||||
}
|
||||
|
||||
message VideoInfo {
|
||||
optional uint32 idx = 1;
|
||||
optional uint32 size = 2;
|
||||
optional bytes binMd5 = 3;
|
||||
optional uint32 format = 4;
|
||||
optional uint32 resLen = 5;
|
||||
optional uint32 resWidth = 6;
|
||||
optional uint32 time = 7;
|
||||
optional uint64 starttime = 8;
|
||||
optional uint32 isAudio = 9;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user