mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
restructure online push decoder.
This commit is contained in:
parent
8c89d62657
commit
ab3ed8f883
@ -68,89 +68,6 @@ func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *in
|
|||||||
} else {
|
} else {
|
||||||
c.Debug("unknown msg type on c2c processor: %v", pMsg.Head.GetMsgType())
|
c.Debug("unknown msg type on c2c processor: %v", pMsg.Head.GetMsgType())
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
switch pMsg.Head.GetMsgType() {
|
|
||||||
case 33: // 加群同步
|
|
||||||
func() {
|
|
||||||
groupJoinLock.Lock()
|
|
||||||
defer groupJoinLock.Unlock()
|
|
||||||
group := c.FindGroupByUin(pMsg.Head.GetFromUin())
|
|
||||||
if pMsg.Head.GetAuthUin() == c.Uin {
|
|
||||||
if group == nil && c.ReloadGroupList() == nil {
|
|
||||||
c.dispatchJoinGroupEvent(c.FindGroupByUin(pMsg.Head.GetFromUin()))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if group != nil && group.FindMember(pMsg.Head.GetAuthUin()) == nil {
|
|
||||||
mem, err := c.getMemberInfo(group.Code, pMsg.Head.GetAuthUin())
|
|
||||||
if err != nil {
|
|
||||||
c.Debug("error to fetch new member info: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
group.Update(func(info *GroupInfo) {
|
|
||||||
info.Members = append(info.Members, mem)
|
|
||||||
})
|
|
||||||
c.dispatchNewMemberEvent(&MemberJoinGroupEvent{
|
|
||||||
Group: group,
|
|
||||||
Member: mem,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
case 84, 87:
|
|
||||||
c.exceptAndDispatchGroupSysMsg()
|
|
||||||
case 141: // 临时会话
|
|
||||||
if pMsg.Head.C2CTmpMsgHead == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
group := c.FindGroupByUin(pMsg.Head.C2CTmpMsgHead.GetGroupUin())
|
|
||||||
if group == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if pMsg.Head.GetFromUin() == c.Uin {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c.dispatchTempMessage(c.parseTempMessage(pMsg))
|
|
||||||
case 166, 208: // 好友消息
|
|
||||||
if pMsg.Head.GetFromUin() == c.Uin {
|
|
||||||
for {
|
|
||||||
frdSeq := atomic.LoadInt32(&c.friendSeq)
|
|
||||||
if frdSeq < pMsg.Head.GetMsgSeq() {
|
|
||||||
if atomic.CompareAndSwapInt32(&c.friendSeq, frdSeq, pMsg.Head.GetMsgSeq()) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if pMsg.Body.RichText == nil || pMsg.Body.RichText.Elems == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c.dispatchFriendMessage(c.parsePrivateMessage(pMsg))
|
|
||||||
case 187:
|
|
||||||
_, pkt := c.buildSystemMsgNewFriendPacket()
|
|
||||||
_ = c.send(pkt)
|
|
||||||
case 529:
|
|
||||||
sub4 := msg.SubMsgType0X4Body{}
|
|
||||||
if err := proto.Unmarshal(pMsg.Body.MsgContent, &sub4); err != nil {
|
|
||||||
err = errors.Wrap(err, "unmarshal sub msg 0x4 error")
|
|
||||||
c.Error("unmarshal sub msg 0x4 error: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if sub4.NotOnlineFile != nil {
|
|
||||||
rsp, err := c.sendAndWait(c.buildOfflineFileDownloadRequestPacket(sub4.NotOnlineFile.FileUuid)) // offline_file.go
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c.dispatchOfflineFileEvent(&OfflineFileEvent{
|
|
||||||
FileName: string(sub4.NotOnlineFile.FileName),
|
|
||||||
FileSize: sub4.NotOnlineFile.GetFileSize(),
|
|
||||||
Sender: pMsg.Head.GetFromUin(),
|
|
||||||
DownloadUrl: rsp.(string),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if delItems != nil {
|
if delItems != nil {
|
||||||
|
@ -16,7 +16,6 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
|
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x6ff"
|
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x6ff"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/notify"
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/profilecard"
|
"github.com/Mrs4s/MiraiGo/client/pb/profilecard"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/qweb"
|
"github.com/Mrs4s/MiraiGo/client/pb/qweb"
|
||||||
@ -520,205 +519,6 @@ func decodeOffPicUpResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte)
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnlinePush.ReqPush
|
|
||||||
func decodeOnlinePushReqPacket(c *QQClient, info *incomingPacketInfo, payload []byte) (interface{}, error) {
|
|
||||||
request := &jce.RequestPacket{}
|
|
||||||
request.ReadFrom(jce.NewJceReader(payload))
|
|
||||||
data := &jce.RequestDataVersion2{}
|
|
||||||
data.ReadFrom(jce.NewJceReader(request.SBuffer))
|
|
||||||
jr := jce.NewJceReader(data.Map["req"]["OnlinePushPack.SvcReqPushMsg"][1:])
|
|
||||||
msgInfos := []jce.PushMessageInfo{}
|
|
||||||
uin := jr.ReadInt64(0)
|
|
||||||
jr.ReadSlice(&msgInfos, 2)
|
|
||||||
_ = c.send(c.buildDeleteOnlinePushPacket(uin, info.SequenceId, msgInfos))
|
|
||||||
for _, m := range msgInfos {
|
|
||||||
k := fmt.Sprintf("%v%v%v", m.MsgSeq, m.MsgTime, m.MsgUid)
|
|
||||||
if _, ok := c.onlinePushCache.Get(k); ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c.onlinePushCache.Add(k, "", time.Second*30)
|
|
||||||
if m.MsgType == 732 {
|
|
||||||
r := binary.NewReader(m.VMsg)
|
|
||||||
groupId := int64(uint32(r.ReadInt32()))
|
|
||||||
iType := r.ReadByte()
|
|
||||||
r.ReadByte()
|
|
||||||
switch iType {
|
|
||||||
case 0x0c: // 群内禁言
|
|
||||||
operator := int64(uint32(r.ReadInt32()))
|
|
||||||
if operator == c.Uin {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
r.ReadBytes(6)
|
|
||||||
target := int64(uint32(r.ReadInt32()))
|
|
||||||
t := r.ReadInt32()
|
|
||||||
c.dispatchGroupMuteEvent(&GroupMuteEvent{
|
|
||||||
GroupCode: groupId,
|
|
||||||
OperatorUin: operator,
|
|
||||||
TargetUin: target,
|
|
||||||
Time: t,
|
|
||||||
})
|
|
||||||
case 0x10, 0x11, 0x14, 0x15: // group notify msg
|
|
||||||
r.ReadByte()
|
|
||||||
b := notify.NotifyMsgBody{}
|
|
||||||
_ = proto.Unmarshal(r.ReadAvailable(), &b)
|
|
||||||
if b.OptMsgRecall != nil {
|
|
||||||
for _, rm := range b.OptMsgRecall.RecalledMsgList {
|
|
||||||
if rm.MsgType == 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c.dispatchGroupMessageRecalledEvent(&GroupMessageRecalledEvent{
|
|
||||||
GroupCode: groupId,
|
|
||||||
OperatorUin: b.OptMsgRecall.Uin,
|
|
||||||
AuthorUin: rm.AuthorUin,
|
|
||||||
MessageId: rm.Seq,
|
|
||||||
Time: rm.Time,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if b.OptGeneralGrayTip != nil {
|
|
||||||
c.grayTipProcessor(groupId, b.OptGeneralGrayTip)
|
|
||||||
}
|
|
||||||
if b.OptMsgRedTips != nil {
|
|
||||||
if b.OptMsgRedTips.LuckyFlag == 1 { // 运气王提示
|
|
||||||
c.dispatchGroupNotifyEvent(&GroupRedBagLuckyKingNotifyEvent{
|
|
||||||
GroupCode: groupId,
|
|
||||||
Sender: int64(b.OptMsgRedTips.SenderUin),
|
|
||||||
LuckyKing: int64(b.OptMsgRedTips.LuckyUin),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if b.QqGroupDigestMsg != nil {
|
|
||||||
var digest = b.QqGroupDigestMsg
|
|
||||||
c.dispatchGroupDigestEvent(&GroupDigestEvent{
|
|
||||||
GroupCode: int64(digest.GroupCode),
|
|
||||||
MessageID: int32(digest.Seq),
|
|
||||||
InternalMessageID: int32(digest.Random),
|
|
||||||
OperationType: digest.OpType,
|
|
||||||
OperateTime: digest.OpTime,
|
|
||||||
SenderUin: int64(digest.Sender),
|
|
||||||
OperatorUin: int64(digest.DigestOper),
|
|
||||||
SenderNick: string(digest.SenderNick),
|
|
||||||
OperatorNick: string(digest.OperNick),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if m.MsgType == 528 {
|
|
||||||
vr := jce.NewJceReader(m.VMsg)
|
|
||||||
subType := vr.ReadInt64(0)
|
|
||||||
probuf := vr.ReadAny(10).([]byte)
|
|
||||||
switch subType {
|
|
||||||
case 0x8A, 0x8B:
|
|
||||||
s8a := pb.Sub8A{}
|
|
||||||
if err := proto.Unmarshal(probuf, &s8a); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
||||||
}
|
|
||||||
for _, m := range s8a.MsgInfo {
|
|
||||||
if m.ToUin == c.Uin {
|
|
||||||
c.dispatchFriendMessageRecalledEvent(&FriendMessageRecalledEvent{
|
|
||||||
FriendUin: m.FromUin,
|
|
||||||
MessageId: m.MsgSeq,
|
|
||||||
Time: m.MsgTime,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 0xB3:
|
|
||||||
b3 := pb.SubB3{}
|
|
||||||
if err := proto.Unmarshal(probuf, &b3); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
||||||
}
|
|
||||||
frd := &FriendInfo{
|
|
||||||
Uin: b3.MsgAddFrdNotify.Uin,
|
|
||||||
Nickname: b3.MsgAddFrdNotify.Nick,
|
|
||||||
}
|
|
||||||
c.FriendList = append(c.FriendList, frd)
|
|
||||||
c.dispatchNewFriendEvent(&NewFriendEvent{Friend: frd})
|
|
||||||
case 0xD4:
|
|
||||||
d4 := pb.SubD4{}
|
|
||||||
if err := proto.Unmarshal(probuf, &d4); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
||||||
}
|
|
||||||
groupLeaveLock.Lock()
|
|
||||||
if g := c.FindGroup(d4.Uin); g != nil {
|
|
||||||
if err := c.ReloadGroupList(); err != nil {
|
|
||||||
groupLeaveLock.Unlock()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
c.dispatchLeaveGroupEvent(&GroupLeaveEvent{Group: g})
|
|
||||||
}
|
|
||||||
groupLeaveLock.Unlock()
|
|
||||||
case 0x27:
|
|
||||||
s27 := pb.Sub27{}
|
|
||||||
if err := proto.Unmarshal(probuf, &s27); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
||||||
}
|
|
||||||
for _, m := range s27.ModInfos {
|
|
||||||
if m.DelFriend != nil {
|
|
||||||
frdUin := m.DelFriend.Uins[0]
|
|
||||||
if frd := c.FindFriend(int64(frdUin)); frd != nil {
|
|
||||||
if err := c.ReloadFriendList(); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to reload friend list")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 290:
|
|
||||||
t := ¬ify.GeneralGrayTipInfo{}
|
|
||||||
_ = proto.Unmarshal(probuf, t)
|
|
||||||
var sender int64
|
|
||||||
for _, templ := range t.MsgTemplParam {
|
|
||||||
if templ.Name == "uin_str1" {
|
|
||||||
sender, _ = strconv.ParseInt(templ.Value, 10, 64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if sender == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
c.dispatchFriendNotifyEvent(&FriendPokeNotifyEvent{
|
|
||||||
Sender: sender,
|
|
||||||
Receiver: c.Uin,
|
|
||||||
})
|
|
||||||
case 0x44:
|
|
||||||
s44 := pb.Sub44{}
|
|
||||||
if err := proto.Unmarshal(probuf, &s44); err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
|
||||||
}
|
|
||||||
if s44.GroupSyncMsg != nil {
|
|
||||||
func() {
|
|
||||||
groupJoinLock.Lock()
|
|
||||||
defer groupJoinLock.Unlock()
|
|
||||||
if s44.GroupSyncMsg.GetGrpCode() != 0 { // member sync
|
|
||||||
c.Debug("syncing members.")
|
|
||||||
if group := c.FindGroup(s44.GroupSyncMsg.GetGrpCode()); group != nil {
|
|
||||||
group.Update(func(_ *GroupInfo) {
|
|
||||||
var lastJoinTime int64 = 0
|
|
||||||
for _, m := range group.Members {
|
|
||||||
if lastJoinTime < m.JoinTime {
|
|
||||||
lastJoinTime = m.JoinTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if newMem, err := c.GetGroupMembers(group); err == nil {
|
|
||||||
group.Members = newMem
|
|
||||||
for _, m := range newMem {
|
|
||||||
if lastJoinTime < m.JoinTime {
|
|
||||||
go c.dispatchNewMemberEvent(&MemberJoinGroupEvent{
|
|
||||||
Group: group,
|
|
||||||
Member: m,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// OnlinePush.PbPushTransMsg
|
// OnlinePush.PbPushTransMsg
|
||||||
func decodeOnlinePushTransPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
func decodeOnlinePushTransPacket(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||||
info := msg.TransMsgInfo{}
|
info := msg.TransMsgInfo{}
|
||||||
|
243
client/online_push.go
Normal file
243
client/online_push.go
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/notify"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var msg0x210Decoders = map[int64]func(*QQClient, []byte) error{
|
||||||
|
0x8A: msgType0x210Sub8ADecoder, 0x8B: msgType0x210Sub8ADecoder, 0xB3: msgType0x210SubB3Decoder,
|
||||||
|
0xD4: msgType0x210SubD4Decoder, 0x27: msgType0x210Sub27Decoder, 0x122: msgType0x210Sub122Decoder,
|
||||||
|
0x123: msgType0x210Sub122Decoder, 0x44: msgType0x210Sub44Decoder,
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlinePush.ReqPush
|
||||||
|
func decodeOnlinePushReqPacket(c *QQClient, info *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||||
|
request := &jce.RequestPacket{}
|
||||||
|
request.ReadFrom(jce.NewJceReader(payload))
|
||||||
|
data := &jce.RequestDataVersion2{}
|
||||||
|
data.ReadFrom(jce.NewJceReader(request.SBuffer))
|
||||||
|
jr := jce.NewJceReader(data.Map["req"]["OnlinePushPack.SvcReqPushMsg"][1:])
|
||||||
|
msgInfos := []jce.PushMessageInfo{}
|
||||||
|
uin := jr.ReadInt64(0)
|
||||||
|
jr.ReadSlice(&msgInfos, 2)
|
||||||
|
_ = c.send(c.buildDeleteOnlinePushPacket(uin, info.SequenceId, msgInfos))
|
||||||
|
for _, m := range msgInfos {
|
||||||
|
k := fmt.Sprintf("%v%v%v", m.MsgSeq, m.MsgTime, m.MsgUid)
|
||||||
|
if _, ok := c.onlinePushCache.Get(k); ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c.onlinePushCache.Add(k, "", time.Second*30)
|
||||||
|
// 0x2dc
|
||||||
|
if m.MsgType == 732 {
|
||||||
|
r := binary.NewReader(m.VMsg)
|
||||||
|
groupId := int64(uint32(r.ReadInt32()))
|
||||||
|
iType := r.ReadByte()
|
||||||
|
r.ReadByte()
|
||||||
|
switch iType {
|
||||||
|
case 0x0c: // 群内禁言
|
||||||
|
operator := int64(uint32(r.ReadInt32()))
|
||||||
|
if operator == c.Uin {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r.ReadBytes(6)
|
||||||
|
target := int64(uint32(r.ReadInt32()))
|
||||||
|
t := r.ReadInt32()
|
||||||
|
c.dispatchGroupMuteEvent(&GroupMuteEvent{
|
||||||
|
GroupCode: groupId,
|
||||||
|
OperatorUin: operator,
|
||||||
|
TargetUin: target,
|
||||||
|
Time: t,
|
||||||
|
})
|
||||||
|
case 0x10, 0x11, 0x14, 0x15: // group notify msg
|
||||||
|
r.ReadByte()
|
||||||
|
b := notify.NotifyMsgBody{}
|
||||||
|
_ = proto.Unmarshal(r.ReadAvailable(), &b)
|
||||||
|
if b.OptMsgRecall != nil {
|
||||||
|
for _, rm := range b.OptMsgRecall.RecalledMsgList {
|
||||||
|
if rm.MsgType == 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
c.dispatchGroupMessageRecalledEvent(&GroupMessageRecalledEvent{
|
||||||
|
GroupCode: groupId,
|
||||||
|
OperatorUin: b.OptMsgRecall.Uin,
|
||||||
|
AuthorUin: rm.AuthorUin,
|
||||||
|
MessageId: rm.Seq,
|
||||||
|
Time: rm.Time,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if b.OptGeneralGrayTip != nil {
|
||||||
|
c.grayTipProcessor(groupId, b.OptGeneralGrayTip)
|
||||||
|
}
|
||||||
|
if b.OptMsgRedTips != nil {
|
||||||
|
if b.OptMsgRedTips.LuckyFlag == 1 { // 运气王提示
|
||||||
|
c.dispatchGroupNotifyEvent(&GroupRedBagLuckyKingNotifyEvent{
|
||||||
|
GroupCode: groupId,
|
||||||
|
Sender: int64(b.OptMsgRedTips.SenderUin),
|
||||||
|
LuckyKing: int64(b.OptMsgRedTips.LuckyUin),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if b.QqGroupDigestMsg != nil {
|
||||||
|
var digest = b.QqGroupDigestMsg
|
||||||
|
c.dispatchGroupDigestEvent(&GroupDigestEvent{
|
||||||
|
GroupCode: int64(digest.GroupCode),
|
||||||
|
MessageID: int32(digest.Seq),
|
||||||
|
InternalMessageID: int32(digest.Random),
|
||||||
|
OperationType: digest.OpType,
|
||||||
|
OperateTime: digest.OpTime,
|
||||||
|
SenderUin: int64(digest.Sender),
|
||||||
|
OperatorUin: int64(digest.DigestOper),
|
||||||
|
SenderNick: string(digest.SenderNick),
|
||||||
|
OperatorNick: string(digest.OperNick),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 0x210
|
||||||
|
if m.MsgType == 528 {
|
||||||
|
vr := jce.NewJceReader(m.VMsg)
|
||||||
|
subType := vr.ReadInt64(0)
|
||||||
|
protobuf := vr.ReadAny(10).([]byte)
|
||||||
|
if decoder, ok := msg0x210Decoders[subType]; ok {
|
||||||
|
if err := decoder(c, protobuf); err != nil {
|
||||||
|
return nil, errors.Wrap(err, "decode online push 0x210 error")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.Debug("unknown online push 0x210 sub type 0x%v", strconv.FormatInt(subType, 16))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msgType0x210Sub8ADecoder(c *QQClient, protobuf []byte) error {
|
||||||
|
s8a := pb.Sub8A{}
|
||||||
|
if err := proto.Unmarshal(protobuf, &s8a); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
|
}
|
||||||
|
for _, m := range s8a.MsgInfo {
|
||||||
|
if m.ToUin == c.Uin {
|
||||||
|
c.dispatchFriendMessageRecalledEvent(&FriendMessageRecalledEvent{
|
||||||
|
FriendUin: m.FromUin,
|
||||||
|
MessageId: m.MsgSeq,
|
||||||
|
Time: m.MsgTime,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msgType0x210SubB3Decoder(c *QQClient, protobuf []byte) error {
|
||||||
|
b3 := pb.SubB3{}
|
||||||
|
if err := proto.Unmarshal(protobuf, &b3); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
|
}
|
||||||
|
frd := &FriendInfo{
|
||||||
|
Uin: b3.MsgAddFrdNotify.Uin,
|
||||||
|
Nickname: b3.MsgAddFrdNotify.Nick,
|
||||||
|
}
|
||||||
|
c.FriendList = append(c.FriendList, frd)
|
||||||
|
c.dispatchNewFriendEvent(&NewFriendEvent{Friend: frd})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msgType0x210SubD4Decoder(c *QQClient, protobuf []byte) error {
|
||||||
|
d4 := pb.SubD4{}
|
||||||
|
if err := proto.Unmarshal(protobuf, &d4); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
|
}
|
||||||
|
groupLeaveLock.Lock()
|
||||||
|
if g := c.FindGroup(d4.Uin); g != nil {
|
||||||
|
if err := c.ReloadGroupList(); err != nil {
|
||||||
|
groupLeaveLock.Unlock()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.dispatchLeaveGroupEvent(&GroupLeaveEvent{Group: g})
|
||||||
|
}
|
||||||
|
groupLeaveLock.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msgType0x210Sub27Decoder(c *QQClient, protobuf []byte) error {
|
||||||
|
s27 := pb.Sub27{}
|
||||||
|
if err := proto.Unmarshal(protobuf, &s27); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
|
}
|
||||||
|
for _, m := range s27.ModInfos {
|
||||||
|
if m.DelFriend != nil {
|
||||||
|
frdUin := m.DelFriend.Uins[0]
|
||||||
|
if frd := c.FindFriend(int64(frdUin)); frd != nil {
|
||||||
|
if err := c.ReloadFriendList(); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to reload friend list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msgType0x210Sub122Decoder(c *QQClient, protobuf []byte) error {
|
||||||
|
t := ¬ify.GeneralGrayTipInfo{}
|
||||||
|
_ = proto.Unmarshal(protobuf, t)
|
||||||
|
var sender int64
|
||||||
|
for _, templ := range t.MsgTemplParam {
|
||||||
|
if templ.Name == "uin_str1" {
|
||||||
|
sender, _ = strconv.ParseInt(templ.Value, 10, 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sender == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
c.dispatchFriendNotifyEvent(&FriendPokeNotifyEvent{
|
||||||
|
Sender: sender,
|
||||||
|
Receiver: c.Uin,
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func msgType0x210Sub44Decoder(c *QQClient, protobuf []byte) error {
|
||||||
|
s44 := pb.Sub44{}
|
||||||
|
if err := proto.Unmarshal(protobuf, &s44); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
|
}
|
||||||
|
if s44.GroupSyncMsg != nil {
|
||||||
|
func() {
|
||||||
|
groupJoinLock.Lock()
|
||||||
|
defer groupJoinLock.Unlock()
|
||||||
|
if s44.GroupSyncMsg.GetGrpCode() != 0 { // member sync
|
||||||
|
c.Debug("syncing members.")
|
||||||
|
if group := c.FindGroup(s44.GroupSyncMsg.GetGrpCode()); group != nil {
|
||||||
|
group.Update(func(_ *GroupInfo) {
|
||||||
|
var lastJoinTime int64 = 0
|
||||||
|
for _, m := range group.Members {
|
||||||
|
if lastJoinTime < m.JoinTime {
|
||||||
|
lastJoinTime = m.JoinTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if newMem, err := c.GetGroupMembers(group); err == nil {
|
||||||
|
group.Members = newMem
|
||||||
|
for _, m := range newMem {
|
||||||
|
if lastJoinTime < m.JoinTime {
|
||||||
|
go c.dispatchNewMemberEvent(&MemberJoinGroupEvent{
|
||||||
|
Group: group,
|
||||||
|
Member: m,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
@ -111,6 +111,10 @@ func (c *QQClient) MarkGroupMessageReaded(groupCode, seq int64) {
|
|||||||
_, _ = c.sendAndWait(c.buildGroupMsgReadedPacket(groupCode, seq))
|
_, _ = c.sendAndWait(c.buildGroupMsgReadedPacket(groupCode, seq))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) MarkPrivateMessageReaded(uin, time int64) {
|
||||||
|
_, _ = c.sendAndWait(c.buildPrivateMsgReadedPacket(uin, time))
|
||||||
|
}
|
||||||
|
|
||||||
// StatSvc.GetDevLoginInfo
|
// StatSvc.GetDevLoginInfo
|
||||||
func (c *QQClient) buildDeviceListRequestPacket() (uint16, []byte) {
|
func (c *QQClient) buildDeviceListRequestPacket() (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
@ -272,6 +276,18 @@ func (c *QQClient) buildGroupMsgReadedPacket(groupCode, msgSeq int64) (uint16, [
|
|||||||
return seq, packet
|
return seq, packet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) buildPrivateMsgReadedPacket(uin, time int64) (uint16, []byte) {
|
||||||
|
seq := c.nextSeq()
|
||||||
|
req, _ := proto.Marshal(&msg.PbMsgReadedReportReq{C2CReadReport: &msg.PbC2CReadedReportReq{PairInfo: []*msg.UinPairReadInfo{
|
||||||
|
{
|
||||||
|
PeerUin: proto.Uint64(uint64(uin)),
|
||||||
|
LastReadTime: proto.Uint32(uint32(time)),
|
||||||
|
},
|
||||||
|
}, SyncCookie: c.syncCookie}})
|
||||||
|
packet := packets.BuildUniPacket(c.Uin, seq, "PbMessageSvc.PbMsgReadedReport", 1, c.OutGoingPacketSessionId, []byte{}, c.sigInfo.d2Key, req)
|
||||||
|
return seq, packet
|
||||||
|
}
|
||||||
|
|
||||||
// StatSvc.GetDevLoginInfo
|
// StatSvc.GetDevLoginInfo
|
||||||
func decodeDevListResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
func decodeDevListResponse(_ *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) {
|
||||||
request := &jce.RequestPacket{}
|
request := &jce.RequestPacket{}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user