diff --git a/cache/cache.go b/cache/cache.go new file mode 100644 index 00000000..c73f6a97 --- /dev/null +++ b/cache/cache.go @@ -0,0 +1,107 @@ +package cache + +import "github.com/LagrangeDev/LagrangeGo/entity" + +// GetUid 根据uin获取uid +func (c *Cache) GetUid(uin uint32, groupUin ...uint32) string { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + if len(groupUin) == 0 { + if friend, ok := c.FriendCache[uin]; ok { + return friend.Uid + } + } else { + if group, ok := c.GroupMemberCache[groupUin[0]]; ok { + if member, ok := group[uin]; ok { + return member.Uid + } + } + } + return "" +} + +// GetUin 根据uid获取uin +func (c *Cache) GetUin(uid string, groupUin ...uint32) uint32 { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + if len(groupUin) == 0 { + for uin, friend := range c.FriendCache { + if friend.Uid == uid { + return uin + } + } + } else { + if group, ok := c.GroupMemberCache[groupUin[0]]; ok { + for uin, member := range group { + if member.Uid == uid { + return uin + } + } + } + } + return 0 +} + +// GetFriend 获取好友信息 +func (c *Cache) GetFriend(uin uint32) *entity.Friend { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + return c.FriendCache[uin] +} + +// GetGroup 获取群聊信息 +func (c *Cache) GetGroup(groupUin uint32) *entity.Group { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + return c.GroupCache[groupUin] +} + +// GetAllGroups 获取所有群聊信息 +func (c *Cache) GetAllGroups() map[uint32]*entity.Group { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + groups := make(map[uint32]*entity.Group, len(c.GroupCache)) + for group, grpInfo := range c.GroupCache { + groups[group] = grpInfo + } + return groups +} + +// GetGroupMember 获取群成员信息 +func (c *Cache) GetGroupMember(uin, groupUin uint32) *entity.GroupMember { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + if group, ok := c.GroupMemberCache[groupUin]; ok { + return group[uin] + } + return nil +} + +// GetGroupMembers 获取指定群所有群成员信息 +func (c *Cache) GetGroupMembers(groupUin uint32) map[uint32]*entity.GroupMember { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + members := make(map[uint32]*entity.GroupMember, len(c.GroupMemberCache)) + for _, member := range c.GroupMemberCache[groupUin] { + members[member.Uin] = member + } + return members +} + +func (c *Cache) FriendCacheIsEmpty() bool { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + return len(c.FriendCache) == 0 +} + +func (c *Cache) GroupCacheIsEmpty() bool { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + return len(c.GroupMemberCache) == 0 +} + +func (c *Cache) GroupMemberCacheIsEmpty(groupUin uint32) bool { + c.refreshLock.RLock() + defer c.refreshLock.RUnlock() + return len(c.GroupMemberCache[groupUin]) == 0 +} diff --git a/cache/operation.go b/cache/operation.go index 25dfb64e..37d75c31 100644 --- a/cache/operation.go +++ b/cache/operation.go @@ -12,6 +12,13 @@ func (c *Cache) RefreshAll(friendCache map[uint32]*entity.Friend, groupCache map c.GroupCache = groupCache } +// RefreshFriend 刷新一个好友的缓存 +func (c *Cache) RefreshFriend(friend *entity.Friend) { + c.refreshLock.Lock() + defer c.refreshLock.Unlock() + c.FriendCache[friend.Uin] = friend +} + // RefreshAllFriend 刷新所有好友缓存 func (c *Cache) RefreshAllFriend(friendCache map[uint32]*entity.Friend) { c.refreshLock.Lock() @@ -19,25 +26,25 @@ func (c *Cache) RefreshAllFriend(friendCache map[uint32]*entity.Friend) { c.FriendCache = friendCache } -// RefreshAllGroup 刷新所有群的群消息缓存 -func (c *Cache) RefreshAllGroup(groupCache map[uint32]*entity.Group) { +// RefreshGroupMember 刷新指定群的一个群成员缓存 +func (c *Cache) RefreshGroupMember(groupUin uint32, groupMember *entity.GroupMember) { c.refreshLock.Lock() defer c.refreshLock.Unlock() - c.GroupCache = groupCache + c.GroupMemberCache[groupUin][groupMember.Uin] = groupMember } -// RefreshAllGroupMember 刷新所有群的群员缓存 -func (c *Cache) RefreshAllGroupMember(groupMemberCache map[uint32]map[uint32]*entity.GroupMember) { +// RefreshGroupMembers 刷新一个群内的所有群成员缓存 +func (c *Cache) RefreshGroupMembers(groupUin uint32, groupMembers map[uint32]*entity.GroupMember) { c.refreshLock.Lock() defer c.refreshLock.Unlock() - c.GroupMemberCache = groupMemberCache + c.GroupMemberCache[groupUin] = groupMembers } -// RefreshFriend 刷新一个好友的缓存 -func (c *Cache) RefreshFriend(friend *entity.Friend) { +// RefreshAllGroupMembers 刷新所有群的群员缓存 +func (c *Cache) RefreshAllGroupMembers(groupMemberCache map[uint32]map[uint32]*entity.GroupMember) { c.refreshLock.Lock() defer c.refreshLock.Unlock() - c.FriendCache[friend.Uin] = friend + c.GroupMemberCache = groupMemberCache } // RefreshGroup 刷新一个群的群信息缓存 @@ -47,16 +54,9 @@ func (c *Cache) RefreshGroup(group *entity.Group) { c.GroupCache[group.GroupUin] = group } -// RefreshGroupMember 刷新指定群的一个群成员缓存 -func (c *Cache) RefreshGroupMember(groupUin uint32, groupMember *entity.GroupMember) { - c.refreshLock.Lock() - defer c.refreshLock.Unlock() - c.GroupMemberCache[groupUin][groupMember.Uin] = groupMember -} - -// RefreshGroupMembers 刷新一个群内的所有群成员缓存 -func (c *Cache) RefreshGroupMembers(groupUin uint32, groupMembers map[uint32]*entity.GroupMember) { +// RefreshAllGroup 刷新所有群的群信息缓存 +func (c *Cache) RefreshAllGroup(groupCache map[uint32]*entity.Group) { c.refreshLock.Lock() defer c.refreshLock.Unlock() - c.GroupMemberCache[groupUin] = groupMembers + c.GroupCache = groupCache } diff --git a/client/base.go b/client/base.go index 76d50e4a..7d89c93d 100644 --- a/client/base.go +++ b/client/base.go @@ -5,6 +5,8 @@ import ( "sync/atomic" "time" + "github.com/LagrangeDev/LagrangeGo/cache" + "github.com/LagrangeDev/LagrangeGo/entity" "github.com/LagrangeDev/LagrangeGo/event" @@ -30,6 +32,7 @@ func NewQQclient(uin uint32, signUrl string, appInfo *info.AppInfo, deviceInfo * pushStore: make(chan *wtlogin.SSOPacket, 128), stopChan: make(chan struct{}), tcp: NewTCPClient(Server, 5), + cache: cache.NewCache(), } client.Online.Store(false) return client @@ -53,6 +56,7 @@ type QQClient struct { tcp *TCPClient + cache *cache.Cache friendCache map[uint32]*entity.Friend groupCache map[uint32]map[uint32]*entity.GroupMember diff --git a/client/cache.go b/client/cache.go index 6a93952c..fa69f7f8 100644 --- a/client/cache.go +++ b/client/cache.go @@ -4,69 +4,62 @@ import ( "github.com/LagrangeDev/LagrangeGo/entity" ) -// GetUidFromFriends 获取缓存中对应qq的uid,仅限好友 -func (c *QQClient) GetUidFromFriends(uin uint32) string { - c.refreshLock.RLock() - defer c.refreshLock.RUnlock() - if friend, ok := c.friendCache[uin]; ok { - return friend.Uid +// GetUid 获取缓存中对应qq的uid,仅限好友 +func (c *QQClient) GetUid(uin uint32, groupUin ...uint32) string { + if c.cache.FriendCacheIsEmpty() { + c.RefreshFriendCache() } - return "" + return c.cache.GetUid(uin, groupUin...) } -func (c *QQClient) GetUidFromGroup(uin, groupUin uint32) string { - c.refreshLock.RLock() - defer c.refreshLock.RUnlock() - if group, ok := c.groupCache[groupUin]; ok { - if member, ok := group[uin]; ok { - return member.Uid - } +// GetFriendInfo 获取好友信息 +func (c *QQClient) GetFriendInfo(uin uint32) *entity.Friend { + if c.cache.FriendCacheIsEmpty() { + c.RefreshFriendCache() } - return "" + return c.cache.GetFriend(uin) } +// GetMemberInfo 获取群成员信息 func (c *QQClient) GetMemberInfo(uin, groupUin uint32) *entity.GroupMember { - c.refreshLock.RLock() - defer c.refreshLock.RUnlock() - if group, ok := c.groupCache[groupUin]; ok { - if member, ok := group[uin]; ok { - return member - } + if c.cache.GroupMemberCacheIsEmpty(groupUin) { + c.RefreshGroupMembersCache(groupUin) + } + return c.cache.GetGroupMember(uin, groupUin) +} + +func (c *QQClient) GetMembersInfo(groupUin uint32) map[uint32]*entity.GroupMember { + if c.cache.GroupMemberCacheIsEmpty(groupUin) { + c.RefreshGroupMembersCache(groupUin) } - return nil + return c.cache.GetGroupMembers(groupUin) } +// RefreshFriendCache 刷新好友缓存 func (c *QQClient) RefreshFriendCache() { friendsData, err := c.GetFriendsData() if err != nil { return } - c.refreshLock.Lock() - defer c.refreshLock.Unlock() - c.friendCache = friendsData + c.cache.RefreshAllFriend(friendsData) } -func (c *QQClient) RefreshGroupCache(groupUin uint32) { +// RefreshGroupMembersCache 刷新指定群的群成员员缓存 +func (c *QQClient) RefreshGroupMembersCache(groupUin uint32) { groupData, err := c.GetGroupMembersData(groupUin) if err != nil { return } - c.refreshLock.Lock() - defer c.refreshLock.Unlock() - if c.groupCache == nil { - c.groupCache = make(map[uint32]map[uint32]*entity.GroupMember) - } - c.groupCache[groupUin] = groupData + c.cache.RefreshGroupMembers(groupUin, groupData) } +// RefreshAllGroupCache 刷新所有群的群成员缓存 func (c *QQClient) RefreshAllGroupCache() { groupsData, err := c.GetAllGroupsMembersData() if err != nil { return } - c.refreshLock.Lock() - defer c.refreshLock.Unlock() - c.groupCache = groupsData + c.cache.RefreshAllGroupMembers(groupsData) } // GetFriendsData 获取好友列表数据 @@ -83,24 +76,6 @@ func (c *QQClient) GetFriendsData() (map[uint32]*entity.Friend, error) { return friendsData, err } -// GetAllGroupsMembersData 获取所有群的群成员信息 -func (c *QQClient) GetAllGroupsMembersData() (map[uint32]map[uint32]*entity.GroupMember, error) { - groups, err := c.FetchGroups() - if err != nil { - return nil, err - } - groupsData := make(map[uint32]map[uint32]*entity.GroupMember, len(groups)) - for _, group := range groups { - groupMembersData, err := c.GetGroupMembersData(group.GroupUin) - if err != nil { - return nil, err - } - groupsData[group.GroupUin] = groupMembersData - } - loginLogger.Infof("获取%d个群和成员信息", len(groupsData)) - return groupsData, err -} - // GetGroupMembersData 获取指定群所有成员信息 func (c *QQClient) GetGroupMembersData(groupUin uint32) (map[uint32]*entity.GroupMember, error) { groupMembers := make(map[uint32]*entity.GroupMember) @@ -122,3 +97,21 @@ func (c *QQClient) GetGroupMembersData(groupUin uint32) (map[uint32]*entity.Grou } return groupMembers, err } + +// GetAllGroupsMembersData 获取所有群的群成员信息 +func (c *QQClient) GetAllGroupsMembersData() (map[uint32]map[uint32]*entity.GroupMember, error) { + groups, err := c.FetchGroups() + if err != nil { + return nil, err + } + groupsData := make(map[uint32]map[uint32]*entity.GroupMember, len(groups)) + for _, group := range groups { + groupMembersData, err := c.GetGroupMembersData(group.GroupUin) + if err != nil { + return nil, err + } + groupsData[group.GroupUin] = groupMembersData + } + loginLogger.Infof("获取%d个群和成员信息", len(groupsData)) + return groupsData, err +}