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

feat: more temp session source support & consulting source message sending. close #142

This commit is contained in:
Mrs4s 2021-04-06 17:30:51 +08:00
parent dd7898c204
commit 5faec8678d
10 changed files with 1556 additions and 1327 deletions

View File

@ -29,6 +29,30 @@ var c2cDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){
529: msgType0x211Decoder, 529: msgType0x211Decoder,
} }
type (
TempSessionInfo struct {
Source TempSessionSource
GroupCode int64
Sender int64
sig []byte
client *QQClient
}
TempSessionSource int
)
const (
GroupSource TempSessionSource = 0 // 来自群聊
ConsultingSource TempSessionSource = 1 // 来自QQ咨询
SearchSource TempSessionSource = 2 // 来自查找
MovieSource TempSessionSource = 3 // 来自QQ电影
HotChatSource TempSessionSource = 4 // 来自热聊
SystemMessageSource TempSessionSource = 6 // 来自验证消息
MultiChatSource TempSessionSource = 7 // 来自多人聊天
DateSource TempSessionSource = 8 // 来自约会
AddressBookSource TempSessionSource = 9 // 来自通讯录
)
func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *incomingPacketInfo) { func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *incomingPacketInfo) {
c.syncCookie = rsp.SyncCookie c.syncCookie = rsp.SyncCookie
c.pubAccountCookie = rsp.PubAccountCookie c.pubAccountCookie = rsp.PubAccountCookie
@ -128,14 +152,59 @@ func tempSessionDecoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) {
return return
} }
if (pMsg.Head.GetMsgType() == 529 && pMsg.Head.GetC2CCmd() == 6) || pMsg.Body.RichText != nil { if (pMsg.Head.GetMsgType() == 529 && pMsg.Head.GetC2CCmd() == 6) || pMsg.Body.RichText != nil {
group := c.FindGroup(pMsg.Head.C2CTmpMsgHead.GetGroupCode()) genTempSessionInfo := func() *TempSessionInfo {
if group == nil { if pMsg.Head.C2CTmpMsgHead.GetServiceType() == 0 {
group := c.FindGroup(pMsg.Head.C2CTmpMsgHead.GetGroupCode())
if group == nil {
return nil
}
return &TempSessionInfo{
Source: GroupSource,
GroupCode: group.Code,
Sender: pMsg.Head.GetFromUin(),
client: c,
}
}
info := &TempSessionInfo{
Source: 0,
Sender: pMsg.Head.GetFromUin(),
sig: pMsg.Head.C2CTmpMsgHead.GetSig(),
client: c,
}
switch pMsg.Head.C2CTmpMsgHead.GetServiceType() {
case 1:
info.Source = MultiChatSource
case 130:
info.Source = AddressBookSource
case 132:
info.Source = HotChatSource
case 134:
info.Source = SystemMessageSource
case 201:
info.Source = ConsultingSource
default:
return nil
}
return info
}
session := genTempSessionInfo()
if session == nil {
return return
} }
/*
group := c.FindGroup(pMsg.Head.C2CTmpMsgHead.GetGroupCode())
if group == nil {
return
}
*/
if pMsg.Head.GetFromUin() == c.Uin { if pMsg.Head.GetFromUin() == c.Uin {
return return
} }
c.dispatchTempMessage(c.parseTempMessage(pMsg)) c.dispatchTempMessage(&TempMessageEvent{
Message: c.parseTempMessage(pMsg),
Session: session,
})
} }
} }
@ -165,7 +234,7 @@ func troopAddMemberBroadcastDecoder(c *QQClient, pMsg *msg.Message, _ *incomingP
} }
} }
func systemMessageDecoder(c *QQClient, pMsg *msg.Message, _ *incomingPacketInfo) { func systemMessageDecoder(c *QQClient, _ *msg.Message, _ *incomingPacketInfo) {
_, pkt := c.buildSystemMsgNewFriendPacket() _, pkt := c.buildSystemMsgNewFriendPacket()
_ = c.send(pkt) _ = c.send(pkt)
} }

