mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
feat: link nested forward message
This commit is contained in:
parent
a5410846cb
commit
dc66c61d57
@ -3,7 +3,6 @@ package client
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"sort"
|
"sort"
|
||||||
@ -19,7 +18,6 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/crypto"
|
"github.com/Mrs4s/MiraiGo/internal/crypto"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/packets"
|
"github.com/Mrs4s/MiraiGo/internal/packets"
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -546,68 +544,6 @@ func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
|
|||||||
return r, nil
|
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) {
|
func (c *QQClient) SendGroupPoke(groupCode, target int64) {
|
||||||
_, _ = c.sendAndWait(c.buildGroupPokePacket(groupCode, target))
|
_, _ = c.sendAndWait(c.buildGroupPokePacket(groupCode, target))
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
@ -11,6 +13,7 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/client/pb/multimsg"
|
"github.com/Mrs4s/MiraiGo/client/pb/multimsg"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/packets"
|
"github.com/Mrs4s/MiraiGo/internal/packets"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/proto"
|
"github.com/Mrs4s/MiraiGo/internal/proto"
|
||||||
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -132,3 +135,84 @@ func decodeMultiApplyDownResponse(_ *QQClient, _ *incomingPacketInfo, payload []
|
|||||||
}
|
}
|
||||||
return &mt, nil
|
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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
|
"regexp"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
@ -34,6 +36,10 @@ type ForwardElement struct {
|
|||||||
|
|
||||||
// *----- Implementations -----* //
|
// *----- Implementations -----* //
|
||||||
|
|
||||||
|
func (f *ForwardMessage) Type() ElementType {
|
||||||
|
return Forward
|
||||||
|
}
|
||||||
|
|
||||||
// Type impl IMessageElement
|
// Type impl IMessageElement
|
||||||
func (e *ForwardElement) Type() ElementType {
|
func (e *ForwardElement) Type() ElementType {
|
||||||
return Forward
|
return Forward
|
||||||
@ -161,3 +167,36 @@ func (f *ForwardMessage) packForwardMsg(seq int32, random int32, groupCode int64
|
|||||||
}
|
}
|
||||||
return ml
|
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 (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -415,10 +414,9 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement {
|
|||||||
}
|
}
|
||||||
if content != "" {
|
if content != "" {
|
||||||
if elem.RichMsg.GetServiceId() == 35 {
|
if elem.RichMsg.GetServiceId() == 35 {
|
||||||
reg := regexp.MustCompile(`m_resid="(.*?)"`)
|
elem := forwardMsgFromXML(content)
|
||||||
sub := reg.FindAllStringSubmatch(content, -1)
|
if elem != nil {
|
||||||
if len(sub) > 0 && len(sub[0]) > 1 {
|
res = append(res, elem)
|
||||||
res = append(res, &ForwardElement{ResId: reg.FindAllStringSubmatch(content, -1)[0][1]})
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user