1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

feat: upload guild short video

This commit is contained in:
wdvxdr 2021-11-18 21:28:17 +08:00
parent 574c4e57b1
commit 19e2050004
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
4 changed files with 111 additions and 34 deletions

View File

@ -2,6 +2,7 @@ package client
import (
"bytes"
"crypto/md5"
"encoding/hex"
"fmt"
"image"
@ -16,6 +17,7 @@ import (
"github.com/Mrs4s/MiraiGo/client/pb/channel"
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x388"
"github.com/Mrs4s/MiraiGo/client/pb/msg"
"github.com/Mrs4s/MiraiGo/client/pb/pttcenter"
"github.com/Mrs4s/MiraiGo/internal/packets"
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/MiraiGo/utils"
@ -42,10 +44,7 @@ func init() {
func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *message.SendingMessage) (*message.GuildChannelMessage, error) {
mr := rand.Uint32() // 客户端似乎是生成的 u32 虽然类型是u64
at := m.FirstOrNil(func(e message.IMessageElement) bool {
_, ok := e.(*message.AtElement)
return ok
})
at := m.FirstOrNil(func(e message.IMessageElement) bool { return e.Type() == message.At })
if at != nil {
at.(*message.AtElement).Guild = true
}
@ -284,3 +283,72 @@ func (c *QQClient) parseGuildChannelMessage(msg *channel.ChannelMsgContent) *mes
Elements: message.ParseMessageElems(msg.Body.RichText.Elems),
}
}
// PttCenterSvr.GroupShortVideoUpReq
func (c *QQClient) buildPttGuildVideoUpReq(videoHash, thumbHash []byte, guildId, channelId int64, videoSize, thumbSize int64) (uint16, []byte) {
seq := c.nextSeq()
pb := c.buildPttGroupShortVideoProto(videoHash, thumbHash, guildId, videoSize, thumbSize, 4)
pb.PttShortVideoUploadReq.BusinessType = 4601
pb.PttShortVideoUploadReq.ToUin = channelId
pb.ExtensionReq[0].SubBusiType = 4601
payload, _ := proto.Marshal(pb)
packet := packets.BuildUniPacket(c.Uin, seq, "PttCenterSvr.GroupShortVideoUpReq", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}
func (c *QQClient) UploadGuildShortVideo(guildId, channelId uint64, video, thumb io.ReadSeeker) (*message.ShortVideoElement, error) {
// todo: combine with group short video upload
videoHash, videoLen := utils.ComputeMd5AndLength(video)
thumbHash, thumbLen := utils.ComputeMd5AndLength(thumb)
key := string(videoHash) + string(thumbHash)
pttWaiter.Wait(key)
defer pttWaiter.Done(key)
i, err := c.sendAndWait(c.buildPttGuildVideoUpReq(videoHash, thumbHash, int64(guildId), int64(channelId), videoLen, thumbLen))
if err != nil {
return nil, errors.Wrap(err, "upload req error")
}
rsp := i.(*pttcenter.ShortVideoUploadRsp)
if rsp.FileExists == 1 {
return &message.ShortVideoElement{
Uuid: []byte(rsp.FileId),
Size: int32(videoLen),
ThumbSize: int32(thumbLen),
Md5: videoHash,
ThumbMd5: thumbHash,
Guild: true,
}, nil
}
req := c.buildPttGroupShortVideoProto(videoHash, thumbHash, int64(guildId), videoLen, thumbLen, 4).PttShortVideoUploadReq
req.BusinessType = 4601
req.ToUin = int64(channelId)
ext, _ := proto.Marshal(req)
var hwRsp []byte
multi := utils.MultiReadSeeker(thumb, video)
h := md5.New()
length, _ := io.Copy(h, multi)
fh := h.Sum(nil)
_, _ = multi.Seek(0, io.SeekStart)
hwRsp, err = c.highwayUploadByBDH(multi, length, 89, c.bigDataSession.SigSession, fh, ext, true)
if err != nil {
return nil, errors.Wrap(err, "upload video file error")
}
if len(hwRsp) == 0 {
return nil, errors.New("resp is empty")
}
rsp = &pttcenter.ShortVideoUploadRsp{}
if err = proto.Unmarshal(hwRsp, rsp); err != nil {
return nil, errors.Wrap(err, "decode error")
}
return &message.ShortVideoElement{
Uuid: []byte(rsp.FileId),
Size: int32(videoLen),
ThumbSize: int32(thumbLen),
Md5: videoHash,
ThumbMd5: thumbHash,
Guild: true,
}, nil
}

View File

@ -134,7 +134,7 @@ func (c *QQClient) UploadGroupShortVideo(groupCode int64, video, thumb io.ReadSe
ThumbMd5: thumbHash,
}, nil
}
ext, _ := proto.Marshal(c.buildPttGroupShortVideoProto(videoHash, thumbHash, groupCode, videoLen, thumbLen).PttShortVideoUploadReq)
ext, _ := proto.Marshal(c.buildPttGroupShortVideoProto(videoHash, thumbHash, groupCode, videoLen, thumbLen, 1).PttShortVideoUploadReq)
var hwRsp []byte
multi := utils.MultiReadSeeker(thumb, video)
h := md5.New()
@ -245,7 +245,7 @@ func (c *QQClient) buildPttShortVideoDownReqPacket(uuid, md5 []byte) (uint16, []
return seq, packet
}
func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64) *pttcenter.ShortVideoReqBody {
func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64, chattype int32) *pttcenter.ShortVideoReqBody {
seq := c.nextSeq()
return &pttcenter.ShortVideoReqBody{
Cmd: 300,
@ -253,7 +253,7 @@ func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toU
PttShortVideoUploadReq: &pttcenter.ShortVideoUploadReq{
FromUin: c.Uin,
ToUin: toUin,
ChatType: 1,
ChatType: chattype,
ClientType: 2,
Info: &pttcenter.ShortVideoFileInfo{
FileName: hex.EncodeToString(videoHash) + ".mp4",
@ -281,7 +281,7 @@ func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toU
// PttCenterSvr.GroupShortVideoUpReq
func (c *QQClient) buildPttGroupShortVideoUploadReqPacket(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64) (uint16, []byte) {
seq := c.nextSeq()
payload, _ := proto.Marshal(c.buildPttGroupShortVideoProto(videoHash, thumbHash, toUin, videoSize, thumbSize))
payload, _ := proto.Marshal(c.buildPttGroupShortVideoProto(videoHash, thumbHash, toUin, videoSize, thumbSize, 1))
packet := packets.BuildUniPacket(c.Uin, seq, "PttCenterSvr.GroupShortVideoUpReq", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}

View File

@ -69,6 +69,7 @@ type ShortVideoElement struct {
Md5 []byte
ThumbMd5 []byte
Url string
Guild bool
}
type ServiceElement struct {

View File

@ -72,12 +72,11 @@ func (e *AtElement) Pack() (r []*msg.Elem) {
w.WriteUInt16(1)
w.WriteUInt16(0)
w.WriteUInt16(uint16(len([]rune(e.Display))))
w.WriteByte(func() byte {
if e.Target == 0 {
return 1
}
return 0
}())
if e.Target == 0 {
w.WriteByte(1)
} else {
w.WriteByte(0)
}
w.WriteUInt32(uint32(e.Target))
w.WriteUInt16(0)
}),
@ -122,25 +121,34 @@ func (e *ShortVideoElement) Pack() (r []*msg.Elem) {
Str: proto.String("你的QQ暂不支持查看视频短片请期待后续版本。"),
},
})
r = append(r, &msg.Elem{
VideoFile: &msg.VideoFile{
FileUuid: e.Uuid,
FileMd5: e.Md5,
FileName: []byte(hex.EncodeToString(e.Md5) + ".mp4"),
FileFormat: proto.Int32(3),
FileTime: proto.Int32(10),
FileSize: proto.Int32(e.Size),
ThumbWidth: proto.Int32(1280),
ThumbHeight: proto.Int32(720),
ThumbFileMd5: e.ThumbMd5,
ThumbFileSize: proto.Int32(e.ThumbSize),
BusiType: proto.Int32(0),
FromChatType: proto.Int32(-1),
ToChatType: proto.Int32(-1),
BoolSupportProgressive: proto.Bool(true),
FileWidth: proto.Int32(1280),
FileHeight: proto.Int32(720),
},
})
video := &msg.VideoFile{
FileUuid: e.Uuid,
FileMd5: e.Md5,
FileName: []byte(hex.EncodeToString(e.Md5) + ".mp4"),
FileFormat: proto.Int32(3),
FileTime: proto.Int32(10),
FileSize: proto.Int32(e.Size),
ThumbWidth: proto.Int32(1280),
ThumbHeight: proto.Int32(720),
ThumbFileMd5: e.ThumbMd5,
ThumbFileSize: proto.Int32(e.ThumbSize),
BusiType: proto.Int32(0),
FromChatType: proto.Int32(-1),
ToChatType: proto.Int32(-1),
BoolSupportProgressive: proto.Bool(true),
FileWidth: proto.Int32(1280),
FileHeight: proto.Int32(720),
}
if e.Guild {
video.BusiType = proto.Int32(4601)
video.SubBusiType = proto.Int32(4601)
video.FileWidth = proto.Int32(0)
video.FileHeight = proto.Int32(0)
video.VideoAttr = proto.Int32(0)
}
r = append(r, &msg.Elem{VideoFile: video})
return
}