From 37b077e610835ecdebb77d2c1ee54fae24ce700d Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Wed, 20 Jan 2021 22:46:40 +0800 Subject: [PATCH] feature OtherClientStatusChangedEvent. --- binary/jce/structs.go | 41 ++++++++++++++++++++++++++++ client/entities.go | 5 ++++ client/events.go | 62 +++++++++++++++++++++++++++---------------- client/sync.go | 51 +++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 23 deletions(-) diff --git a/binary/jce/structs.go b/binary/jce/structs.go index 636fb460..b1cd22dc 100644 --- a/binary/jce/structs.go +++ b/binary/jce/structs.go @@ -195,6 +195,26 @@ type ( UClientType int64 `jceId:"5"` } + SvcReqMSFLoginNotify struct { + AppId int64 `jceId:"0"` + Status byte `jceId:"1"` + Tablet byte `jceId:"2"` + Platform int64 `jceId:"3"` + Title string `jceId:"4"` + Info string `jceId:"5"` + ProductType int64 `jceId:"6"` + ClientType int64 `jceId:"7"` + InstanceList []InstanceInfo `jceId:"8"` + } + + InstanceInfo struct { + AppId int32 `jceId:"0"` + Tablet byte `jceId:"1"` + Platform int64 `jceId:"2"` + ProductType int64 `jceId:"3"` + ClientType int64 `jceId:"4"` + } + PushMessageInfo struct { FromUin int64 `jceId:"0"` MsgTime int64 `jceId:"1"` @@ -746,6 +766,27 @@ func (pkt *OnlineInfo) ReadFrom(r *JceReader) { pkt.UClientType = r.ReadInt64(5) } +func (pkt *SvcReqMSFLoginNotify) ReadFrom(r *JceReader) { + pkt.InstanceList = []InstanceInfo{} + pkt.AppId = r.ReadInt64(0) + pkt.Status = r.ReadByte(1) + pkt.Tablet = r.ReadByte(2) + pkt.Platform = r.ReadInt64(3) + pkt.Title = r.ReadString(4) + pkt.Info = r.ReadString(5) + pkt.ProductType = r.ReadInt64(6) + pkt.ClientType = r.ReadInt64(7) + r.ReadSlice(&pkt.InstanceList, 8) +} + +func (pkt *InstanceInfo) ReadFrom(r *JceReader) { + pkt.AppId = r.ReadInt32(0) + pkt.Tablet = r.ReadByte(1) + pkt.Platform = r.ReadInt64(2) + pkt.ProductType = r.ReadInt64(3) + pkt.ClientType = r.ReadInt64(4) +} + func (pkt *SvcRespPushMsg) ToBytes() []byte { w := NewJceWriter() w.WriteJceStructRaw(pkt) diff --git a/client/entities.go b/client/entities.go index 03c37fea..9446c83a 100644 --- a/client/entities.go +++ b/client/entities.go @@ -69,6 +69,11 @@ type ( List []*FriendInfo } + OtherClientStatusChangedEvent struct { + Client *OtherClientInfo + Online bool + } + GroupMuteEvent struct { GroupCode int64 OperatorUin int64 diff --git a/client/events.go b/client/events.go index 03174b4b..c1247d0f 100644 --- a/client/events.go +++ b/client/events.go @@ -9,29 +9,30 @@ import ( ) type eventHandlers struct { - privateMessageHandlers []func(*QQClient, *message.PrivateMessage) - tempMessageHandlers []func(*QQClient, *message.TempMessage) - groupMessageHandlers []func(*QQClient, *message.GroupMessage) - groupMuteEventHandlers []func(*QQClient, *GroupMuteEvent) - groupRecalledHandlers []func(*QQClient, *GroupMessageRecalledEvent) - friendRecalledHandlers []func(*QQClient, *FriendMessageRecalledEvent) - joinGroupHandlers []func(*QQClient, *GroupInfo) - leaveGroupHandlers []func(*QQClient, *GroupLeaveEvent) - memberJoinedHandlers []func(*QQClient, *MemberJoinGroupEvent) - memberLeavedHandlers []func(*QQClient, *MemberLeaveGroupEvent) - memberCardUpdatedHandlers []func(*QQClient, *MemberCardUpdatedEvent) - permissionChangedHandlers []func(*QQClient, *MemberPermissionChangedEvent) - groupInvitedHandlers []func(*QQClient, *GroupInvitedRequest) - joinRequestHandlers []func(*QQClient, *UserJoinGroupRequest) - friendRequestHandlers []func(*QQClient, *NewFriendRequest) - newFriendHandlers []func(*QQClient, *NewFriendEvent) - disconnectHandlers []func(*QQClient, *ClientDisconnectedEvent) - logHandlers []func(*QQClient, *LogEvent) - serverUpdatedHandlers []func(*QQClient, *ServerUpdatedEvent) bool - groupNotifyHandlers []func(*QQClient, INotifyEvent) - friendNotifyHandlers []func(*QQClient, INotifyEvent) - offlineFileHandlers []func(*QQClient, *OfflineFileEvent) - groupMessageReceiptHandlers sync.Map + privateMessageHandlers []func(*QQClient, *message.PrivateMessage) + tempMessageHandlers []func(*QQClient, *message.TempMessage) + groupMessageHandlers []func(*QQClient, *message.GroupMessage) + groupMuteEventHandlers []func(*QQClient, *GroupMuteEvent) + groupRecalledHandlers []func(*QQClient, *GroupMessageRecalledEvent) + friendRecalledHandlers []func(*QQClient, *FriendMessageRecalledEvent) + joinGroupHandlers []func(*QQClient, *GroupInfo) + leaveGroupHandlers []func(*QQClient, *GroupLeaveEvent) + memberJoinedHandlers []func(*QQClient, *MemberJoinGroupEvent) + memberLeavedHandlers []func(*QQClient, *MemberLeaveGroupEvent) + memberCardUpdatedHandlers []func(*QQClient, *MemberCardUpdatedEvent) + permissionChangedHandlers []func(*QQClient, *MemberPermissionChangedEvent) + groupInvitedHandlers []func(*QQClient, *GroupInvitedRequest) + joinRequestHandlers []func(*QQClient, *UserJoinGroupRequest) + friendRequestHandlers []func(*QQClient, *NewFriendRequest) + newFriendHandlers []func(*QQClient, *NewFriendEvent) + disconnectHandlers []func(*QQClient, *ClientDisconnectedEvent) + logHandlers []func(*QQClient, *LogEvent) + serverUpdatedHandlers []func(*QQClient, *ServerUpdatedEvent) bool + groupNotifyHandlers []func(*QQClient, INotifyEvent) + friendNotifyHandlers []func(*QQClient, INotifyEvent) + offlineFileHandlers []func(*QQClient, *OfflineFileEvent) + otherClientStatusChangedHandlers []func(*QQClient, *OtherClientStatusChangedEvent) + groupMessageReceiptHandlers sync.Map } func (c *QQClient) OnPrivateMessage(f func(*QQClient, *message.PrivateMessage)) { @@ -118,6 +119,10 @@ func (c *QQClient) OnReceivedOfflineFile(f func(*QQClient, *OfflineFileEvent)) { c.eventHandlers.offlineFileHandlers = append(c.eventHandlers.offlineFileHandlers, f) } +func (c *QQClient) OnOtherClientStatusChanged(f func(*QQClient, *OtherClientStatusChangedEvent)) { + c.eventHandlers.otherClientStatusChangedHandlers = append(c.eventHandlers.otherClientStatusChangedHandlers, f) +} + func (c *QQClient) OnLog(f func(*QQClient, *LogEvent)) { c.eventHandlers.logHandlers = append(c.eventHandlers.logHandlers, f) } @@ -371,6 +376,17 @@ func (c *QQClient) dispatchOfflineFileEvent(e *OfflineFileEvent) { } } +func (c *QQClient) dispatchOtherClientStatusChangedEvent(e *OtherClientStatusChangedEvent) { + if e == nil { + return + } + for _, f := range c.eventHandlers.otherClientStatusChangedHandlers { + cover(func() { + f(c, e) + }) + } +} + func (c *QQClient) dispatchLogEvent(e *LogEvent) { if e == nil { return diff --git a/client/sync.go b/client/sync.go index b8670fd9..d40a60d8 100644 --- a/client/sync.go +++ b/client/sync.go @@ -11,6 +11,7 @@ import ( func init() { decoders["StatSvc.GetDevLoginInfo"] = decodeDevListResponse + decoders["StatSvc.SvcReqMSFLoginNotify"] = decodeLoginNotifyPacket decoders["RegPrxySvc.getOffMsg"] = decodeOfflineMsgResponse decoders["RegPrxySvc.PushParam"] = decodePushParamPacket } @@ -194,3 +195,53 @@ func decodePushParamPacket(c *QQClient, _ uint16, payload []byte) (interface{}, } return nil, nil } + +// StatSvc.SvcReqMSFLoginNotify +func decodeLoginNotifyPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) { + request := &jce.RequestPacket{} + request.ReadFrom(jce.NewJceReader(payload)) + data := &jce.RequestDataVersion2{} + data.ReadFrom(jce.NewJceReader(request.SBuffer)) + reader := jce.NewJceReader(data.Map["SvcReqMSFLoginNotify"]["QQService.SvcReqMSFLoginNotify"][1:]) + notify := &jce.SvcReqMSFLoginNotify{} + notify.ReadFrom(reader) + if notify.Status == 1 { + found := false + for _, oc := range c.OnlineClients { + if oc.AppId == notify.AppId { + found = true + } + } + if !found { + allowedClients, _ := c.GetAllowedClients() + for _, ac := range allowedClients { + t := ac + if ac.AppId == notify.AppId { + c.OnlineClients = append(c.OnlineClients, t) + c.dispatchOtherClientStatusChangedEvent(&OtherClientStatusChangedEvent{ + Client: t, + Online: true, + }) + break + } + } + } + } + if notify.Status == 2 { + rmi := -1 + for i, oc := range c.OnlineClients { + if oc.AppId == notify.AppId { + rmi = i + } + } + if rmi != -1 { + rmc := c.OnlineClients[rmi] + c.OnlineClients = append(c.OnlineClients[:rmi], c.OnlineClients[rmi+1:]...) + c.dispatchOtherClientStatusChangedEvent(&OtherClientStatusChangedEvent{ + Client: rmc, + Online: false, + }) + } + } + return nil, nil +}