1
0
mirror of https://github.com/Mrs4s/go-cqhttp.git synced 2025-05-05 03:23:49 +08:00

revert: re-include url in message (#1521)

* revert: re-include url in message

* fix: wrong writer usage

* fix: composite literal uses unkeyed fields

* 优化buffer

* fix: illegal use of non-zero Builder

* fix: illegal use of non-zero Builder

* fix: make lint happy

* fix: replace io.Writer to *strings.Builder

* fix: replace io.Writer to *strings.Builder
This commit is contained in:
源文雨 2022-05-30 14:17:34 +08:00 committed by GitHub
parent 43ea459365
commit 15602e1daa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 71 deletions

View File

@ -1561,7 +1561,7 @@ func (bot *CQBot) CQGetForwardMessage(resID string) global.MSG {
r := make([]global.MSG, len(nodes)) r := make([]global.MSG, len(nodes))
for i, n := range nodes { for i, n := range nodes {
bot.checkMedia(n.Message, 0) bot.checkMedia(n.Message, 0)
content := ToFormattedMessage(n.Message, message.Source{SourceType: message.SourceGroup}, false) content := ToFormattedMessage(n.Message, message.Source{SourceType: message.SourceGroup})
if len(n.Message) == 1 { if len(n.Message) == 1 {
if forward, ok := n.Message[0].(*message.ForwardMessage); ok { if forward, ok := n.Message[0].(*message.ForwardMessage); ok {
content = transformNodes(forward.Nodes) content = transformNodes(forward.Nodes)
@ -1610,9 +1610,9 @@ func (bot *CQBot) CQGetMessage(messageID int32) global.MSG {
switch o := msg.(type) { switch o := msg.(type) {
case *db.StoredGroupMessage: case *db.StoredGroupMessage:
m["group_id"] = o.GroupCode m["group_id"] = o.GroupCode
m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourceGroup), message.Source{SourceType: message.SourceGroup, PrimaryID: o.GroupCode}, false) m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourceGroup), message.Source{SourceType: message.SourceGroup, PrimaryID: o.GroupCode})
case *db.StoredPrivateMessage: case *db.StoredPrivateMessage:
m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourcePrivate), message.Source{SourceType: message.SourcePrivate}, false) m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourcePrivate), message.Source{SourceType: message.SourcePrivate})
} }
return OK(m) return OK(m)
} }
@ -1657,7 +1657,7 @@ func (bot *CQBot) CQGetGuildMessage(messageID string, noCache bool) global.MSG {
"tiny_id": fU64(pull[0].Sender.TinyId), "tiny_id": fU64(pull[0].Sender.TinyId),
"nickname": pull[0].Sender.Nickname, "nickname": pull[0].Sender.Nickname,
} }
m["message"] = ToFormattedMessage(pull[0].Elements, source, false) m["message"] = ToFormattedMessage(pull[0].Elements, source)
m["reactions"] = convertReactions(pull[0].Reactions) m["reactions"] = convertReactions(pull[0].Reactions)
bot.InsertGuildChannelMessage(pull[0]) bot.InsertGuildChannelMessage(pull[0])
} else { } else {
@ -1672,7 +1672,7 @@ func (bot *CQBot) CQGetGuildMessage(messageID string, noCache bool) global.MSG {
"tiny_id": fU64(channelMsgByDB.Attribute.SenderTinyID), "tiny_id": fU64(channelMsgByDB.Attribute.SenderTinyID),
"nickname": channelMsgByDB.Attribute.SenderName, "nickname": channelMsgByDB.Attribute.SenderName,
} }
m["message"] = ToFormattedMessage(bot.ConvertContentMessage(channelMsgByDB.Content, message.SourceGuildChannel), source, false) m["message"] = ToFormattedMessage(bot.ConvertContentMessage(channelMsgByDB.Content, message.SourceGuildChannel), source)
} }
case message.SourceGuildDirect: case message.SourceGuildDirect:
// todo(mrs4s): 支持 direct 消息 // todo(mrs4s): 支持 direct 消息

View File

