From 24b2111673a55380e9155f2f37dd93084cc76ebf Mon Sep 17 00:00:00 2001 From: 2mf8 Date: Sun, 31 Jul 2022 16:54:30 +0800 Subject: [PATCH] fix send channel image --- pkg/bot/api_handler.go | 41 +++++++++++++++++++++++++++++++++++++---- pkg/bot/mirai2proto.go | 15 +++++++++++++++ pkg/bot/mirai2raw.go | 6 +++--- pkg/bot/proto2mirai.go | 38 ++++++++++++++++++++++++++++++++++++-- pkg/bot/raw2mirai.go | 2 ++ pkg/clz/clz.go | 12 ++++++------ pkg/gmc/plugins/log.go | 2 +- 7 files changed, 100 insertions(+), 16 deletions(-) diff --git a/pkg/bot/api_handler.go b/pkg/bot/api_handler.go index 38535f6..4b4ef5d 100644 --- a/pkg/bot/api_handler.go +++ b/pkg/bot/api_handler.go @@ -56,7 +56,7 @@ func preProcessPrivateSendingMessage(cli *client.QQClient, target int64, m *mess log.Errorf("failed to upload private image, %+v", err) continue } - if i.Tp == "flash" { + if i.LocalImageType == "flash" { img.Flash = true } newElements = append(newElements, img) @@ -109,9 +109,9 @@ func preProcessGroupSendingMessage(cli *client.QQClient, groupCode int64, m *mes continue } if img, ok := img.(*message.GroupImageElement); ok { - if i.Tp == "flash" { + if i.LocalImageType == "flash" { img.Flash = true - } else if i.Tp == "show" { + } else if i.LocalImageType == "show" { img.EffectID = i.EffectId } } @@ -613,14 +613,47 @@ func HandleSetFriendPoke(cli *client.QQClient, req *onebot.SetFriendPokeReq) *on return nil } +func preProcessChannelSendingMessage(cli *client.QQClient, guildid uint64, channelId uint64, m *message.SendingMessage) { + newElements := make([]message.IMessageElement, 0, len(m.Elements)) + for _, element := range m.Elements { + if i, ok := element.(*message.TextElement); ok { + for _, text := range utils.ChunkString(i.Content, MAX_TEXT_LENGTH) { + if text != "" { + newElements = append(newElements, message.NewText(text)) + } + } + continue + } + if i, ok := element.(*clz.LocalImageElement); ok { + img, err := cli.UploadImage(message.Source{SourceType: message.SourceGuildChannel, PrimaryID: int64(guildid), SecondaryID: int64(channelId)}, i.Stream) + if err != nil { + log.Errorf("failed to upload guild image, %+v", err) + continue + } + newElements = append(newElements, img) + continue + } + } + m.Elements = newElements +} + func HandleSendChannelMsg(cli *client.QQClient, req *onebot.SendChannelMsgReq) *onebot.SendChannelMsgResp { + if len(req.Message) == 0 { + log.Warnf("消息为空") + return nil + } miraiMsg := ProtoMsgToMiraiMsg(cli, req.Message, req.AutoEscape) sendingMessage := &message.SendingMessage{Elements: miraiMsg} channelInfo, _ := cli.GuildService.FetchChannelInfo(req.GuildId, req.ChannelId) - log.Infof("Bot(%+v) Guild(%+v) ChannelId(%+v) <- %+v\n", cli.Uin, req.GuildId, req.ChannelId, MiraiMsgToRawMsg(cli, miraiMsg)) + log.Infof("Bot(%+v) GuildId(%+v) ChannelId(%+v) <- %+v\n", cli.Uin, req.GuildId, req.ChannelId, MiraiMsgToRawMsg(cli, miraiMsg)) if channelInfo.ChannelType != client.ChannelTypeText { log.Warnf("无法发送频道信息: 频道类型错误, 不接受文本信息") } + preProcessChannelSendingMessage(cli, req.GuildId, req.ChannelId, sendingMessage) + if len(sendingMessage.Elements) == 0 { + log.Warnf("发送消息内容为空") + return nil + } ret, _ := cli.GuildService.SendGuildChannelMessage(req.GuildId, req.ChannelId, sendingMessage) if ret == nil { return nil diff --git a/pkg/bot/mirai2proto.go b/pkg/bot/mirai2proto.go index 013baaa..c66e7fd 100644 --- a/pkg/bot/mirai2proto.go +++ b/pkg/bot/mirai2proto.go @@ -22,6 +22,8 @@ func MiraiMsgToProtoMsg(cli *client.QQClient, messageChain []message.IMessageEle msgList = append(msgList, MiraiDiceToProtoDice(elem)) case *message.FingerGuessingElement: msgList = append(msgList, MiraiFingerGuessingToProtoFingerGuessing(elem)) + case *message.GuildImageElement: + msgList = append(msgList, MiraiGuildImageToProtoImage(elem)) case *message.FriendImageElement: msgList = append(msgList, MiraiFriendImageToProtoImage(elem)) case *message.GroupImageElement: @@ -88,6 +90,19 @@ func MiraiGroupImageToProtoImage(elem *message.GroupImageElement) *onebot.Messag return msg } +func MiraiGuildImageToProtoImage(elem *message.GuildImageElement) *onebot.Message { + msg := &onebot.Message{ + Type: "guild_image", + Data: map[string]string{ + "file_id": strconv.FormatInt(elem.FileId, 10), + "file": elem.FilePath, + "url": elem.Url, + "download_index": elem.DownloadIndex, + }, + } + return msg +} + func MiraiLocalImageToProtoImage(elem *clz.LocalImageElement) *onebot.Message { return &onebot.Message{ Type: "image", diff --git a/pkg/bot/mirai2raw.go b/pkg/bot/mirai2raw.go index 0805139..f8e4606 100644 --- a/pkg/bot/mirai2raw.go +++ b/pkg/bot/mirai2raw.go @@ -3,7 +3,7 @@ package bot import ( "fmt" "html" - + "strconv" "github.com/ProtobufBot/Go-Mirai-Client/pkg/clz" "github.com/Mrs4s/MiraiGo/client" @@ -22,12 +22,12 @@ func MiraiMsgToRawMsg(cli *client.QQClient, messageChain []message.IMessageEleme result += fmt.Sprintf(``, elem.Value) case *message.FingerGuessingElement: result += fmt.Sprintf(``, elem.Value, elem.Name) + case *message.GuildImageElement: + result += fmt.Sprintf(``, html.EscapeString(strconv.FormatInt(elem.FileId, 10)), html.EscapeString(elem.FilePath), html.EscapeString(elem.Url)) case *message.FriendImageElement: result += fmt.Sprintf(``, html.EscapeString(elem.ImageId), html.EscapeString(elem.Url)) case *message.GroupImageElement: result += fmt.Sprintf(``, html.EscapeString(elem.ImageId), html.EscapeString(elem.Url)) - case *message.GuildImageElement: - result += fmt.Sprintf(``, html.EscapeString(elem.FilePath), html.EscapeString(elem.Url)) case *clz.LocalImageElement: result += fmt.Sprintf(``, html.EscapeString(elem.Url)) case *message.FaceElement: diff --git a/pkg/bot/proto2mirai.go b/pkg/bot/proto2mirai.go index d0dd0c8..a5d2992 100644 --- a/pkg/bot/proto2mirai.go +++ b/pkg/bot/proto2mirai.go @@ -55,6 +55,8 @@ func ProtoMsgToMiraiMsg(cli *client.QQClient, msgList []*onebot.Message, notConv messageChain = append(messageChain, ProtoPokeToMiraiPoke(protoMsg.Data)) case "sign_in": messageChain = append(messageChain, ProtoSignInToMiraiSignIn(protoMsg.Data)) + case "guild_image": + messageChain = append(messageChain, ProtoGuildImageToMiraiGuildImage(protoMsg.Data)) case "image": messageChain = append(messageChain, ProtoImageToMiraiImage(protoMsg.Data)) case "img": @@ -128,8 +130,8 @@ func ProtoImageToMiraiImage(data map[string]string) message.IMessageElement { elem.Stream = bytes.NewReader(imageBytes) } - elem.Tp = data["type"] // show或flash - if elem.Tp == "show" { + elem.LocalImageType = data["type"] // show或flash + if elem.LocalImageType == "show" { effectIdStr := data["effect_id"] effectId, err := strconv.Atoi(effectIdStr) if err != nil || effectId < 40000 || effectId > 40005 { @@ -141,6 +143,38 @@ func ProtoImageToMiraiImage(data map[string]string) message.IMessageElement { return elem } +func ProtoGuildImageToMiraiGuildImage(data map[string]string) message.IMessageElement { + elem := &clz.LocalImageElement{} + url, ok := data["url"] + if !ok { + url, ok = data["src"] // TODO 为了兼容我的旧代码偷偷加的 + if !ok { + url, ok = data["file"] + } + } + if !ok { + log.Warnf("imageUrl不存在") + return EmptyText() + } + elem.Url = url + if strings.Contains(url, "http://") || strings.Contains(url, "https://") { + b, err := util.GetBytes(url) + if err != nil { + log.Errorf("failed to download image, %+v", err) + return EmptyText() + } + elem.Stream = bytes.NewReader(b) + } else { + imageBytes, err := ioutil.ReadFile(url) + if err != nil { + log.Errorf("failed to open local image, %+v", err) + return EmptyText() + } + elem.Stream = bytes.NewReader(imageBytes) + } + return elem +} + func ProtoVoiceToMiraiVoice(data map[string]string) message.IMessageElement { url, ok := data["url"] if !ok { diff --git a/pkg/bot/raw2mirai.go b/pkg/bot/raw2mirai.go index 74f7243..caa5d88 100644 --- a/pkg/bot/raw2mirai.go +++ b/pkg/bot/raw2mirai.go @@ -53,6 +53,8 @@ func RawMsgToMiraiMsg(cli *client.QQClient, str string) []message.IMessageElemen elemList = append(elemList, ProtoFingerGuessingToMiraiFingerGuessing(attrMap)) case "poke": elemList = append(elemList, ProtoPokeToMiraiPoke(attrMap)) + case "guild_image": + elemList = append(elemList, ProtoGuildImageToMiraiGuildImage(attrMap)) case "img": elemList = append(elemList, ProtoImageToMiraiImage(attrMap)) // TODO 为了兼容我的旧代码偷偷加的 case "image": diff --git a/pkg/clz/clz.go b/pkg/clz/clz.go index 741df98..eaf4665 100644 --- a/pkg/clz/clz.go +++ b/pkg/clz/clz.go @@ -16,10 +16,10 @@ type MyVideoElement struct { } type LocalImageElement struct { - Url string - Stream io.ReadSeeker - Tp string // 类型 flash/show - EffectId int32 // show的特效id,范围40000-40005 + Url string + Stream io.ReadSeeker + LocalImageType string // 类型 flash/show + EffectId int32 // show的特效id,范围40000-40005 } func (m *LocalImageElement) Type() message.ElementType { @@ -37,6 +37,6 @@ func (g *PokeElement) Type() message.ElementType { return message.At } -func (s *SignInElement) Type() message.ElementType{ +func (s *SignInElement) Type() message.ElementType { return message.Text -} \ No newline at end of file +} diff --git a/pkg/gmc/plugins/log.go b/pkg/gmc/plugins/log.go index f3e9f0a..7d5cb0f 100644 --- a/pkg/gmc/plugins/log.go +++ b/pkg/gmc/plugins/log.go @@ -22,6 +22,6 @@ func LogGroupMessage(cli *client.QQClient, event *message.GroupMessage) int32 { } func LogChannelMessage(cli *client.QQClient, event *message.GuildChannelMessage) int32 { - log.Infof("Bot(%+v) Guild(%+v) ChannelId(%+v) -> %+v\n", cli.Uin, event.GuildId, event.ChannelId, bot.MiraiMsgToRawMsg(cli, event.Elements)) + log.Infof("Bot(%+v) GuildId(%+v) ChannelId(%+v) -> %+v\n", cli.Uin, event.GuildId, event.ChannelId, bot.MiraiMsgToRawMsg(cli, event.Elements)) return plugin.MessageIgnore }