From 92b493e5ac01ecfa7ff88fafff1316e402047939 Mon Sep 17 00:00:00 2001 From: Mrs4s <1844812067@qq.com> Date: Tue, 14 Jul 2020 18:44:47 +0800 Subject: [PATCH] supported MemberLeaveGroupEvent. --- client/client.go | 14 +++++++++++++ client/decoders.go | 51 ++++++++++++++++++++++++++++++---------------- client/entities.go | 13 +++++++++++- client/events.go | 16 +++++++++++++++ 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/client/client.go b/client/client.go index 7adcdcbf..da9efe7d 100644 --- a/client/client.go +++ b/client/client.go @@ -341,6 +341,20 @@ func (g *GroupInfo) FindMember(uin int64) *GroupMemberInfo { return nil } +func (g *GroupInfo) RemoveMember(uin int64) { + if g.memLock == nil { + g.memLock = new(sync.Mutex) + } + g.memLock.Lock() + defer g.memLock.Unlock() + for i, m := range g.Members { + if m.Uin == uin { + g.Members = append(g.Members[:i], g.Members[i+1:]...) + break + } + } +} + func (c *QQClient) connect() error { conn, err := net.Dial("tcp", "125.94.60.146:80") //TODO: more servers if err != nil { diff --git a/client/decoders.go b/client/decoders.go index 6d904b45..f40d3fb7 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -16,7 +16,7 @@ var ( groupLeaveLock = new(sync.Mutex) ) -func decodeLoginResponse(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeLoginResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) { reader := binary.NewReader(payload) reader.ReadUInt16() // sub command t := reader.ReadByte() @@ -100,7 +100,7 @@ func decodeLoginResponse(c *QQClient, seq uint16, payload []byte) (interface{}, return nil, nil // ? } -func decodeClientRegisterResponse(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeClientRegisterResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) { request := &jce.RequestPacket{} request.ReadFrom(jce.NewJceReader(payload)) data := &jce.RequestDataVersion2{} @@ -108,7 +108,7 @@ func decodeClientRegisterResponse(c *QQClient, seq uint16, payload []byte) (inte return nil, nil } -func decodePushReqPacket(c *QQClient, s uint16, payload []byte) (interface{}, error) { +func decodePushReqPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) { request := &jce.RequestPacket{} request.ReadFrom(jce.NewJceReader(payload)) data := &jce.RequestDataVersion2{} @@ -122,7 +122,7 @@ func decodePushReqPacket(c *QQClient, s uint16, payload []byte) (interface{}, er return nil, c.send(pkt) } -func decodeMessageSvcPacket(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeMessageSvcPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) { rsp := msg.GetMessageResponse{} err := proto.Unmarshal(payload, &rsp) if err != nil { @@ -198,7 +198,7 @@ func decodeMessageSvcPacket(c *QQClient, seq uint16, payload []byte) (interface{ return nil, err } -func decodeGroupMessagePacket(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeGroupMessagePacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) { pkt := msg.PushMessagePacket{} err := proto.Unmarshal(payload, &pkt) if err != nil { @@ -215,12 +215,12 @@ func decodeGroupMessagePacket(c *QQClient, seq uint16, payload []byte) (interfac return nil, nil } -func decodeSvcNotify(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeSvcNotify(c *QQClient, _ uint16, _ []byte) (interface{}, error) { _, pkt := c.buildGetMessageRequestPacket(msg.SyncFlag_START, time.Now().Unix()) return nil, c.send(pkt) } -func decodeFriendGroupListResponse(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeFriendGroupListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) { request := &jce.RequestPacket{} request.ReadFrom(jce.NewJceReader(payload)) data := &jce.RequestDataVersion3{} @@ -245,7 +245,7 @@ func decodeFriendGroupListResponse(c *QQClient, seq uint16, payload []byte) (int return rsp, nil } -func decodeGroupListResponse(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeGroupListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) { request := &jce.RequestPacket{} request.ReadFrom(jce.NewJceReader(payload)) data := &jce.RequestDataVersion3{} @@ -268,7 +268,7 @@ func decodeGroupListResponse(c *QQClient, seq uint16, payload []byte) (interface return l, nil } -func decodeGroupMemberListResponse(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeGroupMemberListResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) { request := &jce.RequestPacket{} request.ReadFrom(jce.NewJceReader(payload)) data := &jce.RequestDataVersion3{} @@ -302,7 +302,7 @@ func decodeGroupMemberListResponse(c *QQClient, seq uint16, payload []byte) (int }, nil } -func decodeGroupImageStoreResponse(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) { pkt := pb.D388RespBody{} err := proto.Unmarshal(payload, &pkt) if err != nil { @@ -412,7 +412,7 @@ func decodeOnlinePushReqPacket(c *QQClient, seq uint16, payload []byte) (interfa return nil, nil } -func decodeOnlinePushTransPacket(c *QQClient, seq uint16, payload []byte) (interface{}, error) { +func decodeOnlinePushTransPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) { info := msg.TransMsgInfo{} err := proto.Unmarshal(payload, &info) if err != nil { @@ -422,14 +422,14 @@ func decodeOnlinePushTransPacket(c *QQClient, seq uint16, payload []byte) (inter if info.MsgType == 34 { data.ReadInt32() data.ReadByte() - _ = int64(uint32(data.ReadInt32())) + target := int64(uint32(data.ReadInt32())) typ := int32(data.ReadByte()) operator := int64(uint32(data.ReadInt32())) - switch typ { - case 0x03: - groupLeaveLock.Lock() - defer groupLeaveLock.Unlock() - if g := c.FindGroup(info.FromUin); g != nil { + if g := c.FindGroup(info.FromUin); g != nil { + switch typ { + case 0x03: + groupLeaveLock.Lock() + defer groupLeaveLock.Unlock() if err = c.ReloadGroupList(); err != nil { return nil, err } @@ -437,6 +437,23 @@ func decodeOnlinePushTransPacket(c *QQClient, seq uint16, payload []byte) (inter Group: g, Operator: g.FindMember(operator), }) + case 0x82: + if m := g.FindMember(target); m != nil { + g.RemoveMember(m.Uin) + c.dispatchMemberLeaveEvent(&MemberLeaveGroupEvent{ + Group: g, + Member: m, + }) + } + case 0x83: + if m := g.FindMember(target); m != nil { + g.RemoveMember(m.Uin) + c.dispatchMemberLeaveEvent(&MemberLeaveGroupEvent{ + Group: g, + Member: m, + Operator: g.FindMember(operator), + }) + } } } diff --git a/client/entities.go b/client/entities.go index 9a71e2ac..e94841af 100644 --- a/client/entities.go +++ b/client/entities.go @@ -1,6 +1,9 @@ package client -import "errors" +import ( + "errors" + "sync" +) var ( ErrAlreadyRunning = errors.New("already running") @@ -47,6 +50,8 @@ type ( MemberCount uint16 MaxMemberCount uint16 Members []*GroupMemberInfo + + memLock *sync.Mutex } GroupMemberInfo struct { @@ -81,6 +86,12 @@ type ( Operator *GroupMemberInfo } + MemberLeaveGroupEvent struct { + Group *GroupInfo + Member *GroupMemberInfo + Operator *GroupMemberInfo + } + groupMemberListResponse struct { NextUin int64 list []*GroupMemberInfo diff --git a/client/events.go b/client/events.go index f719a7a9..dead4f4a 100644 --- a/client/events.go +++ b/client/events.go @@ -13,6 +13,7 @@ type eventHandlers struct { joinGroupHandlers []func(*QQClient, *GroupInfo) leaveGroupHandlers []func(*QQClient, *GroupLeaveEvent) memberJoinedHandlers []func(*QQClient, *GroupInfo, *GroupMemberInfo) + memberLeavedHandlers []func(*QQClient, *MemberLeaveGroupEvent) groupMessageReceiptHandlers sync.Map } @@ -48,6 +49,10 @@ func (c *QQClient) OnGroupMemberJoined(f func(*QQClient, *GroupInfo, *GroupMembe c.eventHandlers.memberJoinedHandlers = append(c.eventHandlers.memberJoinedHandlers, f) } +func (c *QQClient) OnGroupMemberLeaved(f func(*QQClient, *MemberLeaveGroupEvent)) { + c.eventHandlers.memberLeavedHandlers = append(c.eventHandlers.memberLeavedHandlers, f) +} + func (c *QQClient) OnGroupMessageRecalled(f func(*QQClient, *GroupMessageRecalledEvent)) { c.eventHandlers.groupRecalledHandlers = append(c.eventHandlers.groupRecalledHandlers, f) } @@ -143,6 +148,17 @@ func (c *QQClient) dispatchNewMemberEvent(group *GroupInfo, mem *GroupMemberInfo } } +func (c *QQClient) dispatchMemberLeaveEvent(e *MemberLeaveGroupEvent) { + if e == nil { + return + } + for _, f := range c.eventHandlers.memberLeavedHandlers { + cover(func() { + f(c, e) + }) + } +} + func (c *QQClient) dispatchGroupMessageReceiptEvent(e *groupMessageReceiptEvent) { c.eventHandlers.groupMessageReceiptHandlers.Range(func(_, f interface{}) bool { go f.(func(*QQClient, *groupMessageReceiptEvent))(c, e)