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:
parent
574c4e57b1
commit
19e2050004
@ -2,6 +2,7 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
@ -16,6 +17,7 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/client/pb/channel"
|
"github.com/Mrs4s/MiraiGo/client/pb/channel"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x388"
|
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x388"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/pttcenter"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/packets"
|
"github.com/Mrs4s/MiraiGo/internal/packets"
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
@ -42,10 +44,7 @@ func init() {
|
|||||||
|
|
||||||
func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *message.SendingMessage) (*message.GuildChannelMessage, error) {
|
func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *message.SendingMessage) (*message.GuildChannelMessage, error) {
|
||||||
mr := rand.Uint32() // 客户端似乎是生成的 u32 虽然类型是u64
|
mr := rand.Uint32() // 客户端似乎是生成的 u32 虽然类型是u64
|
||||||
at := m.FirstOrNil(func(e message.IMessageElement) bool {
|
at := m.FirstOrNil(func(e message.IMessageElement) bool { return e.Type() == message.At })
|
||||||
_, ok := e.(*message.AtElement)
|
|
||||||
return ok
|
|
||||||
})
|
|
||||||
if at != nil {
|
if at != nil {
|
||||||
at.(*message.AtElement).Guild = true
|
at.(*message.AtElement).Guild = true
|
||||||
}
|
}
|
||||||
@ -284,3 +283,72 @@ func (c *QQClient) parseGuildChannelMessage(msg *channel.ChannelMsgContent) *mes
|
|||||||
Elements: message.ParseMessageElems(msg.Body.RichText.Elems),
|
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
|
||||||
|
}
|
||||||
|
@ -134,7 +134,7 @@ func (c *QQClient) UploadGroupShortVideo(groupCode int64, video, thumb io.ReadSe
|
|||||||
ThumbMd5: thumbHash,
|
ThumbMd5: thumbHash,
|
||||||
}, nil
|
}, 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
|
var hwRsp []byte
|
||||||
multi := utils.MultiReadSeeker(thumb, video)
|
multi := utils.MultiReadSeeker(thumb, video)
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
@ -245,7 +245,7 @@ func (c *QQClient) buildPttShortVideoDownReqPacket(uuid, md5 []byte) (uint16, []
|
|||||||
return seq, packet
|
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()
|
seq := c.nextSeq()
|
||||||
return &pttcenter.ShortVideoReqBody{
|
return &pttcenter.ShortVideoReqBody{
|
||||||
Cmd: 300,
|
Cmd: 300,
|
||||||
@ -253,7 +253,7 @@ func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toU
|
|||||||
PttShortVideoUploadReq: &pttcenter.ShortVideoUploadReq{
|
PttShortVideoUploadReq: &pttcenter.ShortVideoUploadReq{
|
||||||
FromUin: c.Uin,
|
FromUin: c.Uin,
|
||||||
ToUin: toUin,
|
ToUin: toUin,
|
||||||
ChatType: 1,
|
ChatType: chattype,
|
||||||
ClientType: 2,
|
ClientType: 2,
|
||||||
Info: &pttcenter.ShortVideoFileInfo{
|
Info: &pttcenter.ShortVideoFileInfo{
|
||||||
FileName: hex.EncodeToString(videoHash) + ".mp4",
|
FileName: hex.EncodeToString(videoHash) + ".mp4",
|
||||||
@ -281,7 +281,7 @@ func (c *QQClient) buildPttGroupShortVideoProto(videoHash, thumbHash []byte, toU
|
|||||||
// PttCenterSvr.GroupShortVideoUpReq
|
// PttCenterSvr.GroupShortVideoUpReq
|
||||||
func (c *QQClient) buildPttGroupShortVideoUploadReqPacket(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64) (uint16, []byte) {
|
func (c *QQClient) buildPttGroupShortVideoUploadReqPacket(videoHash, thumbHash []byte, toUin, videoSize, thumbSize int64) (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
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)
|
packet := packets.BuildUniPacket(c.Uin, seq, "PttCenterSvr.GroupShortVideoUpReq", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||||
return seq, packet
|
return seq, packet
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,7 @@ type ShortVideoElement struct {
|
|||||||
Md5 []byte
|
Md5 []byte
|
||||||
ThumbMd5 []byte
|
ThumbMd5 []byte
|
||||||
Url string
|
Url string
|
||||||
|
Guild bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServiceElement struct {
|
type ServiceElement struct {
|
||||||
|
@ -72,12 +72,11 @@ func (e *AtElement) Pack() (r []*msg.Elem) {
|
|||||||
w.WriteUInt16(1)
|
w.WriteUInt16(1)
|
||||||
w.WriteUInt16(0)
|
w.WriteUInt16(0)
|
||||||
w.WriteUInt16(uint16(len([]rune(e.Display))))
|
w.WriteUInt16(uint16(len([]rune(e.Display))))
|
||||||
w.WriteByte(func() byte {
|
if e.Target == 0 {
|
||||||
if e.Target == 0 {
|
w.WriteByte(1)
|
||||||
return 1
|
} else {
|
||||||
}
|
w.WriteByte(0)
|
||||||
return 0
|
}
|
||||||
}())
|
|
||||||
w.WriteUInt32(uint32(e.Target))
|
w.WriteUInt32(uint32(e.Target))
|
||||||
w.WriteUInt16(0)
|
w.WriteUInt16(0)
|
||||||
}),
|
}),
|
||||||
@ -122,25 +121,34 @@ func (e *ShortVideoElement) Pack() (r []*msg.Elem) {
|
|||||||
Str: proto.String("你的QQ暂不支持查看视频短片,请期待后续版本。"),
|
Str: proto.String("你的QQ暂不支持查看视频短片,请期待后续版本。"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
r = append(r, &msg.Elem{
|
|
||||||
VideoFile: &msg.VideoFile{
|
video := &msg.VideoFile{
|
||||||
FileUuid: e.Uuid,
|
FileUuid: e.Uuid,
|
||||||
FileMd5: e.Md5,
|
FileMd5: e.Md5,
|
||||||
FileName: []byte(hex.EncodeToString(e.Md5) + ".mp4"),
|
FileName: []byte(hex.EncodeToString(e.Md5) + ".mp4"),
|
||||||
FileFormat: proto.Int32(3),
|
FileFormat: proto.Int32(3),
|
||||||
FileTime: proto.Int32(10),
|
FileTime: proto.Int32(10),
|
||||||
FileSize: proto.Int32(e.Size),
|
FileSize: proto.Int32(e.Size),
|
||||||
ThumbWidth: proto.Int32(1280),
|
ThumbWidth: proto.Int32(1280),
|
||||||
ThumbHeight: proto.Int32(720),
|
ThumbHeight: proto.Int32(720),
|
||||||
ThumbFileMd5: e.ThumbMd5,
|
ThumbFileMd5: e.ThumbMd5,
|
||||||
ThumbFileSize: proto.Int32(e.ThumbSize),
|
ThumbFileSize: proto.Int32(e.ThumbSize),
|
||||||
BusiType: proto.Int32(0),
|
BusiType: proto.Int32(0),
|
||||||
FromChatType: proto.Int32(-1),
|
FromChatType: proto.Int32(-1),
|
||||||
ToChatType: proto.Int32(-1),
|
ToChatType: proto.Int32(-1),
|
||||||
BoolSupportProgressive: proto.Bool(true),
|
BoolSupportProgressive: proto.Bool(true),
|
||||||
FileWidth: proto.Int32(1280),
|
FileWidth: proto.Int32(1280),
|
||||||
FileHeight: proto.Int32(720),
|
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
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user