mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
feat: UploadGuildImage
This commit is contained in:
parent
e3411adb3d
commit
b644f5c158
@ -265,19 +265,6 @@ type (
|
|||||||
list []*GroupMemberInfo
|
list []*GroupMemberInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
imageUploadResponse struct {
|
|
||||||
UploadKey []byte
|
|
||||||
UploadIp []uint32
|
|
||||||
UploadPort []uint32
|
|
||||||
ResourceId string
|
|
||||||
Message string
|
|
||||||
FileId int64
|
|
||||||
Width int32
|
|
||||||
Height int32
|
|
||||||
ResultCode int32
|
|
||||||
IsExists bool
|
|
||||||
}
|
|
||||||
|
|
||||||
pttUploadResponse struct {
|
pttUploadResponse struct {
|
||||||
ResultCode int32
|
ResultCode int32
|
||||||
Message string
|
Message string
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/channel"
|
"github.com/Mrs4s/MiraiGo/client/pb/channel"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/packets"
|
"github.com/Mrs4s/MiraiGo/internal/packets"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -19,6 +18,13 @@ var (
|
|||||||
updateChanLock sync.Mutex
|
updateChanLock sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type tipsPushInfo struct {
|
||||||
|
TinyId uint64
|
||||||
|
TargetMessageSenderUin int64
|
||||||
|
GuildId uint64
|
||||||
|
ChannelId uint64
|
||||||
|
}
|
||||||
|
|
||||||
func decodeGuildEventFlowPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
func decodeGuildEventFlowPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||||
push := new(channel.MsgOnlinePush)
|
push := new(channel.MsgOnlinePush)
|
||||||
if err := proto.Unmarshal(payload, push); err != nil {
|
if err := proto.Unmarshal(payload, push); err != nil {
|
||||||
@ -26,12 +32,6 @@ func decodeGuildEventFlowPacket(c *QQClient, _ *incomingPacketInfo, payload []by
|
|||||||
}
|
}
|
||||||
for _, m := range push.Msgs {
|
for _, m := range push.Msgs {
|
||||||
if m.Head.ContentHead.GetType() == 3841 {
|
if m.Head.ContentHead.GetType() == 3841 {
|
||||||
type tipsPushInfo struct {
|
|
||||||
TinyId uint64
|
|
||||||
TargetMessageSenderUin int64
|
|
||||||
GuildId uint64
|
|
||||||
ChannelId uint64
|
|
||||||
}
|
|
||||||
// todo: 回头 event flow 的处理移出去重构下逻辑, 先暂时这样方便改
|
// todo: 回头 event flow 的处理移出去重构下逻辑, 先暂时这样方便改
|
||||||
var common *msg.CommonElem
|
var common *msg.CommonElem
|
||||||
if m.Body != nil {
|
if m.Body != nil {
|
||||||
@ -64,68 +64,7 @@ func decodeGuildEventFlowPacket(c *QQClient, _ *incomingPacketInfo, payload []by
|
|||||||
c.Error("failed to unmarshal guild channel event body: %v", err)
|
c.Error("failed to unmarshal guild channel event body: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if eventBody.ChangeChanInfo != nil {
|
c.processGuildEventBody(m, eventBody)
|
||||||
updateChanLock.Lock()
|
|
||||||
defer updateChanLock.Unlock()
|
|
||||||
guild := c.GuildService.FindGuild(m.Head.RoutingHead.GetGuildId())
|
|
||||||
oldInfo := guild.FindChannel(eventBody.ChangeChanInfo.GetChanId())
|
|
||||||
if time.Now().Unix()-oldInfo.fetchTime <= 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
newInfo, err := c.GuildService.FetchChannelInfo(m.Head.RoutingHead.GetGuildId(), eventBody.ChangeChanInfo.GetChanId())
|
|
||||||
if err != nil {
|
|
||||||
c.Error("error to decode channel info updated event: fetch channel info failed: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for i := range guild.Channels {
|
|
||||||
if guild.Channels[i].ChannelId == newInfo.ChannelId {
|
|
||||||
guild.Channels[i] = newInfo
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.dispatchGuildChannelUpdatedEvent(&GuildChannelUpdatedEvent{
|
|
||||||
OperatorId: m.Head.RoutingHead.GetFromTinyid(),
|
|
||||||
GuildId: m.Head.RoutingHead.GetGuildId(),
|
|
||||||
ChannelId: eventBody.ChangeChanInfo.GetChanId(),
|
|
||||||
OldChannelInfo: oldInfo,
|
|
||||||
NewChannelInfo: newInfo,
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if eventBody.UpdateMsg != nil {
|
|
||||||
if eventBody.UpdateMsg.GetEventType() == 1 || eventBody.UpdateMsg.GetEventType() == 2 { // todo: 撤回消息
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if eventBody.UpdateMsg.GetEventType() == 4 { // 消息贴表情更新 (包含添加或删除)
|
|
||||||
t, err := c.GuildService.pullRoamMsgByEventFlow(m.Head.RoutingHead.GetGuildId(), m.Head.RoutingHead.GetChannelId(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetEventVersion()-1)
|
|
||||||
if err != nil || len(t) == 0 {
|
|
||||||
c.Error("process guild event flow error: pull eventMsg message error: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 自己的消息被贴表情会单独推送一个tips, 这里不需要解析
|
|
||||||
if t[0].Head.RoutingHead.GetFromTinyid() == c.GuildService.TinyId {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
updatedEvent := &GuildMessageReactionsUpdatedEvent{
|
|
||||||
GuildId: m.Head.RoutingHead.GetGuildId(),
|
|
||||||
ChannelId: m.Head.RoutingHead.GetChannelId(),
|
|
||||||
MessageId: t[0].Head.ContentHead.GetSeq(),
|
|
||||||
CurrentReactions: decodeGuildMessageEmojiReactions(t[0]),
|
|
||||||
}
|
|
||||||
tipsInfo, err := c.waitPacketTimeoutSyncF("MsgPush.PushGroupProMsg", time.Second, func(i interface{}) bool {
|
|
||||||
if i == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
_, ok := i.(*tipsPushInfo)
|
|
||||||
return ok
|
|
||||||
})
|
|
||||||
if err == nil {
|
|
||||||
updatedEvent.OperatorId = tipsInfo.(*tipsPushInfo).TinyId
|
|
||||||
updatedEvent.MessageSenderUin = tipsInfo.(*tipsPushInfo).TargetMessageSenderUin
|
|
||||||
}
|
|
||||||
c.dispatchGuildMessageReactionsUpdatedEvent(updatedEvent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if cm := c.parseGuildChannelMessage(m); cm != nil {
|
if cm := c.parseGuildChannelMessage(m); cm != nil {
|
||||||
@ -135,6 +74,70 @@ func decodeGuildEventFlowPacket(c *QQClient, _ *incomingPacketInfo, payload []by
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) processGuildEventBody(m *channel.ChannelMsgContent, eventBody *channel.EventBody) {
|
||||||
|
switch {
|
||||||
|
case eventBody.ChangeChanInfo != nil:
|
||||||
|
updateChanLock.Lock()
|
||||||
|
defer updateChanLock.Unlock()
|
||||||
|
guild := c.GuildService.FindGuild(m.Head.RoutingHead.GetGuildId())
|
||||||
|
oldInfo := guild.FindChannel(eventBody.ChangeChanInfo.GetChanId())
|
||||||
|
if time.Now().Unix()-oldInfo.fetchTime <= 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newInfo, err := c.GuildService.FetchChannelInfo(m.Head.RoutingHead.GetGuildId(), eventBody.ChangeChanInfo.GetChanId())
|
||||||
|
if err != nil {
|
||||||
|
c.Error("error to decode channel info updated event: fetch channel info failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := range guild.Channels {
|
||||||
|
if guild.Channels[i].ChannelId == newInfo.ChannelId {
|
||||||
|
guild.Channels[i] = newInfo
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.dispatchGuildChannelUpdatedEvent(&GuildChannelUpdatedEvent{
|
||||||
|
OperatorId: m.Head.RoutingHead.GetFromTinyid(),
|
||||||
|
GuildId: m.Head.RoutingHead.GetGuildId(),
|
||||||
|
ChannelId: eventBody.ChangeChanInfo.GetChanId(),
|
||||||
|
OldChannelInfo: oldInfo,
|
||||||
|
NewChannelInfo: newInfo,
|
||||||
|
})
|
||||||
|
case eventBody.UpdateMsg != nil:
|
||||||
|
if eventBody.UpdateMsg.GetEventType() == 1 || eventBody.UpdateMsg.GetEventType() == 2 { // todo: 撤回消息
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if eventBody.UpdateMsg.GetEventType() == 4 { // 消息贴表情更新 (包含添加或删除)
|
||||||
|
t, err := c.GuildService.pullRoamMsgByEventFlow(m.Head.RoutingHead.GetGuildId(), m.Head.RoutingHead.GetChannelId(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetMsgSeq(), eventBody.UpdateMsg.GetEventVersion()-1)
|
||||||
|
if err != nil || len(t) == 0 {
|
||||||
|
c.Error("process guild event flow error: pull eventMsg message error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 自己的消息被贴表情会单独推送一个tips, 这里不需要解析
|
||||||
|
if t[0].Head.RoutingHead.GetFromTinyid() == c.GuildService.TinyId {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updatedEvent := &GuildMessageReactionsUpdatedEvent{
|
||||||
|
GuildId: m.Head.RoutingHead.GetGuildId(),
|
||||||
|
ChannelId: m.Head.RoutingHead.GetChannelId(),
|
||||||
|
MessageId: t[0].Head.ContentHead.GetSeq(),
|
||||||
|
CurrentReactions: decodeGuildMessageEmojiReactions(t[0]),
|
||||||
|
}
|
||||||
|
tipsInfo, err := c.waitPacketTimeoutSyncF("MsgPush.PushGroupProMsg", time.Second, func(i interface{}) bool {
|
||||||
|
if i == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, ok := i.(*tipsPushInfo)
|
||||||
|
return ok
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
updatedEvent.OperatorId = tipsInfo.(*tipsPushInfo).TinyId
|
||||||
|
updatedEvent.MessageSenderUin = tipsInfo.(*tipsPushInfo).TargetMessageSenderUin
|
||||||
|
}
|
||||||
|
c.dispatchGuildMessageReactionsUpdatedEvent(updatedEvent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GuildService) pullRoamMsgByEventFlow(guildId, channelId, beginSeq, endSeq, eventVersion uint64) ([]*channel.ChannelMsgContent, error) {
|
func (s *GuildService) pullRoamMsgByEventFlow(guildId, channelId, beginSeq, endSeq, eventVersion uint64) ([]*channel.ChannelMsgContent, error) {
|
||||||
payload, _ := proto.Marshal(&channel.ChannelMsgReq{
|
payload, _ := proto.Marshal(&channel.ChannelMsgReq{
|
||||||
ChannelParam: &channel.ChannelParam{
|
ChannelParam: &channel.ChannelParam{
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
"image"
|
||||||
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@ -16,6 +22,25 @@ import (
|
|||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
guildImageUploadResponse struct {
|
||||||
|
UploadKey []byte
|
||||||
|
UploadIp []uint32
|
||||||
|
UploadPort []uint32
|
||||||
|
Width int32
|
||||||
|
Height int32
|
||||||
|
Message string
|
||||||
|
DownloadIndex string
|
||||||
|
FileId int64
|
||||||
|
ResultCode int32
|
||||||
|
IsExists bool
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
decoders["ImgStore.QQMeetPicUp"] = decodeGuildImageStoreResponse
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *message.SendingMessage) error {
|
func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *message.SendingMessage) error {
|
||||||
mr := rand.Uint32() // 客户端似乎是生成的 u32 虽然类型是u64
|
mr := rand.Uint32() // 客户端似乎是生成的 u32 虽然类型是u64
|
||||||
req := &channel.DF62ReqBody{Msg: &channel.ChannelMsgContent{
|
req := &channel.DF62ReqBody{Msg: &channel.ChannelMsgContent{
|
||||||
@ -55,14 +80,84 @@ func (s *GuildService) SendGuildChannelMessage(guildId, channelId uint64, m *mes
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *GuildService) QueryImage(guildId, channelId uint64, hash []byte, size uint64) (*message.GuildImageElement, error) {
|
func (s *GuildService) QueryImage(guildId, channelId uint64, hash []byte, size uint64) (*message.GuildImageElement, error) {
|
||||||
seq := s.c.nextSeq()
|
rsp, err := s.c.sendAndWait(s.c.buildGuildImageStorePacket(guildId, channelId, hash, size))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "send packet error")
|
||||||
|
}
|
||||||
|
body := rsp.(*guildImageUploadResponse)
|
||||||
|
if body.IsExists {
|
||||||
|
return &message.GuildImageElement{
|
||||||
|
FileId: body.FileId,
|
||||||
|
FilePath: hex.EncodeToString(hash) + ".jpg",
|
||||||
|
Size: int32(size),
|
||||||
|
DownloadIndex: body.DownloadIndex,
|
||||||
|
Width: body.Width,
|
||||||
|
Height: body.Height,
|
||||||
|
Md5: hash,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, errors.New("image is not exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GuildService) UploadGuildImage(guildId, channelId uint64, img io.ReadSeeker) (*message.GuildImageElement, error) {
|
||||||
|
_, _ = img.Seek(0, io.SeekStart) // safe
|
||||||
|
fh, length := utils.ComputeMd5AndLength(img)
|
||||||
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
|
rsp, err := s.c.sendAndWait(s.c.buildGuildImageStorePacket(guildId, channelId, fh, uint64(length)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
body := rsp.(*guildImageUploadResponse)
|
||||||
|
if body.IsExists {
|
||||||
|
goto ok
|
||||||
|
}
|
||||||
|
if len(s.c.srvSsoAddrs) == 0 {
|
||||||
|
for i, addr := range body.UploadIp {
|
||||||
|
s.c.srvSsoAddrs = append(s.c.srvSsoAddrs, fmt.Sprintf("%v:%v", binary.UInt32ToIPV4Address(addr), body.UploadPort[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err = s.c.highwayUploadByBDH(img, length, 83, body.UploadKey, fh, binary.DynamicProtoMessage{11: guildId, 12: channelId}.Encode(), false); err == nil {
|
||||||
|
goto ok
|
||||||
|
}
|
||||||
|
return nil, errors.Wrap(err, "highway upload error")
|
||||||
|
ok:
|
||||||
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
|
i, _, err := 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
|
||||||
|
}
|
||||||
|
width := int32(i.Width)
|
||||||
|
height := int32(i.Height)
|
||||||
|
if err != nil {
|
||||||
|
s.c.Warning("waring: decode image error: %v. this image will be displayed by wrong size in pc guild client", err)
|
||||||
|
width = 200
|
||||||
|
height = 200
|
||||||
|
}
|
||||||
|
return &message.GuildImageElement{
|
||||||
|
FileId: body.FileId,
|
||||||
|
FilePath: hex.EncodeToString(fh) + ".jpg",
|
||||||
|
Size: int32(length),
|
||||||
|
DownloadIndex: body.DownloadIndex,
|
||||||
|
Width: width,
|
||||||
|
Height: height,
|
||||||
|
ImageType: imageType,
|
||||||
|
Md5: fh,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) buildGuildImageStorePacket(guildId, channelId uint64, hash []byte, size uint64) (uint16, []byte) {
|
||||||
|
seq := c.nextSeq()
|
||||||
payload, _ := proto.Marshal(&cmd0x388.D388ReqBody{
|
payload, _ := proto.Marshal(&cmd0x388.D388ReqBody{
|
||||||
NetType: proto.Uint32(3),
|
NetType: proto.Uint32(3),
|
||||||
Subcmd: proto.Uint32(1),
|
Subcmd: proto.Uint32(1),
|
||||||
TryupImgReq: []*cmd0x388.TryUpImgReq{
|
TryupImgReq: []*cmd0x388.TryUpImgReq{
|
||||||
{
|
{
|
||||||
GroupCode: &channelId,
|
GroupCode: &channelId,
|
||||||
SrcUin: proto.Uint64(uint64(s.c.Uin)),
|
SrcUin: proto.Uint64(uint64(c.Uin)),
|
||||||
FileId: proto.Uint64(0),
|
FileId: proto.Uint64(0),
|
||||||
FileMd5: hash,
|
FileMd5: hash,
|
||||||
FileSize: &size,
|
FileSize: &size,
|
||||||
@ -80,28 +175,8 @@ func (s *GuildService) QueryImage(guildId, channelId uint64, hash []byte, size u
|
|||||||
},
|
},
|
||||||
CommandId: proto.Uint32(83),
|
CommandId: proto.Uint32(83),
|
||||||
})
|
})
|
||||||
packet := packets.BuildUniPacket(s.c.Uin, seq, "ImgStore.QQMeetPicUp", 1, s.c.OutGoingPacketSessionId, []byte{}, s.c.sigInfo.d2Key, payload)
|
packet := packets.BuildUniPacket(c.Uin, seq, "ImgStore.QQMeetPicUp", 1, c.OutGoingPacketSessionId, []byte{}, c.sigInfo.d2Key, payload)
|
||||||
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
|
return seq, packet
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "send packet error")
|
|
||||||
}
|
|
||||||
body := new(cmd0x388.D388RspBody)
|
|
||||||
if err = proto.Unmarshal(rsp, body); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
||||||
}
|
|
||||||
if len(body.TryupImgRsp) == 0 {
|
|
||||||
return nil, errors.New("response is empty")
|
|
||||||
}
|
|
||||||
if body.TryupImgRsp[0].GetFileExit() {
|
|
||||||
return &message.GuildImageElement{
|
|
||||||
FileId: body.TryupImgRsp[0].GetFileid(),
|
|
||||||
FilePath: hex.EncodeToString(hash) + ".jpg",
|
|
||||||
Size: int32(size),
|
|
||||||
DownloadIndex: string(body.TryupImgRsp[0].GetDownloadIndex()),
|
|
||||||
Md5: hash,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
return nil, errors.New("image is not exists")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeGuildMessageEmojiReactions(content *channel.ChannelMsgContent) (r []*message.GuildMessageEmojiReaction) {
|
func decodeGuildMessageEmojiReactions(content *channel.ChannelMsgContent) (r []*message.GuildMessageEmojiReaction) {
|
||||||
@ -140,6 +215,36 @@ func decodeGuildMessageEmojiReactions(content *channel.ChannelMsgContent) (r []*
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeGuildImageStoreResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||||
|
body := new(cmd0x388.D388RspBody)
|
||||||
|
if err := proto.Unmarshal(payload, body); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
|
}
|
||||||
|
if len(body.TryupImgRsp) == 0 {
|
||||||
|
return nil, errors.New("response is empty")
|
||||||
|
}
|
||||||
|
rsp := body.TryupImgRsp[0]
|
||||||
|
if rsp.GetResult() != 0 {
|
||||||
|
return &guildImageUploadResponse{
|
||||||
|
ResultCode: int32(rsp.GetResult()),
|
||||||
|
Message: utils.B2S(rsp.GetFailMsg()),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
if rsp.GetFileExit() {
|
||||||
|
if rsp.ImgInfo != nil {
|
||||||
|
return &guildImageUploadResponse{IsExists: true, FileId: int64(rsp.GetFileid()), DownloadIndex: string(rsp.GetDownloadIndex()), Width: int32(rsp.ImgInfo.GetFileWidth()), Height: int32(rsp.ImgInfo.GetFileHeight())}, nil
|
||||||
|
}
|
||||||
|
return &guildImageUploadResponse{IsExists: true, FileId: int64(rsp.GetFileid()), DownloadIndex: string(rsp.GetDownloadIndex())}, nil
|
||||||
|
}
|
||||||
|
return &guildImageUploadResponse{
|
||||||
|
FileId: int64(rsp.GetFileid()),
|
||||||
|
UploadKey: rsp.UpUkey,
|
||||||
|
UploadIp: rsp.GetUpIp(),
|
||||||
|
UploadPort: rsp.GetUpPort(),
|
||||||
|
DownloadIndex: string(rsp.GetDownloadIndex()),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *QQClient) parseGuildChannelMessage(msg *channel.ChannelMsgContent) *message.GuildChannelMessage {
|
func (c *QQClient) parseGuildChannelMessage(msg *channel.ChannelMsgContent) *message.GuildChannelMessage {
|
||||||
guild := c.GuildService.FindGuild(msg.Head.RoutingHead.GetGuildId())
|
guild := c.GuildService.FindGuild(msg.Head.RoutingHead.GetGuildId())
|
||||||
if guild == nil {
|
if guild == nil {
|
||||||
|
@ -34,6 +34,21 @@ func init() {
|
|||||||
|
|
||||||
var imgWaiter = utils.NewUploadWaiter()
|
var imgWaiter = utils.NewUploadWaiter()
|
||||||
|
|
||||||
|
type (
|
||||||
|
imageUploadResponse struct {
|
||||||
|
UploadKey []byte
|
||||||
|
UploadIp []uint32
|
||||||
|
UploadPort []uint32
|
||||||
|
ResourceId string
|
||||||
|
Message string
|
||||||
|
FileId int64
|
||||||
|
Width int32
|
||||||
|
Height int32
|
||||||
|
ResultCode int32
|
||||||
|
IsExists bool
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func (c *QQClient) UploadGroupImage(groupCode int64, img io.ReadSeeker) (*message.GroupImageElement, error) {
|
func (c *QQClient) UploadGroupImage(groupCode int64, img io.ReadSeeker) (*message.GroupImageElement, error) {
|
||||||
_, _ = img.Seek(0, io.SeekStart) // safe
|
_, _ = img.Seek(0, io.SeekStart) // safe
|
||||||
fh, length := utils.ComputeMd5AndLength(img)
|
fh, length := utils.ComputeMd5AndLength(img)
|
||||||
|
@ -37,7 +37,7 @@ type FriendImageElement struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GuildImageElement struct {
|
type GuildImageElement struct {
|
||||||
FileId uint64
|
FileId int64
|
||||||
FilePath string
|
FilePath string
|
||||||
ImageType int32
|
ImageType int32
|
||||||
Size int32
|
Size int32
|
||||||
|
Loading…
x
Reference in New Issue
Block a user