diff --git a/packages/engine-chronocat-api/src/api/friend/list.ts b/packages/engine-chronocat-api/src/api/friend/list.ts index 0d6c9a7..30aa641 100644 --- a/packages/engine-chronocat-api/src/api/friend/list.ts +++ b/packages/engine-chronocat-api/src/api/friend/list.ts @@ -22,12 +22,6 @@ export const buildFriendList = await ctx.chronocat.sleep(1000) return { - data: Object.values(friendMap).map((x) => ({ - id: x.uin, - name: x.nick, - nick: x.remark || undefined, - avatar: `http://thirdqq.qlogo.cn/headimg_dl?dst_uin=${x.uin}&spec=640`, - is_bot: false, - })), + data: Object.values(friendMap), } } diff --git a/packages/engine-chronocat-api/src/globalVars.ts b/packages/engine-chronocat-api/src/globalVars.ts index ce8bc66..0080da4 100644 --- a/packages/engine-chronocat-api/src/globalVars.ts +++ b/packages/engine-chronocat-api/src/globalVars.ts @@ -1,4 +1,5 @@ -import type { Group, Profile, RedIpcData, RedMessage } from '@chronocat/red' +import type { Group, RedIpcData, RedMessage } from '@chronocat/red' +import { User } from '@chronocat/shell' import { ChronoEventEmitter } from './emitter' export const requestMethodMap: Record = {} @@ -9,7 +10,7 @@ export const requestCallbackMap: Record< export const groupMap: Record = {} export const roleMap: Record> = {} -export const friendMap: Record = {} +export const friendMap: Record = {} export const richMediaDownloadMap: Record void> = {} export const emojiDownloadMap: Record void> = {} diff --git a/packages/engine-chronocat-api/src/handler.ts b/packages/engine-chronocat-api/src/handler.ts index 57a54db..6e37b79 100644 --- a/packages/engine-chronocat-api/src/handler.ts +++ b/packages/engine-chronocat-api/src/handler.ts @@ -220,24 +220,59 @@ const responseDispatcher = async ( case 'onBuddyListChange': case 'nodeIKernelBuddyListener/onBuddyListChange': { - const { data } = payload as OnBuddyListChange - - for (const category of data) { - for (const buddy of category.buddyList) { - ctx.chronocat.uix.add(buddy.uid, buddy.uin) - - ctx.chronocatEngineChronocatApi.msgBoxActiv.activate({ - chatType: ChatType.Private, - peerUid: buddy.uid, - guildId: '', - }) + const { data, buddyCategory, userSimpleInfos } = + payload as OnBuddyListChange + + if (data) { + for (const category of data) { + for (const buddy of category.buddyList) { + ctx.chronocat.uix.add(buddy.uid, buddy.uin) + + ctx.chronocatEngineChronocatApi.msgBoxActiv.activate({ + chatType: ChatType.Private, + peerUid: buddy.uid, + guildId: '', + }) + + // buddy.category = category.categoryName + friendMap[buddy.uin] = { + id: buddy.uin, + name: buddy.nick, + nick: buddy.remark || undefined, + avatar: `http://thirdqq.qlogo.cn/headimg_dl?dst_uin=${buddy.uin}&spec=640`, + is_bot: false, + } + } + } - // buddy.category = category.categoryName - friendMap[buddy.uin] = buddy + chronoEventEmitter.emitBuddyListChange() + } else if (buddyCategory && userSimpleInfos) { + // 先填充 uix + for (const uid in userSimpleInfos) + ctx.chronocat.uix.add(uid, userSimpleInfos[uid]!.uin) + + for (const category of buddyCategory) { + for (const uid of category.buddyUids) { + ctx.chronocatEngineChronocatApi.msgBoxActiv.activate({ + chatType: ChatType.Private, + peerUid: uid, + guildId: '', + }) + + const userSimpleInfo = userSimpleInfos[uid]! + + friendMap[userSimpleInfo.uin] = { + id: userSimpleInfo.uin, + name: userSimpleInfo.coreInfo.nick, + nick: userSimpleInfo.coreInfo.remark || undefined, + avatar: `http://thirdqq.qlogo.cn/headimg_dl?dst_uin=${userSimpleInfo.uin}&spec=640`, + is_bot: false, + } + } } - } - chronoEventEmitter.emitBuddyListChange() + chronoEventEmitter.emitBuddyListChange() + } return } diff --git a/packages/engine-chronocat-event/src/handler.ts b/packages/engine-chronocat-event/src/handler.ts index 7e59f96..2c93403 100644 --- a/packages/engine-chronocat-event/src/handler.ts +++ b/packages/engine-chronocat-event/src/handler.ts @@ -294,11 +294,17 @@ const dispatcher = async ( case 'onBuddyListChange': case 'nodeIKernelBuddyListener/onBuddyListChange': { - const { data } = payload as OnBuddyListChange - - for (const category of data) - for (const buddy of category.buddyList) - ctx.chronocat.uix.add(buddy.uid, buddy.uin) + const { data, buddyCategory, userSimpleInfos } = + payload as OnBuddyListChange + + if (data) { + for (const category of data) + for (const buddy of category.buddyList) + ctx.chronocat.uix.add(buddy.uid, buddy.uin) + } else if (buddyCategory && userSimpleInfos) { + for (const uid in userSimpleInfos) + ctx.chronocat.uix.add(uid, userSimpleInfos[uid]!.uin) + } return } diff --git a/packages/red/src/redIpcEntity.ts b/packages/red/src/redIpcEntity.ts index 6143267..6a27a30 100644 --- a/packages/red/src/redIpcEntity.ts +++ b/packages/red/src/redIpcEntity.ts @@ -108,27 +108,231 @@ export interface OnBuddyListChange { /** * 好友分组列表。 */ - data: { - /** - * 好友分组 ID。 - */ - categoryId: number + data: BuddyListChangeData[] | undefined - /** - * 好友分组名称。 - */ - categoryName: string + /** + * 好友分组列表。 + */ + buddyCategory: BuddyCategory[] | undefined - /** - * 分组内好友个数。 - */ - categroyMbCount: number + /** + * 用户信息,键为 uid。 + */ + userSimpleInfos: Record | undefined +} - /** - * 分组内好友列表。 - */ - buddyList: Profile[] - }[] +export interface BuddyListChangeData { + /** + * 好友分组 ID。 + */ + categoryId: number + + /** + * 好友分组名称。 + */ + categoryName: string + + /** + * 分组内好友个数。 + */ + categroyMbCount: number + + /** + * 分组内好友列表。 + */ + buddyList: Profile[] +} + +export interface BuddyCategory { + categoryId: number + + /** + * 数值越小,显示越在上方 + */ + categorySortId: number + + categroyName: string + + categroyMbCount: number + + onlineCount: number + + buddyUids: string[] +} + +export interface UserSimpleInfo { + uid: string + uin: string + coreInfo: UserCoreInfo + baseInfo: UserBaseInfo + status: UserStatus | null + vasInfo: UserVasInfo | null + relationFlags: UserRelationFlags + otherFlags: unknown + intimate: unknown +} + +export interface UserCoreInfo { + uid: string + uin: string + nick: string + + /** + * 无情况下为空字符串 + */ + remark: string +} + +export interface UserBaseInfo { + /** + * 无情况下为空字符串 + */ + qid: string + + /** + * 无情况下为空字符串 + */ + longNick: string + + /** + * 不显示情况下为 0 + */ + birthday_year: number + + /** + * 不显示情况下为 0 + */ + birthday_month: number + + /** + * 不显示情况下为 0 + */ + birthday_day: number + age: number + sex: number + eMail: string + phoneNum: string + categoryId: number + richTime: number + richBuffer: unknown +} + +export interface UserStatus { + uid: string + uin: string + status: number + extStatus: number + batteryStatus: number + termType: number + netType: number + iconType: number + customStatus: { + faceId: string + faceType: string + wording: string + } + setTime: string + specialFlag: number + abiFlag: number + eNetworkType: number + showName: string + termDesc: string + musicInfo: { + buf: unknown + } + extOnlineBusinessInfo: { + buf: unknown + customStatus: unknown + videoBizInfo: { + cid: string + tvUrl: string + synchType: string + } + videoInfo: { + name: string + } + } + extBuffer: { + buf: unknown + } +} + +export interface UserVasInfo { + /** + * 是否为 VIP + */ + vipFlag: boolean + + /** + * 是否为年费 VIP + */ + yearVipFlag: boolean + + /** + * 是否为 SVIP + */ + svipFlag: boolean + + /** + * VIP 等级 + */ + vipLevel: number + + /** + * 是否为大会员 + */ + bigClub: boolean + + /** + * 大会员等级 + */ + bigClubLevel: number + + nameplateVipType: number + grayNameplateFlag: number + superVipTemplateId: number + diyFontId: number + pendantId: number + pendantDiyId: number + faceId: number + vipFont: number + vipFontType: number + magicFont: number + fontEffect: number + newLoverDiamondFlag: number + extendNameplateId: number + diyNameplateIDs: unknown[] + vipStartFlag: number + vipDataFlag: number + gameNameplateId: string + gameLastLoginTime: string + gameRank: number + gameIconShowFlag: boolean + gameCardId: string + + /** + * VIP 昵称颜色类型 + */ + vipNameColorId: string + + privilegeIcon: null +} + +export interface UserRelationFlags { + topTime: string + isBlock: boolean + isMsgDisturb: boolean + isSpecialCareOpen: boolean + isSpecialCareZone: boolean + ringId: string + isBlocked: boolean + recommendImgFlag: number + disableEmojiShortCuts: number + qidianMasterFlag: number + qidianCrewFlag: number + qidianCrewFlag2: number + isHideQQLevel: number + isHidePrivilegeIcon: number } export interface OnAddSendMsg {