diff --git a/client/client.go b/client/client.go index 47663294..9555e9ed 100644 --- a/client/client.go +++ b/client/client.go @@ -103,6 +103,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient { "OnlinePush.PbPushTransMsg": decodeOnlinePushTransPacket, "ConfigPushSvc.PushReq": decodePushReqPacket, "MessageSvc.PbGetMsg": decodeMessageSvcPacket, + "MessageSvc.PushForceOffline": decodeForceOfflinePacket, "friendlist.getFriendGroupList": decodeFriendGroupListResponse, "friendlist.GetTroopListReqV2": decodeGroupListResponse, "friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse, @@ -576,6 +577,7 @@ func (c *QQClient) loop() { } }() } + c.Conn.Close() } func (c *QQClient) heartbeat() { diff --git a/client/decoders.go b/client/decoders.go index 5c608b4e..bad357fd 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -652,3 +652,17 @@ func decodeSystemMsgFriendPacket(c *QQClient, _ uint16, payload []byte) (interfa } return nil, nil } + +func decodeForceOfflinePacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) { + request := &jce.RequestPacket{} + request.ReadFrom(jce.NewJceReader(payload)) + data := &jce.RequestDataVersion2{} + data.ReadFrom(jce.NewJceReader(request.SBuffer)) + r := jce.NewJceReader(data.Map["req_PushForceOffline"]["PushNotifyPack.RequestPushForceOffline"][1:]) + tips := r.ReadString(2) + if c.Online { + c.Online = false + c.dispatchDisconnectEvent(&ClientDisconnectedEvent{Message: tips}) + } + return nil, nil +} diff --git a/client/entities.go b/client/entities.go index 2567c2ac..6664c6a1 100644 --- a/client/entities.go +++ b/client/entities.go @@ -104,6 +104,10 @@ type ( NewPermission MemberPermission } + ClientDisconnectedEvent struct { + Message string + } + GroupInvitedRequest struct { RequestId int64 InvitorUin int64 diff --git a/client/events.go b/client/events.go index a9524eec..c1e686eb 100644 --- a/client/events.go +++ b/client/events.go @@ -19,6 +19,7 @@ type eventHandlers struct { groupInvitedHandlers []func(*QQClient, *GroupInvitedRequest) joinRequestHandlers []func(*QQClient, *UserJoinGroupRequest) friendRequestHandlers []func(*QQClient, *NewFriendRequest) + disconnectHandlers []func(*QQClient, *ClientDisconnectedEvent) groupMessageReceiptHandlers sync.Map } @@ -82,6 +83,10 @@ func (c *QQClient) OnNewFriendRequest(f func(*QQClient, *NewFriendRequest)) { c.eventHandlers.friendRequestHandlers = append(c.eventHandlers.friendRequestHandlers, f) } +func (c *QQClient) OnDisconnected(f func(*QQClient, *ClientDisconnectedEvent)) { + c.eventHandlers.disconnectHandlers = append(c.eventHandlers.disconnectHandlers, f) +} + func NewUinFilterPrivate(uin int64) func(*message.PrivateMessage) bool { return func(msg *message.PrivateMessage) bool { return msg.Sender.Uin == uin @@ -246,6 +251,17 @@ func (c *QQClient) dispatchNewFriendRequest(r *NewFriendRequest) { } } +func (c *QQClient) dispatchDisconnectEvent(e *ClientDisconnectedEvent) { + if e == nil { + return + } + for _, f := range c.eventHandlers.disconnectHandlers { + cover(func() { + f(c, e) + }) + } +} + func cover(f func()) { defer func() { if pan := recover(); pan != nil {