mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
feat: link nested forward message
This commit is contained in:
parent
a5410846cb
commit
dc66c61d57
@ -3,7 +3,6 @@ package client
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net"
|
||||
"sort"
|
||||
@ -19,7 +18,6 @@ import (
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||
"github.com/Mrs4s/MiraiGo/internal/crypto"
|
||||
"github.com/Mrs4s/MiraiGo/internal/packets"
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
)
|
||||
|
||||
@ -546,68 +544,6 @@ func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (c *QQClient) GetForwardMessage(resID string) *message.ForwardMessage {
|
||||
m := c.DownloadForwardMessage(resID)
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
var item *msg.PbMultiMsgItem
|
||||
ret := &message.ForwardMessage{Nodes: []*message.ForwardNode{}}
|
||||
for _, iter := range m.Items {
|
||||
if iter.GetFileName() == m.FileName {
|
||||
item = iter
|
||||
}
|
||||
}
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
for _, m := range item.GetBuffer().GetMsg() {
|
||||
name := m.Head.GetFromNick()
|
||||
if m.Head.GetMsgType() == 82 && m.Head.GroupInfo != nil {
|
||||
name = m.Head.GroupInfo.GetGroupCard()
|
||||
}
|
||||
ret.Nodes = append(ret.Nodes, &message.ForwardNode{
|
||||
SenderId: m.Head.GetFromUin(),
|
||||
SenderName: name,
|
||||
Time: m.Head.GetMsgTime(),
|
||||
Message: message.ParseMessageElems(m.Body.RichText.Elems),
|
||||
})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *QQClient) DownloadForwardMessage(resId string) *message.ForwardElement {
|
||||
i, err := c.sendAndWait(c.buildMultiApplyDownPacket(resId))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
multiMsg := i.(*msg.PbMultiMsgTransmit)
|
||||
if multiMsg.GetPbItemList() == nil {
|
||||
return nil
|
||||
}
|
||||
var pv string
|
||||
for i := 0; i < int(math.Min(4, float64(len(multiMsg.GetMsg())))); i++ {
|
||||
m := multiMsg.Msg[i]
|
||||
pv += fmt.Sprintf(`<title size="26" color="#777777">%s: %s</title>`,
|
||||
func() string {
|
||||
if m.Head.GetMsgType() == 82 && m.Head.GroupInfo != nil {
|
||||
return m.Head.GroupInfo.GetGroupCard()
|
||||
}
|
||||
return m.Head.GetFromNick()
|
||||
}(),
|
||||
message.ToReadableString(
|
||||
message.ParseMessageElems(multiMsg.Msg[i].GetBody().GetRichText().Elems),
|
||||
),
|
||||
)
|
||||
}
|
||||
return genForwardTemplate(
|
||||
resId, pv, "群聊的聊天记录", "[聊天记录]", "聊天记录",
|
||||
fmt.Sprintf("查看 %d 条转发消息", len(multiMsg.GetMsg())),
|
||||
time.Now().UnixNano(),
|
||||
multiMsg.GetPbItemList(),
|
||||
)
|
||||
}
|
||||
|
||||
func (c *QQClient) SendGroupPoke(groupCode, target int64) {
|
||||
_, _ = c.sendAndWait(c.buildGroupPokePacket(groupCode, target))
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
@ -11,6 +13,7 @@ import (
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/multimsg"
|
||||
"github.com/Mrs4s/MiraiGo/internal/packets"
|
||||
"github.com/Mrs4s/MiraiGo/internal/proto"
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
)
|
||||
|
||||
@ -132,3 +135,84 @@ func decodeMultiApplyDownResponse(_ *QQClient, _ *incomingPacketInfo, payload []
|
||||
}
|
||||
return &mt, nil
|
||||
}
|
||||
|
||||
type forwardMsgLinker struct {
|
||||
items map[string]*msg.PbMultiMsgItem
|
||||
}
|
||||
|
||||
func (l *forwardMsgLinker) link(name string) *message.ForwardMessage {
|
||||
item := l.items[name]
|
||||
if item == nil {
|
||||
return nil
|
||||
}
|
||||
nodes := make([]*message.ForwardNode, 0, len(item.GetBuffer().GetMsg()))
|
||||
for _, m := range item.GetBuffer().GetMsg() {
|
||||
name := m.Head.GetFromNick()
|
||||
if m.Head.GetMsgType() == 82 && m.Head.GroupInfo != nil {
|
||||
name = m.Head.GroupInfo.GetGroupCard()
|
||||
}
|
||||
|
||||
msgElems := message.ParseMessageElems(m.Body.RichText.Elems)
|
||||
for i, elem := range msgElems {
|
||||
if forward, ok := elem.(*message.ForwardElement); ok {
|
||||
if forward.FileName != "" {
|
||||
msgElems[i] = l.link(forward.FileName) // 递归处理嵌套转发
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodes = append(nodes, &message.ForwardNode{
|
||||
SenderId: m.Head.GetFromUin(),
|
||||
SenderName: name,
|
||||
Time: m.Head.GetMsgTime(),
|
||||
Message: msgElems,
|
||||
})
|
||||
}
|
||||
return &message.ForwardMessage{Nodes: nodes}
|
||||
}
|
||||
|
||||
func (c *QQClient) GetForwardMessage(resID string) *message.ForwardMessage {
|
||||
m := c.DownloadForwardMessage(resID)
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
linker := forwardMsgLinker{
|
||||
items: make(map[string]*msg.PbMultiMsgItem),
|
||||
}
|
||||
for _, item := range m.Items {
|
||||
linker.items[item.GetFileName()] = item
|
||||
}
|
||||
return linker.link(m.FileName)
|
||||
}
|
||||
|
||||
func (c *QQClient) DownloadForwardMessage(resId string) *message.ForwardElement {
|
||||
i, err := c.sendAndWait(c.buildMultiApplyDownPacket(resId))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
multiMsg := i.(*msg.PbMultiMsgTransmit)
|
||||
if multiMsg.GetPbItemList() == nil {
|
||||
return nil
|
||||
}
|
||||
var pv string
|
||||
for i := 0; i < int(math.Min(4, float64(len(multiMsg.GetMsg())))); i++ {
|
||||
m := multiMsg.Msg[i]
|
||||
pv += fmt.Sprintf(`<title size="26" color="#777777">%s: %s</title>`,
|
||||
func() string {
|
||||
if m.Head.GetMsgType() == 82 && m.Head.GroupInfo != nil {
|
||||
return m.Head.GroupInfo.GetGroupCard()
|
||||
}
|
||||
return m.Head.GetFromNick()
|
||||
}(),
|
||||
message.ToReadableString(
|
||||
message.ParseMessageElems(multiMsg.Msg[i].GetBody().GetRichText().Elems),
|
||||
),
|
||||
)
|
||||
}
|
||||
return genForwardTemplate(
|
||||
resId, pv, "群聊的聊天记录", "[聊天记录]", "聊天记录",
|
||||
fmt.Sprintf("查看 %d 条转发消息", len(multiMsg.GetMsg())),
|
||||
time.Now().UnixNano(),
|
||||
multiMsg.GetPbItemList(),
|
||||
)
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package message
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||
@ -34,6 +36,10 @@ type ForwardElement struct {
|
||||
|
||||
// *----- Implementations -----* //
|
||||
|
||||
func (f *ForwardMessage) Type() ElementType {
|
||||
return Forward
|
||||
}
|
||||
|
||||
// Type impl IMessageElement
|
||||
func (e *ForwardElement) Type() ElementType {
|
||||
return Forward
|
||||
@ -161,3 +167,36 @@ func (f *ForwardMessage) packForwardMsg(seq int32, random int32, groupCode int64
|
||||
}
|
||||
return ml
|
||||
}
|
||||
|
||||
type lazyRegex struct {
|
||||
once sync.Once
|
||||
reg *regexp.Regexp
|
||||
Pattern string
|
||||
}
|
||||
|
||||
func (l *lazyRegex) init() {
|
||||
l.reg = regexp.MustCompile(l.Pattern)
|
||||
}
|
||||
|
||||
func (l *lazyRegex) findMatch1(content string) string {
|
||||
l.once.Do(l.init)
|
||||
matches := l.reg.FindStringSubmatch(content)
|
||||
if matches == nil {
|
||||
return ""
|
||||
}
|
||||
return matches[1]
|
||||
}
|
||||
|
||||
var (
|
||||
mResID = lazyRegex{Pattern: `m_resid="(.*?)"`}
|
||||
mFileName = lazyRegex{Pattern: `m_fileName="(.*?)"`}
|
||||
)
|
||||
|
||||
func forwardMsgFromXML(xml string) *ForwardElement {
|
||||
resid := mResID.findMatch1(xml)
|
||||
fileName := mFileName.findMatch1(xml)
|
||||
if resid == "" && fileName == "" {
|
||||
return nil
|
||||
}
|
||||
return &ForwardElement{FileName: fileName, ResId: resid}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package message
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -415,10 +414,9 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement {
|
||||
}
|
||||
if content != "" {
|
||||
if elem.RichMsg.GetServiceId() == 35 {
|
||||
reg := regexp.MustCompile(`m_resid="(.*?)"`)
|
||||
sub := reg.FindAllStringSubmatch(content, -1)
|
||||
if len(sub) > 0 && len(sub[0]) > 1 {
|
||||
res = append(res, &ForwardElement{ResId: reg.FindAllStringSubmatch(content, -1)[0][1]})
|
||||
elem := forwardMsgFromXML(content)
|
||||
if elem != nil {
|
||||
res = append(res, elem)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user