View File

@ -407,7 +407,7 @@ func (c *QQClient) init() {
c.stat.MessageReceived++ c.stat.MessageReceived++
c.stat.LastMessageTime = time.Now().Unix() c.stat.LastMessageTime = time.Now().Unix()
}) })
c.OnTempMessage(func(_ *QQClient, _ *message.TempMessage) { c.OnTempMessage(func(_ *QQClient, _ *TempMessageEvent) {
c.stat.MessageReceived++ c.stat.MessageReceived++
c.stat.LastMessageTime = time.Now().Unix() c.stat.LastMessageTime = time.Now().Unix()
}) })

View File

@ -114,6 +114,11 @@ type (
Time int64 Time int64
} }
TempMessageEvent struct {
Message *message.TempMessage
Session *TempSessionInfo
}
GroupLeaveEvent struct { GroupLeaveEvent struct {
Group *GroupInfo Group *GroupInfo
Operator *GroupMemberInfo Operator *GroupMemberInfo

View File

@ -10,7 +10,7 @@ import (
type eventHandlers struct { type eventHandlers struct {
privateMessageHandlers []func(*QQClient, *message.PrivateMessage) privateMessageHandlers []func(*QQClient, *message.PrivateMessage)
tempMessageHandlers []func(*QQClient, *message.TempMessage) tempMessageHandlers []func(*QQClient, *TempMessageEvent)
groupMessageHandlers []func(*QQClient, *message.GroupMessage) groupMessageHandlers []func(*QQClient, *message.GroupMessage)
selfPrivateMessageHandlers []func(*QQClient, *message.PrivateMessage) selfPrivateMessageHandlers []func(*QQClient, *message.PrivateMessage)
selfGroupMessageHandlers []func(*QQClient, *message.GroupMessage) selfGroupMessageHandlers []func(*QQClient, *message.GroupMessage)
@ -51,7 +51,7 @@ func (c *QQClient) OnPrivateMessageF(filter func(*message.PrivateMessage) bool,
}) })
} }
func (c *QQClient) OnTempMessage(f func(*QQClient, *message.TempMessage)) { func (c *QQClient) OnTempMessage(f func(*QQClient, *TempMessageEvent)) {
c.eventHandlers.tempMessageHandlers = append(c.eventHandlers.tempMessageHandlers, f) c.eventHandlers.tempMessageHandlers = append(c.eventHandlers.tempMessageHandlers, f)
} }
@ -181,13 +181,13 @@ func (c *QQClient) dispatchPrivateMessage(msg *message.PrivateMessage) {
} }
} }
func (c *QQClient) dispatchTempMessage(msg *message.TempMessage) { func (c *QQClient) dispatchTempMessage(e *TempMessageEvent) {
if msg == nil { if e == nil {
return return
} }
for _, f := range c.eventHandlers.tempMessageHandlers { for _, f := range c.eventHandlers.tempMessageHandlers {
cover(func() { cover(func() {
f(c, msg) f(c, e)
}) })
} }
} }

View File

