Skip to content

Commit

Permalink
feat: 补充陌生人信息
Browse files Browse the repository at this point in the history
  • Loading branch information
Redmomn committed Nov 27, 2024
1 parent 566cbd2 commit 2b65455
Show file tree
Hide file tree
Showing 14 changed files with 209 additions and 49 deletions.
8 changes: 4 additions & 4 deletions client/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (c *QQClient) GetUin(uid string, groupUin ...uint32) uint32 {
}

// GetCachedFriendInfo 获取好友信息(缓存)
func (c *QQClient) GetCachedFriendInfo(uin uint32) *entity.Friend {
func (c *QQClient) GetCachedFriendInfo(uin uint32) *entity.User {
if c.cache.FriendCacheIsEmpty() {
if err := c.RefreshFriendCache(); err != nil {
return nil
Expand All @@ -46,7 +46,7 @@ func (c *QQClient) GetCachedFriendInfo(uin uint32) *entity.Friend {
}

// GetCachedAllFriendsInfo 获取所有好友信息(缓存)
func (c *QQClient) GetCachedAllFriendsInfo() map[uint32]*entity.Friend {
func (c *QQClient) GetCachedAllFriendsInfo() map[uint32]*entity.User {
if c.cache.FriendCacheIsEmpty() {
if err := c.RefreshFriendCache(); err != nil {
return nil
Expand Down Expand Up @@ -198,8 +198,8 @@ func (c *QQClient) RefreshAllRkeyInfoCache() error {
}

// GetFriendsData 获取好友列表数据
func (c *QQClient) GetFriendsData() (map[uint32]*entity.Friend, error) {
friendsData := make(map[uint32]*entity.Friend)
func (c *QQClient) GetFriendsData() (map[uint32]*entity.User, error) {
friendsData := make(map[uint32]*entity.User)
friends, token, err := c.FetchFriends(0)
if err != nil {
return friendsData, err
Expand Down
2 changes: 1 addition & 1 deletion client/entity/avatar.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package entity

import "fmt"

func FriendAvatar(uin uint32) string {
func UserAvatar(uin uint32) string {
return fmt.Sprintf("https://q1.qlogo.cn/g?b=qq&nk=%v&s=640", uin)
}

Expand Down
12 changes: 0 additions & 12 deletions client/entity/friend.go

This file was deleted.

22 changes: 22 additions & 0 deletions client/entity/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package entity

type User struct {
Uin uint32
UID string
Nickname string
Remarks string
PersonalSign string
Avatar string
Age uint32
Sex uint32 // 1男 2女 255不可见
Level uint32
Source string // 好友来源

QID string

Country string
City string
School string

VipLevel uint32
}
2 changes: 1 addition & 1 deletion client/internal/cache/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func typenameof[T any]() string {

var cacheTypesMap = map[string]cacheType{
typenameof[Cache](): cacheTypeCache,
typenameof[entity.Friend](): cacheTypeFriend,
typenameof[entity.User](): cacheTypeFriend,
typenameof[entity.Group](): cacheTypeGroupInfo,
typenameof[entity.GroupMember](): cacheTypeGroupMember,
typenameof[entity.RKeyInfo](): cacheTypeRKey,
Expand Down
16 changes: 8 additions & 8 deletions client/internal/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
// GetUID 根据uin获取uid
func (c *Cache) GetUID(uin uint32, groupUin ...uint32) string {
if len(groupUin) == 0 {
if friend, ok := getCacheOf[entity.Friend](c, uin); ok {
if friend, ok := getCacheOf[entity.User](c, uin); ok {
return friend.UID
}
return ""
Expand All @@ -23,7 +23,7 @@ func (c *Cache) GetUID(uin uint32, groupUin ...uint32) string {
// GetUin 根据uid获取uin
func (c *Cache) GetUin(uid string, groupUin ...uint32) (uin uint32) {
if len(groupUin) == 0 {
rangeCacheOf[entity.Friend](c, func(k uint32, friend *entity.Friend) bool {
rangeCacheOf[entity.User](c, func(k uint32, friend *entity.User) bool {
if friend.UID == uid {
uin = k
return false
Expand All @@ -46,15 +46,15 @@ func (c *Cache) GetUin(uid string, groupUin ...uint32) (uin uint32) {
}

// GetFriend 获取好友信息
func (c *Cache) GetFriend(uin uint32) *entity.Friend {
v, _ := getCacheOf[entity.Friend](c, uin)
func (c *Cache) GetFriend(uin uint32) *entity.User {
v, _ := getCacheOf[entity.User](c, uin)
return v
}

// GetAllFriends 获取所有好友信息
func (c *Cache) GetAllFriends() map[uint32]*entity.Friend {
friends := make(map[uint32]*entity.Friend, 64)
rangeCacheOf[entity.Friend](c, func(k uint32, friend *entity.Friend) bool {
func (c *Cache) GetAllFriends() map[uint32]*entity.User {
friends := make(map[uint32]*entity.User, 64)
rangeCacheOf[entity.User](c, func(k uint32, friend *entity.User) bool {
friends[k] = friend
return true
})
Expand Down Expand Up @@ -116,7 +116,7 @@ func (c *Cache) GetAllRkeyInfo() entity.RKeyMap {

// FriendCacheIsEmpty 好友信息缓存是否为空
func (c *Cache) FriendCacheIsEmpty() bool {
return !hasRefreshed[entity.Friend](c)
return !hasRefreshed[entity.User](c)
}

// GroupMembersCacheIsEmpty 群成员缓存是否为空
Expand Down
6 changes: 3 additions & 3 deletions client/internal/cache/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

func (c *Cache) RefreshAll(
friendCache map[uint32]*entity.Friend,
friendCache map[uint32]*entity.User,
groupCache map[uint32]*entity.Group,
groupMemberCache map[uint32]map[uint32]*entity.GroupMember,
rkeyCache entity.RKeyMap,
Expand All @@ -17,12 +17,12 @@ func (c *Cache) RefreshAll(
}

// RefreshFriend 刷新一个好友的缓存
func (c *Cache) RefreshFriend(friend *entity.Friend) {
func (c *Cache) RefreshFriend(friend *entity.User) {
setCacheOf(c, friend.Uin, friend)
}

// RefreshAllFriend 刷新所有好友缓存
func (c *Cache) RefreshAllFriend(friendCache map[uint32]*entity.Friend) {
func (c *Cache) RefreshAllFriend(friendCache map[uint32]*entity.User) {
refreshAllCacheOf(c, friendCache)
}

Expand Down
10 changes: 5 additions & 5 deletions client/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (c *QQClient) SetOnlineStatus(status, ext, battery uint32) error {
}

// FetchFriends 获取好友列表信息,使用token可以获取下一页的群成员信息
func (c *QQClient) FetchFriends(token uint32) ([]*entity.Friend, uint32, error) {
func (c *QQClient) FetchFriends(token uint32) ([]*entity.User, uint32, error) {
pkt, err := oidb2.BuildFetchFriendsReq(token)
if err != nil {
return nil, 0, err
Expand Down Expand Up @@ -490,7 +490,7 @@ func (c *QQClient) QueryFriendImage(md5 []byte, fileUUID string) (*message2.Imag
}

// FetchUserInfo 获取用户信息
func (c *QQClient) FetchUserInfo(uid string) (*entity.Friend, error) {
func (c *QQClient) FetchUserInfo(uid string) (*entity.User, error) {
pkt, err := oidb2.BuildFetchUserInfoReq(uid)
if err != nil {
return nil, err
Expand All @@ -503,7 +503,7 @@ func (c *QQClient) FetchUserInfo(uid string) (*entity.Friend, error) {
}

// FetchUserInfoUin 通过uin获取用户信息
func (c *QQClient) FetchUserInfoUin(uin uint32) (*entity.Friend, error) {
func (c *QQClient) FetchUserInfoUin(uin uint32) (*entity.User, error) {
pkt, err := oidb2.BuildFetchUserInfoReq(uin)
if err != nil {
return nil, err
Expand Down Expand Up @@ -1278,7 +1278,7 @@ func (c *QQClient) SendGroupSign(groupUin uint32) (*oidb2.BotGroupClockInResult,

// GetUnidirectionalFriendList 获取单向好友列表
// ref https://github.com/Mrs4s/MiraiGo/blob/54bdd873e3fed9fe1c944918924674dacec5ac76/client/web.go#L23
func (c *QQClient) GetUnidirectionalFriendList() (ret []*entity.Friend, err error) {
func (c *QQClient) GetUnidirectionalFriendList() (ret []*entity.User, err error) {
webRsp := &struct {
BlockList []struct {
Uin uint32 `json:"uint64_uin"`
Expand Down Expand Up @@ -1308,7 +1308,7 @@ func (c *QQClient) GetUnidirectionalFriendList() (ret []*entity.Friend, err erro
}
return utils.B2S(b)
}
ret = append(ret, &entity.Friend{
ret = append(ret, &entity.User{
Uin: block.Uin,
UID: block.UID,
Nickname: decodeBase64String(block.NickBytes),
Expand Down
8 changes: 4 additions & 4 deletions client/packets/oidb/fetch_friends.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func BuildFetchFriendsReq(token uint32) (*Packet, error) {
return BuildOidbPacket(0xFD4, 1, &body, false, false)
}

func ParseFetchFriendsResp(data []byte) ([]*entity.Friend, uint32, error) {
func ParseFetchFriendsResp(data []byte) ([]*entity.User, uint32, error) {
var resp oidb.OidbSvcTrpcTcp0XFD4_1Response
var next uint32
if _, err := ParseOidbPacket(data, &resp); err != nil {
Expand All @@ -45,18 +45,18 @@ func ParseFetchFriendsResp(data []byte) ([]*entity.Friend, uint32, error) {
} else {
next = resp.Next.Uin
}
friends := make([]*entity.Friend, len(resp.Friends))
friends := make([]*entity.User, len(resp.Friends))
interner := utils.NewStringInterner()
for i, raw := range resp.Friends {
additional := getFirstFriendAdditionalTypeEqualTo1(raw.Additional)
properties := parseFriendProperty(additional.Layer1.Properties)
friends[i] = &entity.Friend{
friends[i] = &entity.User{
Uin: raw.Uin,
UID: interner.Intern(raw.Uid),
Nickname: interner.Intern(properties[20002]),
Remarks: interner.Intern(properties[103]),
PersonalSign: interner.Intern(properties[102]),
Avatar: interner.Intern(entity.FriendAvatar(raw.Uin)),
Avatar: interner.Intern(entity.UserAvatar(raw.Uin)),
}
}
return friends, next, nil
Expand Down
2 changes: 1 addition & 1 deletion client/packets/oidb/fetch_member.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func ParseFetchMemberResp(data []byte) (*entity.GroupMember, error) {
JoinTime: member.JoinTimestamp,
LastMsgTime: member.LastMsgTimestamp,
ShutUpTime: member.ShutUpTimestamp.Unwrap(),
Avatar: interner.Intern(entity.FriendAvatar(member.Uin.Uin)),
Avatar: interner.Intern(entity.UserAvatar(member.Uin.Uin)),
}
if member.Level != nil {
m.GroupLevel = member.Level.Level
Expand Down
2 changes: 1 addition & 1 deletion client/packets/oidb/fetch_members.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func ParseFetchMembersResp(data []byte) ([]*entity.GroupMember, string, error) {
JoinTime: member.JoinTimestamp,
LastMsgTime: member.LastMsgTimestamp,
ShutUpTime: member.ShutUpTimestamp.Unwrap(),
Avatar: interner.Intern(entity.FriendAvatar(member.Uin.Uin)),
Avatar: interner.Intern(entity.UserAvatar(member.Uin.Uin)),
}
if member.Level != nil {
m.GroupLevel = member.Level.Level
Expand Down
66 changes: 57 additions & 9 deletions client/packets/oidb/fetch_user_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,33 @@ import (
"github.com/LagrangeDev/LagrangeGo/client/entity"
"github.com/LagrangeDev/LagrangeGo/client/packets/pb/service/oidb"
"github.com/LagrangeDev/LagrangeGo/internal/proto"
"github.com/LagrangeDev/LagrangeGo/utils"
)

func BuildFetchUserInfoReq[T ~string | ~uint32](value T) (*Packet, error) {
keys := []uint32{20002, 27394, 20009, 20031, 101, 103, 102, 20022, 20023, 20024, 24002, 27037, 27049, 20011, 20016, 20021, 20003, 20004, 20005, 20006, 20020, 20026, 24007, 104, 105, 42432, 42362, 41756, 41757, 42257, 27372, 42315, 107, 45160, 45161, 27406, 62026, 20037}
keys := []uint32{101, //头像
102, // 简介/签名
103, // 备注
104,
105, // 等级
107, // 业务列表
20002, // 昵称
20003, // 国家
20004, 20005, 20006,
20009, // 性别
20011, 20016,
20020, // 城市
20021, // 学校
20022, 20023, 20024,
20026, // 注册时间
20031, // 生日
20037, // 年龄
24002, 24007, 27037, 27049,
27372, // 状态
27394, // QID
27406, // 自定义状态文本
41756, 41757, 42257, 42315, 42362, 42432, 45160, 45161, 62026,
}
keyList := make([]*oidb.OidbSvcTrpcTcp0XFE1_2Key, len(keys))
for i, key := range keys {
keyList[i] = &oidb.OidbSvcTrpcTcp0XFE1_2Key{Key: key}
Expand All @@ -31,23 +54,48 @@ func BuildFetchUserInfoReq[T ~string | ~uint32](value T) (*Packet, error) {
return nil, nil
}

func ParseFetchUserInfoResp(data []byte) (*entity.Friend, error) {
func ParseFetchUserInfoResp(data []byte) (*entity.User, error) {
var resp oidb.OidbSvcTrpcTcp0XFE1_2Response
_, err := ParseOidbPacket(data, &resp)
if err != nil {
return nil, err
}
nickName := func() string {

stringProperties := func() map[uint32]string {
p := make(map[uint32]string)
for _, property := range resp.Body.Properties.StringProperties {
if property.Code == 20002 {
return property.Value
}
p[property.Code] = property.Value
}
return p
}()
numProperties := func() map[uint32]uint32 {
p := make(map[uint32]uint32)
for _, propetry := range resp.Body.Properties.NumberProperties {
p[propetry.Number1] = propetry.Number2
}
return ""
return p
}()
return &entity.Friend{

var business oidb.Business
_ = proto.Unmarshal(utils.S2B(stringProperties[107]), &business)

return &entity.User{
Uin: resp.Body.Uin,
//UID: resp.Body.UID,
Nickname: nickName,
Avatar: stringProperties[101],
QID: stringProperties[27394],
Nickname: stringProperties[20002],
PersonalSign: stringProperties[102],
Sex: numProperties[20009],
Age: numProperties[20037],
Level: numProperties[105],
VipLevel: func() uint32 {
for _, b := range business.Body.Lists {
if b.Type == 1 {
return b.Level
}
}
return 0
}(),
}, nil
}
Loading

0 comments on commit 2b65455

Please sign in to comment.