@ -65,7 +65,7 @@ func (bot *CQBot) formatGroupMessage(m *message.GroupMessage) *event {
SourceType: message.SourceGroup, SourceType: message.SourceGroup,
PrimaryID: m.GroupCode, PrimaryID: m.GroupCode,
} }
cqm := toStringMessage(m.Elements, source, true) cqm := toStringMessage(m.Elements, source)
typ := "message/group/normal" typ := "message/group/normal"
if m.Sender.Uin == bot.Client.Uin { if m.Sender.Uin == bot.Client.Uin {
typ = "message_sent/group/normal" typ = "message_sent/group/normal"
@ -74,7 +74,7 @@ func (bot *CQBot) formatGroupMessage(m *message.GroupMessage) *event {
"anonymous": nil, "anonymous": nil,
"font": 0, "font": 0,
"group_id": m.GroupCode, "group_id": m.GroupCode,
"message": ToFormattedMessage(m.Elements, source, false), "message": ToFormattedMessage(m.Elements, source),
"message_type": "group", "message_type": "group",
"message_seq": m.Id, "message_seq": m.Id,
"raw_message": cqm, "raw_message": cqm,
@ -210,11 +210,11 @@ func convertReactions(reactions []*message.GuildMessageEmojiReaction) (r []globa
return return
} }
func toStringMessage(m []message.IMessageElement, source message.Source, raw bool) string { func toStringMessage(m []message.IMessageElement, source message.Source) string {
elems := toElements(m, source, raw) elems := toElements(m, source)
var sb strings.Builder var sb strings.Builder
for _, elem := range elems { for _, elem := range elems {
sb.WriteString(elem.CQCode()) elem.WriteCQCodeTo(&sb)
} }
return sb.String() return sb.String()
} }

View File

@ -95,7 +95,7 @@ func replyID(r *message.ReplyElement, source message.Source) int32 {
// toElements 将消息元素数组转为MSG数组以用于消息上报 // toElements 将消息元素数组转为MSG数组以用于消息上报
// //
// nolint:govet // nolint:govet
func toElements(e []message.IMessageElement, source message.Source, raw bool) (r []cqcode.Element) { func toElements(e []message.IMessageElement, source message.Source) (r []cqcode.Element) {
type pair = cqcode.Pair // simplify code type pair = cqcode.Pair // simplify code
type pairs = []pair type pairs = []pair
@ -111,7 +111,7 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
elem := cqcode.Element{ elem := cqcode.Element{
Type: "reply", Type: "reply",
Data: pairs{ Data: pairs{
{"id", strconv.FormatInt(int64(id), 10)}, {K: "id", V: strconv.FormatInt(int64(id), 10)},
}, },
} }
if base.ExtraReplyData { if base.ExtraReplyData {
@ -119,7 +119,7 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
pair{K: "seq", V: strconv.FormatInt(int64(replyElem.ReplySeq), 10)}, pair{K: "seq", V: strconv.FormatInt(int64(replyElem.ReplySeq), 10)},
pair{K: "qq", V: strconv.FormatInt(replyElem.Sender, 10)}, pair{K: "qq", V: strconv.FormatInt(replyElem.Sender, 10)},
pair{K: "time", V: strconv.FormatInt(int64(replyElem.Time), 10)}, pair{K: "time", V: strconv.FormatInt(int64(replyElem.Time), 10)},
pair{K: "text", V: toStringMessage(replyElem.Elements, source, true)}, pair{K: "text", V: toStringMessage(replyElem.Elements, source)},
) )
} }
r = append(r, elem) r = append(r, elem)
@ -139,14 +139,14 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
m = cqcode.Element{ m = cqcode.Element{
Type: "text", Type: "text",
Data: pairs{ Data: pairs{
{"text", o.Content}, {K: "text", V: o.Content},
}, },
} }
case *message.LightAppElement: case *message.LightAppElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "json", Type: "json",
Data: pairs{ Data: pairs{
{"data", o.Content}, {K: "data", V: o.Content},
}, },
} }
case *message.AtElement: case *message.AtElement:
@ -157,53 +157,51 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
m = cqcode.Element{ m = cqcode.Element{
Type: "at", Type: "at",
Data: pairs{ Data: pairs{
{"qq", target}, {K: "qq", V: target},
}, },
} }
case *message.RedBagElement: case *message.RedBagElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "redbag", Type: "redbag",
Data: pairs{ Data: pairs{
{"title", o.Title}, {K: "title", V: o.Title},
}, },
} }
case *message.ForwardElement: case *message.ForwardElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "forward", Type: "forward",
Data: pairs{ Data: pairs{
{"id", o.ResId}, {K: "id", V: o.ResId},
}, },
} }
case *message.FaceElement: case *message.FaceElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "face", Type: "face",
Data: pairs{ Data: pairs{
{"id", strconv.FormatInt(int64(o.Index), 10)}, {K: "id", V: strconv.FormatInt(int64(o.Index), 10)},
}, },
} }
case *message.VoiceElement: case *message.VoiceElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "record", Type: "record",
Data: pairs{ Data: pairs{
{"file", o.Name}, {K: "file", V: o.Name},
{"url", o.Url}, {K: "url", V: o.Url},
}, },
} }
case *message.ShortVideoElement: case *message.ShortVideoElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "video", Type: "video",
Data: pairs{ Data: pairs{
{"file", o.Name}, {K: "file", V: o.Name},
{"url", o.Url}, {K: "url", V: o.Url},
}, },
} }
case *message.GroupImageElement: case *message.GroupImageElement:
data := pairs{ data := pairs{
{"file", hex.EncodeToString(o.Md5) + ".image"}, {K: "file", V: hex.EncodeToString(o.Md5) + ".image"},
{"subType", strconv.FormatInt(int64(o.ImageBizType), 10)}, {K: "subType", V: strconv.FormatInt(int64(o.ImageBizType), 10)},
} {K: "url", V: o.Url},
if raw {
data = append(data, pair{K: "url", V: o.Url})
} }
switch { switch {
case o.Flash: case o.Flash:
@ -218,10 +216,8 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
} }
case *message.GuildImageElement: case *message.GuildImageElement:
data := pairs{ data := pairs{
{"file", hex.EncodeToString(o.Md5) + ".image"}, {K: "file", V: hex.EncodeToString(o.Md5) + ".image"},
} {K: "url", V: o.Url},
if raw {
data = append(data, pair{K: "url", V: o.Url})
} }
m = cqcode.Element{ m = cqcode.Element{
Type: "image", Type: "image",
@ -229,10 +225,8 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
} }
case *message.FriendImageElement: case *message.FriendImageElement:
data := pairs{ data := pairs{
{"file", hex.EncodeToString(o.Md5) + ".image"}, {K: "file", V: hex.EncodeToString(o.Md5) + ".image"},
} {K: "url", V: o.Url},
if raw {
data = append(data, pair{K: "url", V: o.Url})
} }
if o.Flash { if o.Flash {
data = append(data, pair{K: "type", V: "flash"}) data = append(data, pair{K: "type", V: "flash"})
@ -245,29 +239,29 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
m = cqcode.Element{ m = cqcode.Element{
Type: "dice", Type: "dice",
Data: pairs{ Data: pairs{
{"value", strconv.FormatInt(int64(o.Value), 10)}, {K: "value", V: strconv.FormatInt(int64(o.Value), 10)},
}, },
} }
case *message.FingerGuessingElement: case *message.FingerGuessingElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "rps", Type: "rps",
Data: pairs{ Data: pairs{
{"value", strconv.FormatInt(int64(o.Value), 10)}, {K: "value", V: strconv.FormatInt(int64(o.Value), 10)},
}, },
} }
case *message.MarketFaceElement: case *message.MarketFaceElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "text", Type: "text",
Data: pairs{ Data: pairs{
{"text", o.Name}, {K: "text", V: o.Name},
}, },
} }
case *message.ServiceElement: case *message.ServiceElement:
m = cqcode.Element{ m = cqcode.Element{
Type: "xml", Type: "xml",
Data: pairs{ Data: pairs{
{"data", o.Content}, {K: "data", V: o.Content},
{"resid", o.ResId}, {K: "resid", V: o.ResId},
}, },
} }
if !strings.Contains(o.Content, "<?xml") { if !strings.Contains(o.Content, "<?xml") {
@ -277,8 +271,8 @@ func toElements(e []message.IMessageElement, source message.Source, raw bool) (r
m = cqcode.Element{ m = cqcode.Element{
Type: "face", Type: "face",
Data: pairs{ Data: pairs{
{"id", strconv.FormatInt(int64(o.ID), 10)}, {K: "id", V: strconv.FormatInt(int64(o.ID), 10)},
{"type", "sticker"}, {K: "type", V: "sticker"},
}, },
} }
default: default:

View File

@ -1,10 +1,11 @@
package cqcode package cqcode
import ( import (
"fmt" "bytes"
"strconv"
"strings" "strings"
"github.com/Mrs4s/go-cqhttp/global" "github.com/Mrs4s/MiraiGo/binary"
) )
// Element single message // Element single message
@ -19,12 +20,19 @@ type Pair struct {
V string V string
} }
// CQCode convert to cqcode // CQCode convert element to cqcode
func (e *Element) CQCode() string { func (e *Element) CQCode() string {
buf := strings.Builder{}
e.WriteCQCodeTo(&buf)
return buf.String()
}
// WriteCQCodeTo write element's cqcode into sb
func (e *Element) WriteCQCodeTo(sb *strings.Builder) {
if e.Type == "text" { if e.Type == "text" {
return EscapeText(e.Data[0].V) // must be {"text": value} sb.WriteString(EscapeText(e.Data[0].V)) // must be {"text": value}
return
} }
var sb strings.Builder
sb.WriteString("[CQ:") sb.WriteString("[CQ:")
sb.WriteString(e.Type) sb.WriteString(e.Type)
for _, data := range e.Data { for _, data := range e.Data {
@ -34,22 +42,26 @@ func (e *Element) CQCode() string {
sb.WriteString(EscapeValue(data.V)) sb.WriteString(EscapeValue(data.V))
} }
sb.WriteByte(']') sb.WriteByte(']')
return sb.String()
} }
// MarshalJSON see encoding/json.Marshaler // MarshalJSON see encoding/json.Marshaler
func (e *Element) MarshalJSON() ([]byte, error) { func (e *Element) MarshalJSON() ([]byte, error) {
buf := global.NewBuffer() return binary.NewWriterF(func(w *binary.Writer) {
defer global.PutBuffer(buf) buf := (*bytes.Buffer)(w)
// fmt.Fprintf(buf, `{"type":"%s","data":{`, e.Type)
fmt.Fprintf(buf, `{"type":"%s","data":{`, e.Type) buf.WriteString(`{"type":"`)
buf.WriteString(e.Type)
buf.WriteString(`","data":{`)
for i, data := range e.Data { for i, data := range e.Data {
if i != 0 { if i != 0 {
buf.WriteByte(',') buf.WriteByte(',')
} }
fmt.Fprintf(buf, `"%s":%q`, data.K, data.V) // fmt.Fprintf(buf, `"%s":%q`, data.K, data.V)
buf.WriteByte('"')
buf.WriteString(data.K)
buf.WriteString(`":`)
buf.WriteString(strconv.Quote(data.V))
} }
buf.WriteString(`}}`) buf.WriteString(`}}`)
}), nil
return append([]byte(nil), buf.Bytes()...), nil
} }

View File

@ -21,11 +21,11 @@ import (
) )
// ToFormattedMessage 将给定[]message.IMessageElement转换为通过coolq.SetMessageFormat所定义的消息上报格式 // ToFormattedMessage 将给定[]message.IMessageElement转换为通过coolq.SetMessageFormat所定义的消息上报格式
func ToFormattedMessage(e []message.IMessageElement, source message.Source, raw bool) (r interface{}) { func ToFormattedMessage(e []message.IMessageElement, source message.Source) (r interface{}) {
if base.PostFormat == "string" { if base.PostFormat == "string" {
r = toStringMessage(e, source, raw) r = toStringMessage(e, source)
} else if base.PostFormat == "array" { } else if base.PostFormat == "array" {
r = toElements(e, source, raw) r = toElements(e, source)
} }
return return
} }
@ -74,7 +74,7 @@ func (bot *CQBot) privateMessageEvent(_ *client.QQClient, m *message.PrivateMess
SourceType: message.SourcePrivate, SourceType: message.SourcePrivate,
PrimaryID: m.Sender.Uin, PrimaryID: m.Sender.Uin,
} }
cqm := toStringMessage(m.Elements, source, true) cqm := toStringMessage(m.Elements, source)
id := bot.InsertPrivateMessage(m) id := bot.InsertPrivateMessage(m)
log.Infof("收到好友 %v(%v) 的消息: %v (%v)", m.Sender.DisplayName(), m.Sender.Uin, cqm, id) log.Infof("收到好友 %v(%v) 的消息: %v (%v)", m.Sender.DisplayName(), m.Sender.Uin, cqm, id)
typ := "message/private/friend" typ := "message/private/friend"
@ -85,7 +85,7 @@ func (bot *CQBot) privateMessageEvent(_ *client.QQClient, m *message.PrivateMess
"message_id": id, "message_id": id,
"user_id": m.Sender.Uin, "user_id": m.Sender.Uin,
"target_id": m.Target, "target_id": m.Target,
"message": ToFormattedMessage(m.Elements, source, false), "message": ToFormattedMessage(m.Elements, source),
"raw_message": cqm, "raw_message": cqm,
"font": 0, "font": 0,
"sender": global.MSG{ "sender": global.MSG{
@ -121,7 +121,7 @@ func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage)
SourceType: message.SourceGroup, SourceType: message.SourceGroup,
PrimaryID: m.GroupCode, PrimaryID: m.GroupCode,
} }
cqm := toStringMessage(m.Elements, source, true) cqm := toStringMessage(m.Elements, source)
id := bot.InsertGroupMessage(m) id := bot.InsertGroupMessage(m)
log.Infof("收到群 %v(%v) 内 %v(%v) 的消息: %v (%v)", m.GroupName, m.GroupCode, m.Sender.DisplayName(), m.Sender.Uin, cqm, id) log.Infof("收到群 %v(%v) 内 %v(%v) 的消息: %v (%v)", m.GroupName, m.GroupCode, m.Sender.DisplayName(), m.Sender.Uin, cqm, id)
gm := bot.formatGroupMessage(m) gm := bot.formatGroupMessage(m)
@ -139,7 +139,7 @@ func (bot *CQBot) tempMessageEvent(c *client.QQClient, e *client.TempMessageEven
SourceType: message.SourcePrivate, SourceType: message.SourcePrivate,
PrimaryID: e.Session.Sender, PrimaryID: e.Session.Sender,
} }
cqm := toStringMessage(m.Elements, source, true) cqm := toStringMessage(m.Elements, source)
bot.tempSessionCache.Store(m.Sender.Uin, e.Session) bot.tempSessionCache.Store(m.Sender.Uin, e.Session)
id := m.Id id := m.Id
// todo(Mrs4s) // todo(Mrs4s)
@ -151,7 +151,7 @@ func (bot *CQBot) tempMessageEvent(c *client.QQClient, e *client.TempMessageEven
"temp_source": e.Session.Source, "temp_source": e.Session.Source,
"message_id": id, "message_id": id,
"user_id": m.Sender.Uin, "user_id": m.Sender.Uin,
"message": ToFormattedMessage(m.Elements, source, false), "message": ToFormattedMessage(m.Elements, source),
"raw_message": cqm, "raw_message": cqm,
"font": 0, "font": 0,
"sender": global.MSG{ "sender": global.MSG{
@ -177,14 +177,14 @@ func (bot *CQBot) guildChannelMessageEvent(c *client.QQClient, m *message.GuildC
PrimaryID: int64(m.GuildId), PrimaryID: int64(m.GuildId),
SecondaryID: int64(m.ChannelId), SecondaryID: int64(m.ChannelId),
} }
log.Infof("收到来自频道 %v(%v) 子频道 %v(%v) 内 %v(%v) 的消息: %v", guild.GuildName, guild.GuildId, channel.ChannelName, m.ChannelId, m.Sender.Nickname, m.Sender.TinyId, toStringMessage(m.Elements, source, true)) log.Infof("收到来自频道 %v(%v) 子频道 %v(%v) 内 %v(%v) 的消息: %v", guild.GuildName, guild.GuildId, channel.ChannelName, m.ChannelId, m.Sender.Nickname, m.Sender.TinyId, toStringMessage(m.Elements, source))
id := bot.InsertGuildChannelMessage(m) id := bot.InsertGuildChannelMessage(m)
ev := bot.event("message/guild/channel", global.MSG{ ev := bot.event("message/guild/channel", global.MSG{
"guild_id": fU64(m.GuildId), "guild_id": fU64(m.GuildId),
"channel_id": fU64(m.ChannelId), "channel_id": fU64(m.ChannelId),
"message_id": id, "message_id": id,
"user_id": fU64(m.Sender.TinyId), "user_id": fU64(m.Sender.TinyId),
"message": ToFormattedMessage(m.Elements, source, false), // todo: 增加对频道消息 Reply 的支持 "message": ToFormattedMessage(m.Elements, source), // todo: 增加对频道消息 Reply 的支持
"self_tiny_id": fU64(bot.Client.GuildService.TinyId), "self_tiny_id": fU64(bot.Client.GuildService.TinyId),
"sender": global.MSG{ "sender": global.MSG{
"user_id": m.Sender.TinyId, "user_id": m.Sender.TinyId,