@ -510,21 +510,27 @@ func (c *QQClient) parsePrivateMessage(msg *msg.Message) *message.PrivateMessage
} }
func (c *QQClient) parseTempMessage(msg *msg.Message) *message.TempMessage { func (c *QQClient) parseTempMessage(msg *msg.Message) *message.TempMessage {
var groupCode int64
var groupName string
group := c.FindGroupByUin(msg.Head.C2CTmpMsgHead.GetGroupUin()) group := c.FindGroupByUin(msg.Head.C2CTmpMsgHead.GetGroupUin())
mem := group.FindMember(msg.Head.GetFromUin())
sender := &message.Sender{ sender := &message.Sender{
Uin: msg.Head.GetFromUin(), Uin: msg.Head.GetFromUin(),
Nickname: "Unknown", Nickname: "Unknown",
IsFriend: false, IsFriend: false,
} }
if mem != nil { if group != nil {
sender.Nickname = mem.Nickname groupCode = group.Code
sender.CardName = mem.CardName groupName = group.Name
mem := group.FindMember(msg.Head.GetFromUin())
if mem != nil {
sender.Nickname = mem.Nickname
sender.CardName = mem.CardName
}
} }
return &message.TempMessage{ return &message.TempMessage{
Id: msg.Head.GetMsgSeq(), Id: msg.Head.GetMsgSeq(),
GroupCode: group.Code, GroupCode: groupCode,
GroupName: group.Name, GroupName: groupName,
Self: c.Uin, Self: c.Uin,
Sender: sender, Sender: sender,
Elements: message.ParseMessageElems(msg.Body.RichText.Elems), Elements: message.ParseMessageElems(msg.Body.RichText.Elems),

File diff suppressed because it is too large Load Diff

View File

@ -98,10 +98,10 @@ message RoutingHead {
optional C2C c2c = 1; optional C2C c2c = 1;
optional Grp grp = 2; optional Grp grp = 2;
optional GrpTmp grpTmp = 3; optional GrpTmp grpTmp = 3;
optional WPATmp wpaTmp = 6;
/* /*
Dis dis = 4; Dis dis = 4;
DisTmp disTmp = 5; DisTmp disTmp = 5;
WPATmp? wpaTmp = 6;
SecretFileHead? secretFile = 7; SecretFileHead? secretFile = 7;
PublicPlat? publicPlat = 8; PublicPlat? publicPlat = 8;
TransMsg? transMsg = 9; TransMsg? transMsg = 9;
@ -121,6 +121,11 @@ message RoutingHead {
*/ */
} }
message WPATmp {
optional uint64 toUin = 1;
optional bytes sig = 2;
}
message C2C { message C2C {
optional int64 toUin = 1; optional int64 toUin = 1;
} }

View File

@ -1,18 +1,17 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.23.0
// protoc v3.14.0 // protoc v3.14.0
// source: objmsg.proto // source: objmsg.proto
package msg package msg
import ( import (
reflect "reflect"
sync "sync"
proto "github.com/golang/protobuf/proto" proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
) )
const ( const (

View File

@ -1,18 +1,17 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.23.0
// protoc v3.14.0 // protoc v3.14.0
// source: report.proto // source: report.proto
package msg package msg
import ( import (
reflect "reflect"
sync "sync"
proto "github.com/golang/protobuf/proto" proto "github.com/golang/protobuf/proto"
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
) )
const ( const (

View File

@ -1,6 +1,7 @@
package client package client
import ( import (
"github.com/pkg/errors"
"math/rand" "math/rand"
"time" "time"
@ -48,7 +49,7 @@ func (c *QQClient) SendPrivateMessage(target int64, m *message.SendingMessage) *
return ret return ret
} }
func (c *QQClient) SendTempMessage(groupCode, target int64, m *message.SendingMessage) *message.TempMessage { func (c *QQClient) SendGroupTempMessage(groupCode, target int64, m *message.SendingMessage) *message.TempMessage {
group := c.FindGroup(groupCode) group := c.FindGroup(groupCode)
if group == nil { if group == nil {
return nil return nil
@ -67,7 +68,7 @@ func (c *QQClient) SendTempMessage(groupCode, target int64, m *message.SendingMe
mr := int32(rand.Uint32()) mr := int32(rand.Uint32())
seq := c.nextFriendSeq() seq := c.nextFriendSeq()
t := time.Now().Unix() t := time.Now().Unix()
_, pkt := c.buildTempSendingPacket(group.Uin, target, seq, mr, t, m) _, pkt := c.buildGroupTempSendingPacket(group.Uin, target, seq, mr, t, m)
_ = c.send(pkt) _ = c.send(pkt)
c.stat.MessageSent++ c.stat.MessageSent++
return &message.TempMessage{ return &message.TempMessage{
@ -84,6 +85,36 @@ func (c *QQClient) SendTempMessage(groupCode, target int64, m *message.SendingMe
} }
} }
func (c *QQClient) sendWPATempMessage(target int64, sig []byte, m *message.SendingMessage) *message.TempMessage {
mr := int32(rand.Uint32())
seq := c.nextFriendSeq()
t := time.Now().Unix()
_, pkt := c.buildWPATempSendingPacket(target, sig, seq, mr, t, m)
_ = c.send(pkt)
c.stat.MessageSent++
return &message.TempMessage{
Id: seq,
Self: c.Uin,
Sender: &message.Sender{
Uin: c.Uin,
Nickname: c.Nickname,
IsFriend: true,
},
Elements: m.Elements,
}
}
func (s *TempSessionInfo) SendMessage(m *message.SendingMessage) (*message.TempMessage, error) {
switch s.Source {
case GroupSource:
return s.client.SendGroupTempMessage(s.GroupCode, s.Sender, m), nil
case ConsultingSource:
return s.client.sendWPATempMessage(s.Sender, s.sig, m), nil
default:
return nil, errors.New("unsupported message source")
}
}
func (c *QQClient) buildGetOneDayRoamMsgRequest(target, lastMsgTime, random int64, count uint32) (uint16, []byte) { func (c *QQClient) buildGetOneDayRoamMsgRequest(target, lastMsgTime, random int64, count uint32) (uint16, []byte) {
seq := c.nextSeq() seq := c.nextSeq()
req := &msg.PbGetOneDayRoamMsgReq{ req := &msg.PbGetOneDayRoamMsgReq{
@ -137,7 +168,7 @@ func (c *QQClient) buildFriendSendingPacket(target int64, msgSeq, r, pkgNum, pkg
} }
// MessageSvc.PbSendMsg // MessageSvc.PbSendMsg
func (c *QQClient) buildTempSendingPacket(groupUin, target int64, msgSeq, r int32, time int64, m *message.SendingMessage) (uint16, []byte) { func (c *QQClient) buildGroupTempSendingPacket(groupUin, target int64, msgSeq, r int32, time int64, m *message.SendingMessage) (uint16, []byte) {
seq := c.nextSeq() seq := c.nextSeq()
req := &msg.SendMessageRequest{ req := &msg.SendMessageRequest{
RoutingHead: &msg.RoutingHead{GrpTmp: &msg.GrpTmp{ RoutingHead: &msg.RoutingHead{GrpTmp: &msg.GrpTmp{
@ -169,3 +200,36 @@ func (c *QQClient) buildTempSendingPacket(groupUin, target int64, msgSeq, r int3
packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbSendMsg", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload) packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbSendMsg", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet return seq, packet
} }
func (c *QQClient) buildWPATempSendingPacket(uin int64, sig []byte, msgSeq, r int32, time int64, m *message.SendingMessage) (uint16, []byte) {
seq := c.nextSeq()
req := &msg.SendMessageRequest{
RoutingHead: &msg.RoutingHead{WpaTmp: &msg.WPATmp{
ToUin: proto.Uint64(uint64(uin)),
Sig: sig,
}},
ContentHead: &msg.ContentHead{PkgNum: proto.Int32(1)},
MsgBody: &msg.MessageBody{
RichText: &msg.RichText{
Elems: message.ToProtoElems(m.Elements, false),
},
},
MsgSeq: &msgSeq,
MsgRand: &r,
SyncCookie: func() []byte {
cookie := &msg.SyncCookie{
Time: &time,
Ran1: proto.Int64(rand.Int63()),
Ran2: proto.Int64(rand.Int63()),
Const1: &syncConst1,
Const2: &syncConst2,
Const3: proto.Int64(0x1d),
}
b, _ := proto.Marshal(cookie)
return b
}(),
}
payload, _ := proto.Marshal(req)
packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbSendMsg", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}