mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
client: refactor forward message api
This commit is contained in:
parent
38990f6e1c
commit
8b86fe4d9c
@ -296,11 +296,6 @@ func packUniRequestData(data []byte) []byte {
|
||||
|
||||
func genForwardTemplate(resID, preview, summary string, ts int64, items []*msg.PbMultiMsgItem) *message.ForwardElement {
|
||||
template := forwardDisplay(resID, strconv.FormatInt(ts, 10), preview, summary)
|
||||
for _, item := range items {
|
||||
if item.GetFileName() == "MultiMsg" {
|
||||
*item.FileName = strconv.FormatInt(ts, 10)
|
||||
}
|
||||
}
|
||||
return &message.ForwardElement{
|
||||
FileName: strconv.FormatInt(ts, 10),
|
||||
Content: template,
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
@ -186,33 +185,6 @@ func (c *QQClient) uploadGroupLongMessage(groupCode int64, m *message.ForwardMes
|
||||
return nil, errors.New("upload long message error: highway server list is empty or not available server.")
|
||||
}
|
||||
|
||||
func (c *QQClient) UploadGroupForwardMessage(groupCode int64, m *message.ForwardMessage) *message.ForwardElement {
|
||||
if m.Length() > 200 {
|
||||
return nil
|
||||
}
|
||||
ts := time.Now().UnixNano()
|
||||
seq := c.nextGroupSeq()
|
||||
data, hash, items := m.CalculateValidationDataForward(seq, rand.Int31(), groupCode)
|
||||
rsp, body, err := c.multiMsgApplyUp(groupCode, data, hash, 2)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
for i, ip := range rsp.Uint32UpIp {
|
||||
addr := highway.Addr{IP: uint32(ip), Port: int(rsp.Uint32UpPort[i])}
|
||||
input := highway.Input{
|
||||
CommandID: 27,
|
||||
Key: rsp.MsgSig,
|
||||
Body: bytes.NewReader(body),
|
||||
}
|
||||
err := c.highwaySession.Upload(addr, input)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return genForwardTemplate(rsp.MsgResid, m.Preview(), fmt.Sprintf("查看 %d 条转发消息", m.Length()), ts, items)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *QQClient) multiMsgApplyUp(groupCode int64, data []byte, hash []byte, buType int32) (*multimsg.MultiMsgApplyUpRsp, []byte, error) {
|
||||
i, err := c.sendAndWait(c.buildMultiApplyUpPacket(data, hash, buType, utils.ToGroupUin(groupCode)))
|
||||
if err != nil {
|
||||
|
@ -2,14 +2,18 @@ package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"github.com/Mrs4s/MiraiGo/client/internal/highway"
|
||||
"github.com/Mrs4s/MiraiGo/client/internal/network"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/longmsg"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||
@ -228,3 +232,82 @@ func forwardDisplay(resID, fileName, preview, summary string) string {
|
||||
sb.WriteString(`</summary></item><source name="聊天记录"></source></msg>`)
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func (c *QQClient) NewForwardMessageBuilder(groupCode int64) *ForwardMessageBuilder {
|
||||
return &ForwardMessageBuilder{
|
||||
c: c,
|
||||
groupCode: groupCode,
|
||||
}
|
||||
}
|
||||
|
||||
type ForwardMessageBuilder struct {
|
||||
c *QQClient
|
||||
groupCode int64
|
||||
objs []*msg.PbMultiMsgItem
|
||||
}
|
||||
|
||||
// NestedNode 返回一个嵌套转发节点,其内容将会被 Builder 重定位
|
||||
func (builder *ForwardMessageBuilder) NestedNode() *message.ForwardElement {
|
||||
filename := strconv.FormatInt(time.Now().UnixNano(), 10) // 大概率不会重复
|
||||
return &message.ForwardElement{FileName: filename}
|
||||
}
|
||||
|
||||
// Link 将真实的消息内容填充 reloc
|
||||
func (builder *ForwardMessageBuilder) Link(reloc *message.ForwardElement, fmsg *message.ForwardMessage) {
|
||||
seq := builder.c.nextGroupSeq()
|
||||
m := fmsg.PackForwardMessage(seq, rand.Int31(), builder.groupCode)
|
||||
builder.objs = append(builder.objs, &msg.PbMultiMsgItem{
|
||||
FileName: proto.String(reloc.FileName),
|
||||
Buffer: &msg.PbMultiMsgNew{
|
||||
Msg: m,
|
||||
},
|
||||
})
|
||||
reloc.Content = forwardDisplay("", reloc.FileName, fmsg.Preview(), fmt.Sprintf("查看 %d 条转发消息", fmsg.Length()))
|
||||
}
|
||||
|
||||
// Main 最外层的转发消息, 调用该方法后即上传消息
|
||||
func (builder *ForwardMessageBuilder) Main(m *message.ForwardMessage) *message.ForwardElement {
|
||||
if m.Length() > 200 {
|
||||
return nil
|
||||
}
|
||||
c := builder.c
|
||||
seq := c.nextGroupSeq()
|
||||
fm := m.PackForwardMessage(seq, rand.Int31(), builder.groupCode)
|
||||
const filename = "MultiMsg"
|
||||
builder.objs = append(builder.objs, &msg.PbMultiMsgItem{
|
||||
FileName: proto.String(filename),
|
||||
Buffer: &msg.PbMultiMsgNew{
|
||||
Msg: fm,
|
||||
},
|
||||
})
|
||||
trans := &msg.PbMultiMsgTransmit{
|
||||
Msg: fm,
|
||||
PbItemList: builder.objs,
|
||||
}
|
||||
b, _ := proto.Marshal(trans)
|
||||
data := binary.GZipCompress(b)
|
||||
hash := md5.Sum(data)
|
||||
rsp, body, err := c.multiMsgApplyUp(builder.groupCode, data, hash[:], 2)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
content := forwardDisplay(rsp.MsgResid, filename, m.Preview(), fmt.Sprintf("查看 %d 条转发消息", m.Length()))
|
||||
for i, ip := range rsp.Uint32UpIp {
|
||||
addr := highway.Addr{IP: uint32(ip), Port: int(rsp.Uint32UpPort[i])}
|
||||
input := highway.Input{
|
||||
CommandID: 27,
|
||||
Key: rsp.MsgSig,
|
||||
Body: bytes.NewReader(body),
|
||||
}
|
||||
err := c.highwaySession.Upload(addr, input)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return &message.ForwardElement{
|
||||
FileName: filename,
|
||||
Content: content,
|
||||
ResId: rsp.MsgResid,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -14,10 +14,9 @@ import (
|
||||
|
||||
// *----- Definitions -----* //
|
||||
|
||||
// ForwardMessage 添加 Node 请用 AddNode 方法
|
||||
// ForwardMessage 合并转发消息
|
||||
type ForwardMessage struct {
|
||||
Nodes []*ForwardNode
|
||||
items []*msg.PbMultiMsgItem
|
||||
}
|
||||
|
||||
type ForwardNode struct {
|
||||
@ -72,9 +71,6 @@ func (f *ForwardMessage) AddNode(node *ForwardNode) *ForwardMessage {
|
||||
if item.Type() != Forward { // quick path
|
||||
continue
|
||||
}
|
||||
if forward, ok := item.(*ForwardElement); ok {
|
||||
f.items = append(f.items, forward.Items...)
|
||||
}
|
||||
}
|
||||
return f
|
||||
}
|
||||
@ -109,7 +105,7 @@ func (f *ForwardMessage) Preview() string {
|
||||
}
|
||||
|
||||
func (f *ForwardMessage) CalculateValidationData(seq, random int32, groupCode int64) ([]byte, []byte) {
|
||||
msgs := f.packForwardMsg(seq, random, groupCode)
|
||||
msgs := f.PackForwardMessage(seq, random, groupCode)
|
||||
trans := &msg.PbMultiMsgTransmit{Msg: msgs, PbItemList: []*msg.PbMultiMsgItem{
|
||||
{
|
||||
FileName: proto.String("MultiMsg"),
|
||||
@ -122,23 +118,7 @@ func (f *ForwardMessage) CalculateValidationData(seq, random int32, groupCode in
|
||||
return data, hash[:]
|
||||
}
|
||||
|
||||
// CalculateValidationDataForward 屎代码
|
||||
func (f *ForwardMessage) CalculateValidationDataForward(seq, random int32, groupCode int64) ([]byte, []byte, []*msg.PbMultiMsgItem) {
|
||||
msgs := f.packForwardMsg(seq, random, groupCode)
|
||||
trans := &msg.PbMultiMsgTransmit{Msg: msgs, PbItemList: []*msg.PbMultiMsgItem{
|
||||
{
|
||||
FileName: proto.String("MultiMsg"),
|
||||
Buffer: &msg.PbMultiMsgNew{Msg: msgs},
|
||||
},
|
||||
}}
|
||||
trans.PbItemList = append(trans.PbItemList, f.items...)
|
||||
b, _ := proto.Marshal(trans)
|
||||
data := binary.GZipCompress(b)
|
||||
hash := md5.Sum(data)
|
||||
return data, hash[:], trans.PbItemList
|
||||
}
|
||||
|
||||
func (f *ForwardMessage) packForwardMsg(seq int32, random int32, groupCode int64) []*msg.Message {
|
||||
func (f *ForwardMessage) PackForwardMessage(seq int32, random int32, groupCode int64) []*msg.Message {
|
||||
ml := make([]*msg.Message, 0, len(f.Nodes))
|
||||
for _, node := range f.Nodes {
|
||||
ml = append(ml, &msg.Message{
|
||||
|
Loading…
x
Reference in New Issue
Block a user