diff --git a/binary/jce/structs.go b/binary/jce/structs.go index 15d8cda8..acdf0683 100644 --- a/binary/jce/structs.go +++ b/binary/jce/structs.go @@ -190,6 +190,18 @@ type ( PCClientType int32 `jceId:"8"` } + RequestPushNotify struct { + Uin int64 `jceId:"0"` + Type byte `jceId:"1"` + Service string `jceId:"2"` + Cmd string `jceId:"3"` + NotifyCookie []byte `jceId:"4"` + MsgType int32 `jceId:"5"` + UserActive int32 `jceId:"6"` + GeneralFlag int32 `jceId:"7"` + BindedUin int64 `jceId:"8"` + } + OnlineInfo struct { InstanceId int32 `jceId:"0"` ClientType int32 `jceId:"1"` @@ -761,6 +773,18 @@ func (pkt *SvcRespParam) ReadFrom(r *JceReader) { pkt.PCClientType = r.ReadInt32(8) } +func (pkt *RequestPushNotify) ReadFrom(r *JceReader) { + pkt.Uin = r.ReadInt64(0) + pkt.Type = r.ReadByte(1) + pkt.Service = r.ReadString(2) + pkt.Cmd = r.ReadString(3) + pkt.NotifyCookie = r.ReadAny(4).([]byte) + pkt.MsgType = r.ReadInt32(5) + pkt.UserActive = r.ReadInt32(6) + pkt.GeneralFlag = r.ReadInt32(7) + pkt.BindedUin = r.ReadInt64(8) +} + func (pkt *OnlineInfo) ReadFrom(r *JceReader) { pkt.InstanceId = r.ReadInt32(0) pkt.ClientType = r.ReadInt32(1) diff --git a/client/c2c_processor.go b/client/c2c_processor.go index e85b375a..4c924860 100644 --- a/client/c2c_processor.go +++ b/client/c2c_processor.go @@ -13,22 +13,31 @@ import ( "google.golang.org/protobuf/proto" ) -var c2cDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){ - 33: troopAddMemberBroadcastDecoder, - 35: troopSystemMessageDecoder, 36: troopSystemMessageDecoder, 37: troopSystemMessageDecoder, - 45: troopSystemMessageDecoder, 46: troopSystemMessageDecoder, 84: troopSystemMessageDecoder, - 85: troopSystemMessageDecoder, 86: troopSystemMessageDecoder, 87: troopSystemMessageDecoder, - 140: tempSessionDecoder, 141: tempSessionDecoder, +var privateMsgDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){ 9: privateMessageDecoder, 10: privateMessageDecoder, 31: privateMessageDecoder, 79: privateMessageDecoder, 97: privateMessageDecoder, 120: privateMessageDecoder, 132: privateMessageDecoder, 133: privateMessageDecoder, 166: privateMessageDecoder, - 167: privateMessageDecoder, + 167: privateMessageDecoder, 140: tempSessionDecoder, 141: tempSessionDecoder, 208: privatePttDecoder, +} + +var troopSystemMsgDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){ + 35: troopSystemMessageDecoder, 36: troopSystemMessageDecoder, 37: troopSystemMessageDecoder, + 45: troopSystemMessageDecoder, 46: troopSystemMessageDecoder, 84: troopSystemMessageDecoder, + 85: troopSystemMessageDecoder, 86: troopSystemMessageDecoder, 87: troopSystemMessageDecoder, +} + +var sysMsgDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){ 187: systemMessageDecoder, 188: systemMessageDecoder, 189: systemMessageDecoder, 190: systemMessageDecoder, 191: systemMessageDecoder, - 529: msgType0x211Decoder, } +var otherDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){ + 33: troopAddMemberBroadcastDecoder, 529: msgType0x211Decoder, +} + +var c2cDecoders = map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo){} + type ( TempSessionInfo struct { Source TempSessionSource @@ -53,6 +62,18 @@ const ( AddressBookSource TempSessionSource = 9 // 来自通讯录 ) +func init() { + merge := func(m map[int32]func(*QQClient, *msg.Message, *incomingPacketInfo)) { + for k, v := range m { + c2cDecoders[k] = v + } + } + merge(privateMsgDecoders) + merge(troopSystemMsgDecoders) + merge(sysMsgDecoders) + merge(otherDecoders) +} + func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *incomingPacketInfo) { c.syncCookie = rsp.SyncCookie c.pubAccountCookie = rsp.PubAccountCookie @@ -93,11 +114,11 @@ func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *in func (c *QQClient) commMsgProcessor(pMsg *msg.Message, info *incomingPacketInfo) { strKey := fmt.Sprintf("%d%d%d%d", pMsg.Head.GetFromUin(), pMsg.Head.GetToUin(), pMsg.Head.GetMsgSeq(), pMsg.Head.GetMsgUid()) - if _, ok := c.msgSvcCache.GetAndUpdate(strKey, time.Hour*5); ok { + if _, ok := c.msgSvcCache.GetAndUpdate(strKey, time.Hour); ok { c.Debug("c2c msg %v already exists in cache. skip.", pMsg.Head.GetMsgUid()) return } - c.msgSvcCache.Add(strKey, "", time.Hour*5) + c.msgSvcCache.Add(strKey, "", time.Hour) if info.Params.bool("init") { return } diff --git a/client/decoders.go b/client/decoders.go index db2ee516..79493046 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -383,7 +383,25 @@ func decodeMessageSvcPacket(c *QQClient, info *incomingPacketInfo, payload []byt } // MessageSvc.PushNotify -func decodeSvcNotify(c *QQClient, _ *incomingPacketInfo, _ []byte) (interface{}, error) { +func decodeSvcNotify(c *QQClient, _ *incomingPacketInfo, payload []byte) (interface{}, error) { + request := &jce.RequestPacket{} + request.ReadFrom(jce.NewJceReader(payload[15:])) + data := &jce.RequestDataVersion2{} + data.ReadFrom(jce.NewJceReader(request.SBuffer)) + if len(data.Map) == 0 { + _, err := c.sendAndWait(c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix())) + return nil, err + } + notify := &jce.RequestPushNotify{} + notify.ReadFrom(jce.NewJceReader(data.Map["req_PushNotify"]["PushNotifyPack.RequestPushNotify"][1:])) + if _, ok := troopSystemMsgDecoders[notify.MsgType]; ok && notify.MsgType != 85 && notify.MsgType != 36 { + c.exceptAndDispatchGroupSysMsg() + return nil, nil + } + if _, ok := sysMsgDecoders[notify.MsgType]; ok { + _, pkt := c.buildSystemMsgNewFriendPacket() + return nil, c.send(pkt) + } _, err := c.sendAndWait(c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix())) return nil, err }