1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

add func: GetForwardMessage().

This commit is contained in:
Mrs4s 2020-07-27 03:52:38 +08:00
parent 1561cf25a4
commit 21befc2052
5 changed files with 118 additions and 2 deletions

View File

@ -18,7 +18,7 @@ qq-android协议的golang实现 移植于Mirai
- [x] At - [x] At
- [x] 回复 - [x] 回复
- [ ] 长消息 - [ ] 长消息
- [x] 合并转发(有待测试) - [x] 合并转发(只能接收, 发送还有问题)
#### 事件 #### 事件
- [x] 好友消息 - [x] 好友消息

View File

@ -856,3 +856,26 @@ func (c *QQClient) buildMultiApplyUpPacket(data, hash []byte, groupUin int64) (u
packet := packets.BuildUniPacket(c.Uin, seq, "MultiMsg.ApplyUp", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload) packet := packets.BuildUniPacket(c.Uin, seq, "MultiMsg.ApplyUp", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet return seq, packet
} }
// MultiMsg.ApplyDown
func (c *QQClient) buildMultiApplyDownPacket(resId string) (uint16, []byte) {
seq := c.nextSeq()
req := &multimsg.MultiReqBody{
Subcmd: 2,
TermType: 5,
PlatformType: 9,
NetType: 3,
BuildVer: "8.2.0.1296",
MultimsgApplydownReq: []*multimsg.MultiMsgApplyDownReq{
{
MsgResid: []byte(resId),
MsgType: 3,
},
},
BuType: 2,
ReqChannelType: 2,
}
payload, _ := proto.Marshal(req)
packet := packets.BuildUniPacket(c.Uin, seq, "MultiMsg.ApplyDown", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}

View File

@ -118,6 +118,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
"ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket, "ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
"ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket, "ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket,
"MultiMsg.ApplyUp": decodeMultiApplyUpResponse, "MultiMsg.ApplyUp": decodeMultiApplyUpResponse,
"MultiMsg.ApplyDown": decodeMultiApplyDownResponse,
}, },
handlers: map[uint16]func(interface{}, error){}, handlers: map[uint16]func(interface{}, error){},
sigInfo: &loginSigInfo{}, sigInfo: &loginSigInfo{},
@ -257,7 +258,30 @@ func (c *QQClient) SendPrivateMessage(target int64, m *message.SendingMessage) *
} }
} }
// 目前似乎iOS端无法正常打开转发消息经测试数据上传正常应该是解析问题。iOS目前没有越狱设备抓不到日志有空再测试。 func (c *QQClient) GetForwardMessage(resId string) *message.ForwardMessage {
i, err := c.sendAndWait(c.buildMultiApplyDownPacket(resId))
if err != nil {
return nil
}
multiMsg := i.(*msg.PbMultiMsgTransmit)
ret := &message.ForwardMessage{}
for _, m := range multiMsg.Msg {
ret.Nodes = append(ret.Nodes, &message.ForwardNode{
SenderId: m.Head.FromUin,
SenderName: func() string {
if m.Head.MsgType == 82 {
return m.Head.GroupInfo.GroupCard
}
return m.Head.FromNick
}(),
Time: m.Head.MsgTime,
Message: message.ParseMessageElems(m.Body.RichText.Elems),
})
}
return ret
}
// 目前手机端无法解析,可能是加密的问题,等待修复
func (c *QQClient) SendForwardMessage(groupCode int64, m *message.ForwardMessage) *message.GroupMessage { func (c *QQClient) SendForwardMessage(groupCode int64, m *message.ForwardMessage) *message.GroupMessage {
if len(m.Nodes) >= 200 { if len(m.Nodes) >= 200 {
return nil return nil

View File

@ -2,13 +2,16 @@ package client
import ( import (
"errors" "errors"
"fmt"
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/binary/jce" "github.com/Mrs4s/MiraiGo/binary/jce"
"github.com/Mrs4s/MiraiGo/client/pb" "github.com/Mrs4s/MiraiGo/client/pb"
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352" "github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
"github.com/Mrs4s/MiraiGo/client/pb/longmsg"
"github.com/Mrs4s/MiraiGo/client/pb/msg" "github.com/Mrs4s/MiraiGo/client/pb/msg"
"github.com/Mrs4s/MiraiGo/client/pb/multimsg" "github.com/Mrs4s/MiraiGo/client/pb/multimsg"
"github.com/Mrs4s/MiraiGo/client/pb/structmsg" "github.com/Mrs4s/MiraiGo/client/pb/structmsg"
"github.com/Mrs4s/MiraiGo/utils"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -686,3 +689,37 @@ func decodeMultiApplyUpResponse(c *QQClient, _ uint16, payload []byte) (interfac
} }
return nil, errors.New("failed") return nil, errors.New("failed")
} }
func decodeMultiApplyDownResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
body := multimsg.MultiRspBody{}
if err := proto.Unmarshal(payload, &body); err != nil {
return nil, err
}
if len(body.MultimsgApplydownRsp) == 0 {
return nil, errors.New("not found")
}
rsp := body.MultimsgApplydownRsp[0]
i := binary.UInt32ToIPV4Address(uint32(rsp.Uint32DownIp[0]))
b, err := utils.HttpGetBytes(fmt.Sprintf("http://%s:%d%s", i, body.MultimsgApplydownRsp[0].Uint32DownPort[0], string(rsp.ThumbDownPara)))
if err != nil {
return nil, err
}
tea := binary.NewTeaCipher(body.MultimsgApplydownRsp[0].MsgKey)
r := binary.NewReader(b[1:])
i1 := r.ReadInt32()
i2 := r.ReadInt32()
if i1 > 0 {
r.ReadBytes(int(i1)) // highway head
}
data := tea.Decrypt(r.ReadBytes(int(i2)))
lb := longmsg.LongRspBody{}
if err = proto.Unmarshal(data, &lb); err != nil {
return nil, err
}
uc := binary.GZipUncompress(lb.MsgDownRsp[0].MsgContent)
mt := msg.PbMultiMsgTransmit{}
if err = proto.Unmarshal(uc, &mt); err != nil {
return nil, err
}
return &mt, nil
}

32
utils/http.go Normal file
View File

@ -0,0 +1,32 @@
package utils
import (
"bytes"
"compress/gzip"
"io/ioutil"
"net/http"
"strings"
)
func HttpGetBytes(url string) ([]byte, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if strings.Contains(resp.Header.Get("Content-Encoding"), "gzip") {
buffer := bytes.NewBuffer(body)
r, _ := gzip.NewReader(buffer)
unCom, err := ioutil.ReadAll(r)
return unCom, err
}
return body, nil
}