Skip to content

Commit

Permalink
client: refactor forward message api
Browse files Browse the repository at this point in the history
  • Loading branch information
wdvxdr1123 committed Mar 21, 2022
1 parent 38990f6 commit 8b86fe4
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 56 deletions.
5 changes: 0 additions & 5 deletions client/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
28 changes: 0 additions & 28 deletions client/group_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
"math"
"math/rand"
"strconv"
Expand Down Expand Up @@ -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 {
Expand Down
83 changes: 83 additions & 0 deletions client/multimsg.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}
26 changes: 3 additions & 23 deletions message/forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ import (

// *----- Definitions -----* //

// ForwardMessage 添加 Node 请用 AddNode 方法
// ForwardMessage 合并转发消息
type ForwardMessage struct {
Nodes []*ForwardNode
items []*msg.PbMultiMsgItem
}

type ForwardNode struct {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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"),
Expand All @@ -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{
Expand Down

0 comments on commit 8b86fe4

Please sign in to comment.