From be71abe580d4170abf02ce84d004117ef9709235 Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Fri, 9 Aug 2024 15:58:40 +0800 Subject: [PATCH] chore: fix indentation in files --- src/core/apis/file.ts | 519 +++++++++++++++---------------- src/core/apis/friend.ts | 49 +-- src/core/apis/group.ts | 668 +++++++++++++++++++++------------------- src/core/apis/sign.ts | 146 +++++---- src/core/apis/system.ts | 19 +- src/core/apis/user.ts | 599 +++++++++++++++++------------------ 6 files changed, 1045 insertions(+), 955 deletions(-) diff --git a/src/core/apis/file.ts b/src/core/apis/file.ts index 6b9a60a7..b54ae53b 100644 --- a/src/core/apis/file.ts +++ b/src/core/apis/file.ts @@ -1,9 +1,9 @@ import { - CacheFileListItem, - CacheFileType, - ChatCacheListItemBasic, - ChatType, - ElementType, IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, Peer, PicElement + CacheFileListItem, + CacheFileType, + ChatCacheListItemBasic, + ChatType, + ElementType, IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, Peer, PicElement } from '@/core/entities'; import path from 'path'; import fs from 'fs'; @@ -18,197 +18,197 @@ import { calculateFileMD5 } from '@/common/utils/file'; export class NTQQFileApi { - context: InstanceContext; - core: NapCatCore; - rkeyManager: RkeyManager; - constructor(context: InstanceContext, core: NapCatCore) { - this.context = context; - this.core = core; - this.rkeyManager = new RkeyManager('http://napcat-sign.wumiao.wang:2082/rkey', this.context.logger); - } - async getFileType(filePath: string) { - return fileType.fileTypeFromFile(filePath); - } + context: InstanceContext; + core: NapCatCore; + rkeyManager: RkeyManager; + constructor(context: InstanceContext, core: NapCatCore) { + this.context = context; + this.core = core; + this.rkeyManager = new RkeyManager('http://napcat-sign.wumiao.wang:2082/rkey', this.context.logger); + } + async getFileType(filePath: string) { + return fileType.fileTypeFromFile(filePath); + } - async copyFile(filePath: string, destPath: string) { - await this.context.wrapper.util.copyFile(filePath, destPath); - } + async copyFile(filePath: string, destPath: string) { + await this.context.wrapper.util.copyFile(filePath, destPath); + } - async getFileSize(filePath: string): Promise { - return await this.context.wrapper.util.getFileSize(filePath); - } - async getVideoUrl(peer: Peer, msgId: string, elementId: string) { - return (await this.context.session.getRichMediaService().getVideoPlayUrlV2(peer, msgId, elementId, 0, { downSourceType: 1, triggerType: 1 })).urlResult.domainUrl; - } - // 上传文件到QQ的文件夹 - async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC, elementSubType: number = 0) { + async getFileSize(filePath: string): Promise { + return await this.context.wrapper.util.getFileSize(filePath); + } + async getVideoUrl(peer: Peer, msgId: string, elementId: string) { + return (await this.context.session.getRichMediaService().getVideoPlayUrlV2(peer, msgId, elementId, 0, { downSourceType: 1, triggerType: 1 })).urlResult.domainUrl; + } + // 上传文件到QQ的文件夹 + async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC, elementSubType: number = 0) { // napCatCore.wrapper.util. - const fileMd5 = await calculateFileMD5(filePath); - let ext: string = (await this.getFileType(filePath))?.ext as string || ''; - if (ext) { - ext = '.' + ext; + const fileMd5 = await calculateFileMD5(filePath); + let ext: string = (await this.getFileType(filePath))?.ext as string || ''; + if (ext) { + ext = '.' + ext; + } + let fileName = `${path.basename(filePath)}`; + if (fileName.indexOf('.') === -1) { + fileName += ext; + } + const mediaPath = this.context.session.getMsgService().getRichMediaFilePathForGuild({ + md5HexStr: fileMd5, + fileName: fileName, + elementType: elementType, + elementSubType, + thumbSize: 0, + needCreate: true, + downloadType: 1, + file_uuid: '' + }); + await this.copyFile(filePath, mediaPath!); + const fileSize = await this.getFileSize(filePath); + return { + md5: fileMd5, + fileName, + path: mediaPath, + fileSize, + ext + }; } - let fileName = `${path.basename(filePath)}`; - if (fileName.indexOf('.') === -1) { - fileName += ext; - } - const mediaPath = this.context.session.getMsgService().getRichMediaFilePathForGuild({ - md5HexStr: fileMd5, - fileName: fileName, - elementType: elementType, - elementSubType, - thumbSize: 0, - needCreate: true, - downloadType: 1, - file_uuid: '' - }); - await this.copyFile(filePath, mediaPath!); - const fileSize = await this.getFileSize(filePath); - return { - md5: fileMd5, - fileName, - path: mediaPath, - fileSize, - ext - }; - } - async downloadMediaByUuid() { + async downloadMediaByUuid() { //napCatCore.session.getRichMediaService().downloadFileForFileUuid(); - } - // async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) { - // //logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force); - // // 用于下载收到的消息中的图片等 - // if (sourcePath && fs.existsSync(sourcePath)) { - // if (force) { - // try { - // await fsPromises.unlink(sourcePath); - // } catch (e) { - // // - // } - // } else { - // return sourcePath; - // } - // } - // const data = await this.core.eventWrapper.CallNormalEvent< - // ( - // params: { - // fileModelId: string, - // downloadSourceType: number, - // triggerType: number, - // msgId: string, - // chatType: ChatType, - // peerUid: string, - // elementId: string, - // thumbSize: number, - // downloadType: number, - // filePath: string - // }) => Promise, - // (fileTransNotifyInfo: OnRichMediaDownloadCompleteParams) => void - // >( - // 'NodeIKernelMsgService/downloadRichMedia', - // 'NodeIKernelMsgListener/onRichMediaDownloadComplete', - // 1, - // timeout, - // (arg: OnRichMediaDownloadCompleteParams) => { - // if (arg.msgId === msgId) { - // return true; - // } - // return false; - // }, - // { - // fileModelId: '0', - // downloadSourceType: 0, - // triggerType: 1, - // msgId: msgId, - // chatType: chatType, - // peerUid: peerUid, - // elementId: elementId, - // thumbSize: 0, - // downloadType: 1, - // filePath: thumbPath - // } - // ); - // let filePath = data[1].filePath; - // if (filePath.startsWith('\\')) { - // // log('filePath start with \\'); - // const downloadPath = sessionConfig.defaultFileDownloadPath; - // //logDebug('downloadPath', downloadPath); - // filePath = path.join(downloadPath, filePath); - // // 下载路径是下载文件夹的相对路径 - // } - // return filePath; - // } - - async getImageSize(filePath: string): Promise { - return new Promise((resolve, reject) => { - imageSize(filePath, (err, dimensions) => { - if (err) { - reject(err); - } else { - resolve(dimensions); - } - }); - }); - } - async addFileCache(peer: Peer, msgId: string, msgSeq: string, senderUid: string, elemId: string, elemType: string, fileSize: string, fileName: string) { - let GroupData; - let BuddyData; - if (peer.chatType === ChatType.group) { - GroupData = - [{ - groupCode: peer.peerUid, - isConf: false, - hasModifyConfGroupFace: true, - hasModifyConfGroupName: true, - groupName: "NapCat.Cached", - remark: "NapCat.Cached" - }]; - } else if (peer.chatType === ChatType.friend) { - BuddyData = [{ - category_name: 'NapCat.Cached', - peerUid: peer.peerUid, - peerUin: peer.peerUid, - remark: 'NapCat.Cached' - }]; - } else { - return undefined; } + // async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) { + // //logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force); + // // 用于下载收到的消息中的图片等 + // if (sourcePath && fs.existsSync(sourcePath)) { + // if (force) { + // try { + // await fsPromises.unlink(sourcePath); + // } catch (e) { + // // + // } + // } else { + // return sourcePath; + // } + // } + // const data = await this.core.eventWrapper.CallNormalEvent< + // ( + // params: { + // fileModelId: string, + // downloadSourceType: number, + // triggerType: number, + // msgId: string, + // chatType: ChatType, + // peerUid: string, + // elementId: string, + // thumbSize: number, + // downloadType: number, + // filePath: string + // }) => Promise, + // (fileTransNotifyInfo: OnRichMediaDownloadCompleteParams) => void + // >( + // 'NodeIKernelMsgService/downloadRichMedia', + // 'NodeIKernelMsgListener/onRichMediaDownloadComplete', + // 1, + // timeout, + // (arg: OnRichMediaDownloadCompleteParams) => { + // if (arg.msgId === msgId) { + // return true; + // } + // return false; + // }, + // { + // fileModelId: '0', + // downloadSourceType: 0, + // triggerType: 1, + // msgId: msgId, + // chatType: chatType, + // peerUid: peerUid, + // elementId: elementId, + // thumbSize: 0, + // downloadType: 1, + // filePath: thumbPath + // } + // ); + // let filePath = data[1].filePath; + // if (filePath.startsWith('\\')) { + // // log('filePath start with \\'); + // const downloadPath = sessionConfig.defaultFileDownloadPath; + // //logDebug('downloadPath', downloadPath); + // filePath = path.join(downloadPath, filePath); + // // 下载路径是下载文件夹的相对路径 + // } + // return filePath; + // } - return this.context.session.getSearchService().addSearchHistory({ - type: 4, - contactList: [], - id: -1, - groupInfos: [], - msgs: [], - fileInfos: [ - { - chatType: peer.chatType, - buddyChatInfo: BuddyData || [], - discussChatInfo: [], - groupChatInfo: GroupData || [], - dataLineChatInfo: [], - tmpChatInfo: [], - msgId: msgId, - msgSeq: msgSeq, - msgTime: Math.floor(Date.now() / 1000).toString(), - senderUid: senderUid, - senderNick: 'NapCat.Cached', - senderRemark: 'NapCat.Cached', - senderCard: 'NapCat.Cached', - elemId: elemId, - elemType: elemType, - fileSize: fileSize, - filePath: '', - fileName: fileName, - hits: [{ - start: 12, - end: 14 - }] + async getImageSize(filePath: string): Promise { + return new Promise((resolve, reject) => { + imageSize(filePath, (err, dimensions) => { + if (err) { + reject(err); + } else { + resolve(dimensions); + } + }); + }); + } + async addFileCache(peer: Peer, msgId: string, msgSeq: string, senderUid: string, elemId: string, elemType: string, fileSize: string, fileName: string) { + let GroupData; + let BuddyData; + if (peer.chatType === ChatType.group) { + GroupData = + [{ + groupCode: peer.peerUid, + isConf: false, + hasModifyConfGroupFace: true, + hasModifyConfGroupName: true, + groupName: "NapCat.Cached", + remark: "NapCat.Cached" + }]; + } else if (peer.chatType === ChatType.friend) { + BuddyData = [{ + category_name: 'NapCat.Cached', + peerUid: peer.peerUid, + peerUin: peer.peerUid, + remark: 'NapCat.Cached' + }]; + } else { + return undefined; } - ] - }); - } - async searchfile(keys: string[]) { + + return this.context.session.getSearchService().addSearchHistory({ + type: 4, + contactList: [], + id: -1, + groupInfos: [], + msgs: [], + fileInfos: [ + { + chatType: peer.chatType, + buddyChatInfo: BuddyData || [], + discussChatInfo: [], + groupChatInfo: GroupData || [], + dataLineChatInfo: [], + tmpChatInfo: [], + msgId: msgId, + msgSeq: msgSeq, + msgTime: Math.floor(Date.now() / 1000).toString(), + senderUid: senderUid, + senderNick: 'NapCat.Cached', + senderRemark: 'NapCat.Cached', + senderCard: 'NapCat.Cached', + elemId: elemId, + elemType: elemType, + fileSize: fileSize, + filePath: '', + fileName: fileName, + hits: [{ + start: 12, + end: 14 + }] + } + ] + }); + } + async searchfile(keys: string[]) { type EventType = NodeIKernelSearchService['searchFileWithKeywords']; interface OnListener { searchId: string, @@ -250,99 +250,100 @@ export class NTQQFileApi { } const Event = this.core.eventWrapper.createEventFunction('NodeIKernelSearchService/searchFileWithKeywords'); let id = ''; - const Listener = this.core.eventWrapper.RegisterListen<(params: OnListener) => void>('NodeIKernelSearchListener/onSearchFileKeywordsResult', 1, 20000, (params) => { - if (id !== '' && params.searchId == id) { - return true; - } - return false; - }); + const Listener = this.core.eventWrapper.RegisterListen<(params: OnListener) => void> + ( + 'NodeIKernelSearchListener/onSearchFileKeywordsResult', + 1, + 20000, + (params) => id !== '' && params.searchId == id + ); id = await Event!(keys, 12); const [ret] = (await Listener); return ret; - } - async getImageUrl(element: PicElement) { - if (!element) { - return ''; } - const url: string = element.originImageUrl!; // 没有域名 - const md5HexStr = element.md5HexStr; - const fileMd5 = element.md5HexStr; - const fileUuid = element.fileUuid; - - if (url) { - const UrlParse = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接 - const imageAppid = UrlParse.searchParams.get('appid'); - const isNewPic = imageAppid && ['1406', '1407'].includes(imageAppid); - if (isNewPic) { - let UrlRkey = UrlParse.searchParams.get('rkey'); - if (UrlRkey) { - return IMAGE_HTTP_HOST_NT + url; + async getImageUrl(element: PicElement) { + if (!element) { + return ''; } - const rkeyData = await this.rkeyManager.getRkey(); - UrlRkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey; - return IMAGE_HTTP_HOST_NT + url + `${UrlRkey}`; - } else { - // 老的图片url,不需要rkey - return IMAGE_HTTP_HOST + url; - } - } else if (fileMd5 || md5HexStr) { - // 没有url,需要自己拼接 - return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${(fileMd5 || md5HexStr)!.toUpperCase()}/0`; + const url: string = element.originImageUrl!; // 没有域名 + const md5HexStr = element.md5HexStr; + const fileMd5 = element.md5HexStr; + const fileUuid = element.fileUuid; + + if (url) { + const UrlParse = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接 + const imageAppid = UrlParse.searchParams.get('appid'); + const isNewPic = imageAppid && ['1406', '1407'].includes(imageAppid); + if (isNewPic) { + let UrlRkey = UrlParse.searchParams.get('rkey'); + if (UrlRkey) { + return IMAGE_HTTP_HOST_NT + url; + } + const rkeyData = await this.rkeyManager.getRkey(); + UrlRkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey; + return IMAGE_HTTP_HOST_NT + url + `${UrlRkey}`; + } else { + // 老的图片url,不需要rkey + return IMAGE_HTTP_HOST + url; + } + } else if (fileMd5 || md5HexStr) { + // 没有url,需要自己拼接 + return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${(fileMd5 || md5HexStr)!.toUpperCase()}/0`; + } + this.context.logger.logDebug('图片url获取失败', element); + return ''; } - this.context.logger.logDebug('图片url获取失败', element); - return ''; - } } export class NTQQFileCacheApi { - context: InstanceContext; - core: NapCatCore; - constructor(context: InstanceContext, core: NapCatCore) { - this.context = context; - this.core = core; - } - async setCacheSilentScan(isSilent: boolean = true) { - return ''; - } + context: InstanceContext; + core: NapCatCore; + constructor(context: InstanceContext, core: NapCatCore) { + this.context = context; + this.core = core; + } + async setCacheSilentScan(isSilent: boolean = true) { + return ''; + } - getCacheSessionPathList() { - return ''; - } + getCacheSessionPathList() { + return ''; + } - clearCache(cacheKeys: Array = ['tmp', 'hotUpdate']) { + clearCache(cacheKeys: Array = ['tmp', 'hotUpdate']) { // 参数未验证 - return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys); - } + return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys); + } - addCacheScannedPaths(pathMap: object = {}) { - return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap); - } + addCacheScannedPaths(pathMap: object = {}) { + return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap); + } - scanCache() { + scanCache() { //return (await this.context.session.getStorageCleanService().scanCache()).size; - } + } - getHotUpdateCachePath() { + getHotUpdateCachePath() { // 未实现 - return ''; - } + return ''; + } - getDesktopTmpPath() { + getDesktopTmpPath() { // 未实现 - return ''; - } + return ''; + } - getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) { - return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex); - } + getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) { + return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex); + } - getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) { - const _lastRecord = lastRecord ? lastRecord : { fileType: fileType }; + getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) { + const _lastRecord = lastRecord ? lastRecord : { fileType: fileType }; //需要五个参数 //return napCatCore.session.getStorageCleanService().getFileCacheInfo(); - } + } - async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) { - return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys); - } + async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) { + return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys); + } } diff --git a/src/core/apis/friend.ts b/src/core/apis/friend.ts index 78ea97ce..22e45f22 100644 --- a/src/core/apis/friend.ts +++ b/src/core/apis/friend.ts @@ -1,26 +1,31 @@ import { FriendV2, User } from '@/core/entities'; import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelProfileService, OnBuddyChangeParams } from '@/core'; import { LimitedHashTable } from '@/common/utils/MessageUnique'; + export class NTQQFriendApi { context: InstanceContext; core: NapCatCore; + constructor(context: InstanceContext, core: NapCatCore) { this.context = context; this.core = core; } + async getBuddyV2(refresh = false): Promise { const uids: string[] = []; const buddyService = this.context.session.getBuddyService(); const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL); uids.push(...buddyListV2.data.flatMap(item => item.buddyUids)); const data = await this.core.eventWrapper.callNoListenerEvent( - 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids + 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids, ); return Array.from(data.values()); } + async getBuddyIdMapCache(refresh = false): Promise> { return await this.getBuddyIdMap(refresh); } + async getBuddyIdMap(refresh = false): Promise> { const uids: string[] = []; const retMap: LimitedHashTable = new LimitedHashTable(5000); @@ -28,7 +33,7 @@ export class NTQQFriendApi { const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL); uids.push(...buddyListV2.data.flatMap(item => item.buddyUids)); const data = await this.core.eventWrapper.callNoListenerEvent( - 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids + 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids, ); data.forEach((value, key) => { retMap.set(value.uin!, value.uid!); @@ -36,6 +41,7 @@ export class NTQQFriendApi { //console.log('getBuddyIdMap', retMap.getValue); return retMap; } + async getBuddyV2ExWithCate(refresh = false) { const uids: string[] = []; const categoryMap: Map = new Map(); @@ -49,32 +55,37 @@ export class NTQQFriendApi { return item.buddyUids; })); const data = await this.core.eventWrapper.callNoListenerEvent( - 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids + 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids, ); return Array.from(data).map(([key, value]) => { const category = categoryMap.get(key); - return category ? { ...value, categoryId: category.categoryId, categroyName: category.categroyName } : value; + return category ? { + ...value, + categoryId: category.categoryId, + categroyName: category.categroyName, + } : value; }); } + async isBuddy(uid: string) { return this.context.session.getBuddyService().isBuddy(uid); } + /** - * @deprecated - * @param forced - * @returns - */ + * @deprecated + * @param forced + * @returns + */ async getFriends(forced = false): Promise { - const [_retData, _BuddyArg] = await this.core.eventWrapper.CallNormalEvent - <(force: boolean) => Promise, (arg: OnBuddyChangeParams) => void> - ( - 'NodeIKernelBuddyService/getBuddyList', - 'NodeIKernelBuddyListener/onBuddyListChange', - 1, - 5000, - () => true, - forced - ); + const [_retData, _BuddyArg] = await this.core.eventWrapper.CallNormalEvent<(force: boolean) => Promise, (arg: OnBuddyChangeParams) => void> + ( + 'NodeIKernelBuddyService/getBuddyList', + 'NodeIKernelBuddyListener/onBuddyListChange', + 1, + 5000, + () => true, + forced, + ); const friends: User[] = []; for (const categoryItem of _BuddyArg) { for (const friend of categoryItem.buddyList) { @@ -94,7 +105,7 @@ export class NTQQFriendApi { this.context.session.getBuddyService()?.approvalFriendRequest({ friendUid: friendUid, reqTime: reqTime, - accept + accept, }); } } diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index d6d6ed33..43046cf3 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -1,325 +1,367 @@ -import { GroupMember, GroupRequestOperateTypes, GroupMemberRole, GroupNotify, Group, MemberExtSourceType, GroupNotifyTypes, ChatType, Peer, GroupListUpdateType } from '../entities'; +import { + ChatType, + GroupMember, + GroupMemberRole, + GroupNotify, + GroupRequestOperateTypes, + MemberExtSourceType, +} from '../entities'; import { GeneralCallResult, InstanceContext, NapCatCore, NodeIKernelGroupService } from '@/core'; import { runAllWithTimeout } from '@/common/utils/helper'; import { NodeIKernelGroupListener } from '../listeners'; + export class NTQQGroupApi { - context: InstanceContext; - core: NapCatCore; - constructor(context: InstanceContext, core: NapCatCore) { - this.context = context; - this.core = core; - } - async setGroupAvatar(gc: string, filePath: string) { - return this.context.session.getGroupService().setHeader(gc, filePath); - } - async getGroups(forced = false) { - type ListenerType = NodeIKernelGroupListener['onGroupListUpdate']; - const [_retData, _updateType, groupList] = await this.core.eventWrapper.CallNormalEvent - <(force: boolean) => Promise, ListenerType> - ( - 'NodeIKernelGroupService/getGroupList', - 'NodeIKernelGroupListener/onGroupListUpdate', - 1, - 5000, - (updateType) => true, - forced - ); - return groupList; - } - async getGroupMemberLatestSendTimeCache(GroupCode: string, uids: string[]) { - return this.getGroupMemberLatestSendTime(GroupCode, uids); - } - /** - * 通过QQ自带数据库获取群成员最后发言时间(仅返回有效数据 且消耗延迟大 需要进行缓存) - * @param GroupCode 群号 - * @returns Map key: uin value: sendTime - * @example - * let ret = await NTQQGroupApi.getGroupMemberLastestSendTime('123456'); - * for (let [uin, sendTime] of ret) { - * console.log(uin, sendTime); - * } -*/ - async getGroupMemberLatestSendTime(GroupCode: string, uids: string[]) { - const getdata = async (uid: string) => { - const NTRet = await this.getLatestMsgByUids(GroupCode, [uid]); - if (NTRet.result != 0 && NTRet.msgList.length < 1) { - return undefined; - } - return { sendUin: NTRet.msgList[0].senderUin, sendTime: NTRet.msgList[0].msgTime }; - }; - const PromiseData: Promise<({ - sendUin: string; - sendTime: string; - } | undefined)>[] = []; - const ret: Map = new Map(); - for (const uid of uids) { - PromiseData.push(getdata(uid).catch(() => undefined)); - } - const allRet = await runAllWithTimeout(PromiseData, 2500); - for (const PromiseDo of allRet) { - if (PromiseDo) { - ret.set(PromiseDo.sendUin, PromiseDo.sendTime); - } - } - return ret; - } - async getLatestMsgByUids(GroupCode: string, uids: string[]) { - const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { - chatInfo: { - peerUid: GroupCode, - chatType: ChatType.group, - }, - filterMsgType: [], - filterSendersUid: uids, - filterMsgToTime: '0', - filterMsgFromTime: '0', - isReverseOrder: false, - isIncludeCurrent: true, - pageLimit: 1, - }); - return ret; - } - async getGroupMemberAll(GroupCode: string, forced = false) { - return this.context.session.getGroupService().getAllMemberList(GroupCode, forced); - } - async getLatestMsg(GroupCode: string, uins: string[]) { - const uids: Array = []; - for (const uin of uins) { - const uid = await this.core.getApiContext().UserApi.getUidByUin(uin); - if (uid) { - uids.push(uid); - } - } - const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { - chatInfo: { - peerUid: GroupCode, - chatType: ChatType.group, - }, - filterMsgType: [], - filterSendersUid: uids, - filterMsgToTime: '0', - filterMsgFromTime: '0', - isReverseOrder: false, - isIncludeCurrent: true, - pageLimit: 1, - }); - return ret; - } - async getGroupRecommendContactArkJson(GroupCode: string) { - return this.context.session.getGroupService().getGroupRecommendContactArkJson(GroupCode); - } - async CreatGroupFileFolder(groupCode: string, folderName: string) { - return this.context.session.getRichMediaService().createGroupFolder(groupCode, folderName); - } - async DelGroupFile(groupCode: string, files: string[]) { - return this.context.session.getRichMediaService().deleteGroupFile(groupCode, [102], files); - } - async DelGroupFileFolder(groupCode: string, folderId: string) { - return this.context.session.getRichMediaService().deleteGroupFolder(groupCode, folderId); - } - async addGroupEssence(GroupCode: string, msgId: string) { - // 代码没测过 - // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom - const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false); - const param = { - groupCode: GroupCode, - msgRandom: parseInt(MsgData.msgList[0].msgRandom), - msgSeq: parseInt(MsgData.msgList[0].msgSeq) - }; - // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数 - return this.context.session.getGroupService().addGroupEssence(param); - } - async removeGroupEssence(GroupCode: string, msgId: string) { - // 代码没测过 - // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom - const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false); - const param = { - groupCode: GroupCode, - msgRandom: parseInt(MsgData.msgList[0].msgRandom), - msgSeq: parseInt(MsgData.msgList[0].msgSeq) - }; - // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数 - return this.context.session.getGroupService().removeGroupEssence(param); - } - async getSingleScreenNotifies(num: number) { - const [_retData, _doubt, _seq, notifies] = await this.core.eventWrapper.CallNormalEvent - <(arg1: boolean, arg2: string, arg3: number) => Promise, (doubt: boolean, seq: string, notifies: GroupNotify[]) => void> - ( - 'NodeIKernelGroupService/getSingleScreenNotifies', - 'NodeIKernelGroupListener/onGroupSingleScreenNotifies', - 1, - 5000, - () => true, - false, - '', - num - ); - return notifies; - } - async getGroupMemberV2(GroupCode: string, uid: string, forced = false) { - type ListenerType = NodeIKernelGroupListener['onMemberInfoChange']; - type EventType = NodeIKernelGroupService['getMemberInfo']; - // NTEventDispatch.CreatListenerFunction('NodeIKernelGroupListener/onGroupMemberInfoUpdate', - //return napCatCore.session.getGroupService().getMemberInfo(GroupCode, [uid], forced); - const [ret, _groupCode, _changeType, _members] = await this.core.eventWrapper.CallNormalEvent - - ( - 'NodeIKernelGroupService/getMemberInfo', - 'NodeIKernelGroupListener/onMemberInfoChange', - 1, - 5000, - (groupCode: string, changeType: number, members: Map) => { - return groupCode == GroupCode && members.has(uid); - }, - GroupCode, [uid], forced - ); - return _members.get(uid); - } - async getGroupMembers(groupQQ: string, num = 3000): Promise> { - const groupService = this.context.session.getGroupService(); - const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow'); - const result = await groupService.getNextMemberList(sceneId!, undefined, num); - if (result.errCode !== 0) { - throw ('获取群成员列表出错,' + result.errMsg); + context: InstanceContext; + core: NapCatCore; + + constructor(context: InstanceContext, core: NapCatCore) { + this.context = context; + this.core = core; } - //logDebug(`获取群(${groupQQ})成员列表结果:`, `finish: ${result.result.finish}`); //, Array.from(result.result.infos.values())); - return result.result.infos; - /* - console.log(sceneId); - const result = await napCatCore.getGroupService().getNextMemberList(sceneId, num); - console.log(result); + async setGroupAvatar(gc: string, filePath: string) { + return this.context.session.getGroupService().setHeader(gc, filePath); + } - return result; - */ - } + async getGroups(forced = false) { + type ListenerType = NodeIKernelGroupListener['onGroupListUpdate']; + const [_retData, _updateType, groupList] = await this.core.eventWrapper.CallNormalEvent <(force: boolean) => Promise, ListenerType> + ( + 'NodeIKernelGroupService/getGroupList', + 'NodeIKernelGroupListener/onGroupListUpdate', + 1, + 5000, + (updateType) => true, + forced, + ); + return groupList; + } - async getGroupNotifies() { - // 获取管理员变更 - // 加群通知,退出通知,需要管理员权限 + async getGroupMemberLatestSendTimeCache(GroupCode: string, uids: string[]) { + return this.getGroupMemberLatestSendTime(GroupCode, uids); + } - } - async GetGroupFileCount(Gids: Array) { - return this.context.session.getRichMediaService().batchGetGroupFileCount(Gids); - } - async getGroupIgnoreNotifies() { - } - async getArkJsonGroupShare(GroupCode: string) { - const ret = await this.core.eventWrapper.callNoListenerEvent - <(GroupId: string) => Promise>( - 'NodeIKernelGroupService/getGroupRecommendContactArkJson', - 5000, - GroupCode - ); - return ret.arkJson; - } - //需要异常处理 - async uploadGroupBulletinPic(GroupCode: string, imageurl: string) { - const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!; - return this.context.session.getGroupService().uploadGroupBulletinPic(GroupCode, _Pskey, imageurl); - } - async handleGroupRequest(flag: string, operateType: GroupRequestOperateTypes, reason?: string) { - const flagitem = flag.split('|'); - const groupCode = flagitem[0]; - const seq = flagitem[1]; - const type = parseInt(flagitem[2]); - - return this.context.session.getGroupService().operateSysNotify( - false, - { - 'operateType': operateType, // 2 拒绝 - 'targetMsg': { - 'seq': seq, // 通知序列号 - 'type': type, - 'groupCode': groupCode, - 'postscript': reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格 + /** + * 通过QQ自带数据库获取群成员最后发言时间(仅返回有效数据 且消耗延迟大 需要进行缓存) + * @param GroupCode 群号 + * @returns Map key: uin value: sendTime + * @example + * let ret = await NTQQGroupApi.getGroupMemberLastestSendTime('123456'); + * for (let [uin, sendTime] of ret) { + * console.log(uin, sendTime); + * } + */ + async getGroupMemberLatestSendTime(GroupCode: string, uids: string[]) { + const getdata = async (uid: string) => { + const NTRet = await this.getLatestMsgByUids(GroupCode, [uid]); + if (NTRet.result != 0 && NTRet.msgList.length < 1) { + return undefined; + } + return { sendUin: NTRet.msgList[0].senderUin, sendTime: NTRet.msgList[0].msgTime }; + }; + const PromiseData: Promise<({ + sendUin: string; + sendTime: string; + } | undefined)>[] = []; + const ret: Map = new Map(); + for (const uid of uids) { + PromiseData.push(getdata(uid).catch(() => undefined)); } - }); - } - - async quitGroup(groupQQ: string) { - return this.context.session.getGroupService().quitGroup(groupQQ); - } - - async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') { - return this.context.session.getGroupService().kickMember(groupQQ, kickUids, refuseForever, kickReason); - } - - async banMember(groupQQ: string, memList: Array<{ uid: string, timeStamp: number }>) { - // timeStamp为秒数, 0为解除禁言 - return this.context.session.getGroupService().setMemberShutUp(groupQQ, memList); - } - - async banGroup(groupQQ: string, shutUp: boolean) { - return this.context.session.getGroupService().setGroupShutUp(groupQQ, shutUp); - } - - async setMemberCard(groupQQ: string, memberUid: string, cardName: string) { - return this.context.session.getGroupService().modifyMemberCardName(groupQQ, memberUid, cardName); - } - - async setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole) { - return this.context.session.getGroupService().modifyMemberRole(groupQQ, memberUid, role); - } - - async setGroupName(groupQQ: string, groupName: string) { - return this.context.session.getGroupService().modifyGroupName(groupQQ, groupName, false); - } - - // 头衔不可用 - async setGroupTitle(groupQQ: string, uid: string, title: string) { - - } - - async publishGroupBulletin(groupQQ: string, content: string, picInfo: { id: string, width: number, height: number } | undefined = undefined, pinned: number = 0, confirmRequired: number = 0,) { - const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com'); - //text是content内容url编码 - const data = { - text: encodeURI(content), - picInfo: picInfo, - oldFeedsId: '', - pinned: pinned, - confirmRequired: confirmRequired - }; - return this.context.session.getGroupService().publishGroupBulletin(groupQQ, _Pskey!, data); - } - async getGroupRemainAtTimes(GroupCode: string) { - this.context.session.getGroupService().getGroupRemainAtTimes(GroupCode); - } - async getMemberExtInfo(groupCode: string, uin: string) { - // 仅NTQQ 9.9.11 24568测试 容易炸开谨慎使用 - return this.context.session.getGroupService().getMemberExtInfo( - { - groupCode: groupCode, - sourceType: MemberExtSourceType.TITLETYPE, - beginUin: '0', - dataTime: '0', - uinList: [uin], - uinNum: '', - seq: '', - groupType: '', - richCardNameVer: '', - memberExtFilter: { - memberLevelInfoUin: 1, - memberLevelInfoPoint: 1, - memberLevelInfoActiveDay: 1, - memberLevelInfoLevel: 1, - memberLevelInfoName: 1, - levelName: 1, - dataTime: 1, - userShowFlag: 1, - sysShowFlag: 1, - timeToUpdate: 1, - nickName: 1, - specialTitle: 1, - levelNameNew: 1, - userShowFlagNew: 1, - msgNeedField: 1, - cmdUinFlagExt3Grocery: 1, - memberIcon: 1, - memberInfoSeq: 1 + const allRet = await runAllWithTimeout(PromiseData, 2500); + for (const PromiseDo of allRet) { + if (PromiseDo) { + ret.set(PromiseDo.sendUin, PromiseDo.sendTime); + } } - } - ); - } + return ret; + } + + async getLatestMsgByUids(GroupCode: string, uids: string[]) { + const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { + chatInfo: { + peerUid: GroupCode, + chatType: ChatType.group, + }, + filterMsgType: [], + filterSendersUid: uids, + filterMsgToTime: '0', + filterMsgFromTime: '0', + isReverseOrder: false, + isIncludeCurrent: true, + pageLimit: 1, + }); + return ret; + } + + async getGroupMemberAll(GroupCode: string, forced = false) { + return this.context.session.getGroupService().getAllMemberList(GroupCode, forced); + } + + async getLatestMsg(GroupCode: string, uins: string[]) { + const uids: Array = []; + for (const uin of uins) { + const uid = await this.core.getApiContext().UserApi.getUidByUin(uin); + if (uid) { + uids.push(uid); + } + } + const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { + chatInfo: { + peerUid: GroupCode, + chatType: ChatType.group, + }, + filterMsgType: [], + filterSendersUid: uids, + filterMsgToTime: '0', + filterMsgFromTime: '0', + isReverseOrder: false, + isIncludeCurrent: true, + pageLimit: 1, + }); + return ret; + } + + async getGroupRecommendContactArkJson(GroupCode: string) { + return this.context.session.getGroupService().getGroupRecommendContactArkJson(GroupCode); + } + + async CreatGroupFileFolder(groupCode: string, folderName: string) { + return this.context.session.getRichMediaService().createGroupFolder(groupCode, folderName); + } + + async DelGroupFile(groupCode: string, files: string[]) { + return this.context.session.getRichMediaService().deleteGroupFile(groupCode, [102], files); + } + + async DelGroupFileFolder(groupCode: string, folderId: string) { + return this.context.session.getRichMediaService().deleteGroupFolder(groupCode, folderId); + } + + async addGroupEssence(GroupCode: string, msgId: string) { + // 代码没测过 + // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom + const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ + chatType: 2, + guildId: '', + peerUid: GroupCode, + }, msgId, 1, false); + const param = { + groupCode: GroupCode, + msgRandom: parseInt(MsgData.msgList[0].msgRandom), + msgSeq: parseInt(MsgData.msgList[0].msgSeq), + }; + // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数 + return this.context.session.getGroupService().addGroupEssence(param); + } + + async removeGroupEssence(GroupCode: string, msgId: string) { + // 代码没测过 + // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom + const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ + chatType: 2, + guildId: '', + peerUid: GroupCode, + }, msgId, 1, false); + const param = { + groupCode: GroupCode, + msgRandom: parseInt(MsgData.msgList[0].msgRandom), + msgSeq: parseInt(MsgData.msgList[0].msgSeq), + }; + // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数 + return this.context.session.getGroupService().removeGroupEssence(param); + } + + async getSingleScreenNotifies(num: number) { + const [_retData, _doubt, _seq, notifies] = await this.core.eventWrapper.CallNormalEvent <(arg1: boolean, arg2: string, arg3: number) => Promise, (doubt: boolean, seq: string, notifies: GroupNotify[]) => void> + ( + 'NodeIKernelGroupService/getSingleScreenNotifies', + 'NodeIKernelGroupListener/onGroupSingleScreenNotifies', + 1, + 5000, + () => true, + false, + '', + num, + ); + return notifies; + } + + async getGroupMemberV2(GroupCode: string, uid: string, forced = false) { + type ListenerType = NodeIKernelGroupListener['onMemberInfoChange']; + type EventType = NodeIKernelGroupService['getMemberInfo']; + // NTEventDispatch.CreatListenerFunction('NodeIKernelGroupListener/onGroupMemberInfoUpdate', + //return napCatCore.session.getGroupService().getMemberInfo(GroupCode, [uid], forced); + const [ret, _groupCode, _changeType, _members] = await this.core.eventWrapper.CallNormalEvent + ( + 'NodeIKernelGroupService/getMemberInfo', + 'NodeIKernelGroupListener/onMemberInfoChange', + 1, + 5000, + (groupCode: string, changeType: number, members: Map) => { + return groupCode == GroupCode && members.has(uid); + }, + GroupCode, [uid], forced, + ); + return _members.get(uid); + } + + async getGroupMembers(groupQQ: string, num = 3000): Promise> { + const groupService = this.context.session.getGroupService(); + const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow'); + const result = await groupService.getNextMemberList(sceneId!, undefined, num); + if (result.errCode !== 0) { + throw ('获取群成员列表出错,' + result.errMsg); + } + + //logDebug(`获取群(${groupQQ})成员列表结果:`, `finish: ${result.result.finish}`); //, Array.from(result.result.infos.values())); + return result.result.infos; + /* + console.log(sceneId); + const result = await napCatCore.getGroupService().getNextMemberList(sceneId, num); + console.log(result); + + return result; + */ + } + + async getGroupNotifies() { + // 获取管理员变更 + // 加群通知,退出通知,需要管理员权限 + + } + + async GetGroupFileCount(Gids: Array) { + return this.context.session.getRichMediaService().batchGetGroupFileCount(Gids); + } + + async getGroupIgnoreNotifies() { + } + + async getArkJsonGroupShare(GroupCode: string) { + const ret = await this.core.eventWrapper.callNoListenerEvent<(GroupId: string) => Promise>( + 'NodeIKernelGroupService/getGroupRecommendContactArkJson', + 5000, + GroupCode, + ); + return ret.arkJson; + } + + //需要异常处理 + async uploadGroupBulletinPic(GroupCode: string, imageurl: string) { + const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!; + return this.context.session.getGroupService().uploadGroupBulletinPic(GroupCode, _Pskey, imageurl); + } + + async handleGroupRequest(flag: string, operateType: GroupRequestOperateTypes, reason?: string) { + const flagitem = flag.split('|'); + const groupCode = flagitem[0]; + const seq = flagitem[1]; + const type = parseInt(flagitem[2]); + + return this.context.session.getGroupService().operateSysNotify( + false, + { + 'operateType': operateType, // 2 拒绝 + 'targetMsg': { + 'seq': seq, // 通知序列号 + 'type': type, + 'groupCode': groupCode, + 'postscript': reason || ' ', // 仅传空值可能导致处理失败,故默认给个空格 + }, + }); + } + + async quitGroup(groupQQ: string) { + return this.context.session.getGroupService().quitGroup(groupQQ); + } + + async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') { + return this.context.session.getGroupService().kickMember(groupQQ, kickUids, refuseForever, kickReason); + } + + async banMember(groupQQ: string, memList: Array<{ uid: string, timeStamp: number }>) { + // timeStamp为秒数, 0为解除禁言 + return this.context.session.getGroupService().setMemberShutUp(groupQQ, memList); + } + + async banGroup(groupQQ: string, shutUp: boolean) { + return this.context.session.getGroupService().setGroupShutUp(groupQQ, shutUp); + } + + async setMemberCard(groupQQ: string, memberUid: string, cardName: string) { + return this.context.session.getGroupService().modifyMemberCardName(groupQQ, memberUid, cardName); + } + + async setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole) { + return this.context.session.getGroupService().modifyMemberRole(groupQQ, memberUid, role); + } + + async setGroupName(groupQQ: string, groupName: string) { + return this.context.session.getGroupService().modifyGroupName(groupQQ, groupName, false); + } + + // 头衔不可用 + async setGroupTitle(groupQQ: string, uid: string, title: string) { + + } + + async publishGroupBulletin(groupQQ: string, content: string, picInfo: { + id: string, + width: number, + height: number + } | undefined = undefined, pinned: number = 0, confirmRequired: number = 0) { + const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com'); + //text是content内容url编码 + const data = { + text: encodeURI(content), + picInfo: picInfo, + oldFeedsId: '', + pinned: pinned, + confirmRequired: confirmRequired, + }; + return this.context.session.getGroupService().publishGroupBulletin(groupQQ, _Pskey!, data); + } + + async getGroupRemainAtTimes(GroupCode: string) { + this.context.session.getGroupService().getGroupRemainAtTimes(GroupCode); + } + + async getMemberExtInfo(groupCode: string, uin: string) { + // 仅NTQQ 9.9.11 24568测试 容易炸开谨慎使用 + return this.context.session.getGroupService().getMemberExtInfo( + { + groupCode: groupCode, + sourceType: MemberExtSourceType.TITLETYPE, + beginUin: '0', + dataTime: '0', + uinList: [uin], + uinNum: '', + seq: '', + groupType: '', + richCardNameVer: '', + memberExtFilter: { + memberLevelInfoUin: 1, + memberLevelInfoPoint: 1, + memberLevelInfoActiveDay: 1, + memberLevelInfoLevel: 1, + memberLevelInfoName: 1, + levelName: 1, + dataTime: 1, + userShowFlag: 1, + sysShowFlag: 1, + timeToUpdate: 1, + nickName: 1, + specialTitle: 1, + levelNameNew: 1, + userShowFlagNew: 1, + msgNeedField: 1, + cmdUinFlagExt3Grocery: 1, + memberIcon: 1, + memberInfoSeq: 1, + }, + }, + ); + } } diff --git a/src/core/apis/sign.ts b/src/core/apis/sign.ts index a0054961..f3fbbcd3 100644 --- a/src/core/apis/sign.ts +++ b/src/core/apis/sign.ts @@ -1,6 +1,5 @@ - import { RequestUtil } from '@/common/utils/request'; -import { MiniAppLuaJsonType } from '../entities/sign'; +import { MiniAppLuaJsonType } from '@/core'; import { InstanceContext, NapCatCore } from '..'; // let t = await napCatCore.session.getGroupService().shareDigest({ @@ -73,14 +72,17 @@ import { InstanceContext, NapCatCore } from '..'; // }); // } // } + export class NTQQMusicSignApi { context: InstanceContext; core: NapCatCore; + constructor(context: InstanceContext, core: NapCatCore) { this.context = context; this.core = core; } - async SignMiniApp(CardData: MiniAppLuaJsonType) { + + async signMiniApp(CardData: MiniAppLuaJsonType) { // { // "app": "com.tencent.miniapp.lua", // "bizsrc": "tianxuan.imgJumpArk", @@ -128,26 +130,26 @@ export class NTQQMusicSignApi { // return hash & 0x7fffffff; // } const signCard = { - "app": "com.tencent.miniapp.lua", - "bizsrc": "tianxuan.imgJumpArk", - "view": "miniapp", - "prompt": CardData.prompt, - "config": { - "type": "normal", - "forward": 1, - "autosize": 0 + 'app': 'com.tencent.miniapp.lua', + 'bizsrc': 'tianxuan.imgJumpArk', + 'view': 'miniapp', + 'prompt': CardData.prompt, + 'config': { + 'type': 'normal', + 'forward': 1, + 'autosize': 0, + }, + 'meta': { + 'miniapp': { + 'title': CardData.title, + 'preview': (CardData.preview as string).replace(/\\/g, '\\/\\/'), + 'jumpUrl': (CardData.jumpUrl as string).replace(/\\/g, '\\/\\/'), + 'tag': CardData.tag, + 'tagIcon': (CardData.tagIcon as string).replace(/\\/g, '\\/\\/'), + 'source': CardData.source, + 'sourcelogo': (CardData.sourcelogo as string).replace(/\\/g, '\\/\\/'), + }, }, - "meta": { - "miniapp": { - "title": CardData.title, - "preview": (CardData.preview as string).replace(/\\/g, "\\/\\/"), - "jumpUrl": (CardData.jumpUrl as string).replace(/\\/g, "\\/\\/"), - "tag": CardData.tag, - "tagIcon": (CardData.tagIcon as string).replace(/\\/g, "\\/\\/"), - "source": CardData.source, - "sourcelogo": (CardData.sourcelogo as string).replace(/\\/g, "\\/\\/") - } - } }; // let signCard = { // "app": "com.tencent.eventshare.lua", @@ -188,10 +190,13 @@ export class NTQQMusicSignApi { const CookieValue = 'p_skey=' + data.p_skey + '; skey=' + data.skey + '; p_uin=o' + this.core.selfInfo.uin + '; uin=o' + this.core.selfInfo.uin; - const signurl = "https://h5.qzone.qq.com/v2/vip/tx/trpc/ark-share/GenNewSignedArk?g_tk=" + Bkn + "&ark=" + encodeURIComponent(JSON.stringify(signCard)); - let signed_ark = ""; + const signurl = 'https://h5.qzone.qq.com/v2/vip/tx/trpc/ark-share/GenNewSignedArk?g_tk=' + Bkn + '&ark=' + encodeURIComponent(JSON.stringify(signCard)); + let signed_ark = ''; try { - const retData = await RequestUtil.HttpGetJson<{ code: number, data: { signed_ark: string } }>(signurl, 'GET', undefined, { Cookie: CookieValue }); + const retData = await RequestUtil.HttpGetJson<{ + code: number, + data: { signed_ark: string } + }>(signurl, 'GET', undefined, { Cookie: CookieValue }); //logDebug('MiniApp JSON 消息生成成功', retData); signed_ark = retData.data.signed_ark; } catch (error) { @@ -199,76 +204,92 @@ export class NTQQMusicSignApi { } return signed_ark; } - async SignMusicInternal(songname: string, singer: string, cover: string, songmid: string, songmusic: string) { + + async signInternal(songname: string, singer: string, cover: string, songmid: string, songmusic: string) { //curl -X POST 'https://mqq.reader.qq.com/api/mqq/share/card?accessToken&_csrfToken&source=c0003' -H 'Content-Type: application/json' -H 'Cookie: uin=o10086' -d '{"app":"com.tencent.qqreader.share","config":{"ctime":1718634110,"forward":1,"token":"9a63343c32d5a16bcde653eb97faa25d","type":"normal"},"extra":{"app_type":1,"appid":100497308,"msg_seq":14386738075403815000.0,"uin":1733139081},"meta":{"music":{"action":"","android_pkg_name":"","app_type":1,"appid":100497308,"ctime":1718634110,"desc":"周杰伦","jumpUrl":"https://i.y.qq.com/v8/playsong.html?songmid=0039MnYb0qxYhV&type=0","musicUrl":"http://ws.stream.qqmusic.qq.com/http://isure6.stream.qqmusic.qq.com/M800002202B43Cq4V4.mp3?fromtag=810033622&guid=br_xzg&trace=23fe7bcbe2336bbf&uin=553&vkey=CF0F5CE8B0FA16F3001F8A88D877A217EB5E4F00BDCEF1021EB6C48969CA33C6303987AEECE9CC840122DD2F917A59D6130D8A8CA4577C87","preview":"https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg","cover":"https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg","sourceMsgId":"0","source_icon":"https://p.qpic.cn/qqconnect/0/app_100497308_1626060999/100?max-age=2592000&t=0","source_url":"","tag":"QQ音乐","title":"晴天","uin":10086}},"prompt":"[分享]晴天","ver":"0.0.0.1","view":"music"}' const signurl = 'https://mqq.reader.qq.com/api/mqq/share/card?accessToken&_csrfToken&source=c0003'; //let = "https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg"; const signCard = { - app: "com.tencent.qqreader.share", + app: 'com.tencent.qqreader.share', config: { ctime: 1718634110, forward: 1, - token: "9a63343c32d5a16bcde653eb97faa25d", - type: "normal" + token: '9a63343c32d5a16bcde653eb97faa25d', + type: 'normal', }, extra: { app_type: 1, appid: 100497308, - msg_seq: 14386738075403815000.0, - uin: 1733139081 + msg_seq: 14386738075403815000, + uin: 1733139081, }, meta: { - music: - { - action: "", - android_pkg_name: "", + music: { + action: '', + android_pkg_name: '', app_type: 1, appid: 100497308, ctime: 1718634110, desc: singer, - jumpUrl: "https://i.y.qq.com/v8/playsong.html?songmid=" + songmid + "&type=0", + jumpUrl: 'https://i.y.qq.com/v8/playsong.html?songmid=' + songmid + '&type=0', musicUrl: songmusic, preview: cover, cover: cover, - sourceMsgId: "0", - source_icon: "https://p.qpic.cn/qqconnect/0/app_100497308_1626060999/100?max-age=2592000&t=0", - source_url: "", - tag: "QQ音乐", + sourceMsgId: '0', + source_icon: 'https://p.qpic.cn/qqconnect/0/app_100497308_1626060999/100?max-age=2592000&t=0', + source_url: '', + tag: 'QQ音乐', title: songname, - uin: 10086 - } + uin: 10086, + }, }, - prompt: "[分享]" + songname, - ver: "0.0.0.1", - view: "music" + prompt: '[分享]' + songname, + ver: '0.0.0.1', + view: 'music', }; //console.log(JSON.stringify(signCard, null, 2)); const data = await RequestUtil.HttpGetJson<{ code: number, data: { arkResult: string } }> - (signurl, 'POST', signCard, { 'Cookie': 'uin=o10086', 'Content-Type': 'application/json' }); + (signurl, 'POST', signCard, { 'Cookie': 'uin=o10086', 'Content-Type': 'application/json' }); return data; } + //注意处理错误 - async CreateMusicThridWay0(id: string = '', mid: string = '') { + async signWay03(id: string = '', mid: string = '') { + let signedMid; if (mid == '') { - const MusicInfo = await RequestUtil.HttpGetJson - <{ songinfo?: { data?: { track_info: { mid: string } } } }> - ( - 'https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data={"comm":{"ct":24,"cv":0},"songinfo":{"method":"get_song_detail_yqq","param":{"song_type":0,"song_mid":"","song_id":' + id + '},"module":"music.pf_song_detail_svr"}}', - 'GET', - undefined - ); - mid = MusicInfo.songinfo?.data?.track_info.mid!; + const MusicInfo = await RequestUtil.HttpGetJson<{ + songinfo?: { + data?: { + track_info: { + mid: string + } + } + } + }>( + 'https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data={"comm":{"ct":24,"cv":0},"songinfo":{"method":"get_song_detail_yqq","param":{"song_type":0,"song_mid":"","song_id":' + id + '},"module":"music.pf_song_detail_svr"}}', + 'GET', + undefined, + ); + signedMid = MusicInfo.songinfo?.data?.track_info.mid; } //第三方接口 存在速率限制 现在勉强用 - const MusicReal = await RequestUtil.HttpGetJson - <{ code: number, data?: { name: string, singer: string, url: string, cover: string } }> - ('https://api.leafone.cn/api/qqmusic?id=' + mid + '&type=8', 'GET', undefined); + const MusicReal = await RequestUtil.HttpGetJson<{ + code: number, + data?: { + name: string, + singer: string, + url: string, + cover: string + } + }>('https://api.leafone.cn/api/qqmusic?id=' + signedMid + '&type=8', 'GET'); //console.log(MusicReal); - return { ...MusicReal.data, mid: mid }; + return { ...MusicReal.data, mid: signedMid }; } - async CreateMusicThridWay1(id: string = '', mid: string = '') { + + async CreateMusicThirdWay1(id: string = '', mid: string = '') { } + //转换外域名为 https://qq.ugcimg.cn/v1/cpqcbu4b8870i61bde6k7cbmjgejq8mr3in82qir4qi7ielffv5slv8ck8g42novtmev26i233ujtuab6tvu2l2sjgtupfr389191v00s1j5oh5325j5eqi40774jv1i/khovifoh7jrqd6eahoiv7koh8o //https://cgi.connect.qq.com/qqconnectopen/openapi/change_image_url?url=https://th.bing.com/th?id=OSK.b8ed36f1fb1889de6dc84fd81c187773&w=46&h=46&c=11&rs=1&qlt=80&o=6&dpr=2&pid=SANGAM @@ -283,9 +304,8 @@ export class NTQQMusicSignApi { //还有一处公告上传可以上传高质量图片 持久为qq域名 async SignMusicWrapper(id: string = '') { - const MusicInfo = await this.CreateMusicThridWay0(id)!; - const MusicCard = await this.SignMusicInternal(MusicInfo.name!, MusicInfo.singer!, MusicInfo.cover!, MusicInfo.mid!, "https://ws.stream.qqmusic.qq.com/" + MusicInfo.url!); - return MusicCard; + const MusicInfo = await this.signWay03(id)!; + return await this.signInternal(MusicInfo.name!, MusicInfo.singer!, MusicInfo.cover!, MusicInfo.mid!, 'https://ws.stream.qqmusic.qq.com/' + MusicInfo.url!); } } diff --git a/src/core/apis/system.ts b/src/core/apis/system.ts index 466cc431..5bf3123e 100644 --- a/src/core/apis/system.ts +++ b/src/core/apis/system.ts @@ -1,36 +1,43 @@ - - import { GeneralCallResult, InstanceContext, NapCatCore } from '@/core'; + export class NTQQSystemApi { context: InstanceContext; core: NapCatCore; + constructor(context: InstanceContext, core: NapCatCore) { this.context = context; this.core = core; } + async hasOtherRunningQQProcess() { return this.context.wrapper.util.hasOtherRunningQQProcess(); } + async ORCImage(filePath: string) { return this.context.session.getNodeMiscService().wantWinScreenOCR(filePath); } + async translateEnWordToZn(words: string[]) { return this.context.session.getRichMediaService().translateEnWordToZn(words); } + //调用会超时 没灯用 (好像是通知listener的) onLineDev async getOnlineDev() { return this.context.session.getMsgService().getOnLineDev(); } + //1-2-162b9b42-65b9-4405-a8ed-2e256ec8aa50 async getArkJsonCollection(cid: string) { - const ret = await this.core.eventWrapper.callNoListenerEvent - <(cid: string) => Promise>( - 'NodeIKernelCollectionService/collectionArkShare', + const ret = await this.core.eventWrapper.callNoListenerEvent<(cid: string) => Promise>( + 'NodeIKernelCollectionService/collectionArkShare', 5000, - '1717662698058' + '1717662698058', ); return ret; } + async BootMiniApp(appfile: string, params: string) { await this.context.session.getNodeMiscService().setMiniAppVersion('2.16.4'); const c = await this.context.session.getNodeMiscService().getMiniAppPath(); diff --git a/src/core/apis/user.ts b/src/core/apis/user.ts index 7cc13a54..0a54cf05 100644 --- a/src/core/apis/user.ts +++ b/src/core/apis/user.ts @@ -5,310 +5,319 @@ import { NodeIKernelProfileService, ProfileBizType, UserDetailSource } from '@/c import { InstanceContext, NapCatCore } from '..'; export class NTQQUserApi { - context: InstanceContext; - core: NapCatCore; - constructor(context: InstanceContext, core: NapCatCore) { - this.context = context; - this.core = core; - } - async getProfileLike(uid: string) { - return this.context.session.getProfileLikeService().getBuddyProfileLike({ - friendUids: [ - uid - ], - basic: 1, - vote: 1, - favorite: 0, - userProfile: 1, - type: 2, - start: 0, - limit: 20 - }); - } - async setLongNick(longNick: string) { - return this.context.session.getProfileService().setLongNick(longNick); - } - async setSelfOnlineStatus(status: number, extStatus: number, batteryStatus: number) { - return this.context.session.getMsgService().setStatus({ status: status, extStatus: extStatus, batteryStatus: batteryStatus }); - } - async getBuddyRecommendContactArkJson(uin: string, sencenID = '') { - return this.context.session.getBuddyService().getBuddyRecommendContactArkJson(uin, sencenID); - } - async like(uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number }> { - return this.context.session.getProfileLikeService().setBuddyProfileLike({ - friendUid: uid, - sourceId: 71, - doLikeCount: count, - doLikeTollCount: 0 - }); - } + context: InstanceContext; + core: NapCatCore; - async setQQAvatar(filePath: string) { - type setQQAvatarRet = { result: number, errMsg: string }; - const ret = await this.context.session.getProfileService().setHeader(filePath) as setQQAvatarRet; - return { result: ret?.result, errMsg: ret?.errMsg }; - } - async setGroupAvatar(gc: string, filePath: string) { - return this.context.session.getGroupService().setHeader(gc, filePath); - } + constructor(context: InstanceContext, core: NapCatCore) { + this.context = context; + this.core = core; + } - async fetchUserDetailInfos(uids: string[]) { - //26702 以上使用新接口 .Dev Mlikiowa - type EventService = NodeIKernelProfileService['fetchUserDetailInfo']; - type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']; - let retData: User[] = []; - let [_retData, _retListener] = await this.core.eventWrapper.CallNormalEvent - - ( - 'NodeIKernelProfileService/fetchUserDetailInfo', - 'NodeIKernelProfileListener/onUserDetailInfoChanged', - uids.length, - 5000, - (profile) => { - if (uids.includes(profile.uid)) { - let RetUser: User = { - ...profile.simpleInfo.coreInfo, - ...profile.simpleInfo.status, - ...profile.simpleInfo.vasInfo, - ...profile.commonExt, - ...profile.simpleInfo.baseInfo, - qqLevel: profile.commonExt.qqLevel, - pendantId: "" - }; - retData.push(RetUser); - return true; - } - return false; - }, - "BuddyProfileStore", - uids, - UserDetailSource.KSERVER, - [ - ProfileBizType.KALL - ] - ); + async getProfileLike(uid: string) { + return this.context.session.getProfileLikeService().getBuddyProfileLike({ + friendUids: [ + uid, + ], + basic: 1, + vote: 1, + favorite: 0, + userProfile: 1, + type: 2, + start: 0, + limit: 20, + }); + } - return retData; - } - async fetchUserDetailInfo(uid: string) { - type EventService = NodeIKernelProfileService['fetchUserDetailInfo']; - type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']; - let [_retData, profile] = await this.core.eventWrapper.CallNormalEvent - - ( - 'NodeIKernelProfileService/fetchUserDetailInfo', - 'NodeIKernelProfileListener/onUserDetailInfoChanged', - 1, - 5000, - (profile) => { - if (profile.uid === uid) { - return true; - } - return false; - }, - "BuddyProfileStore", - [ - uid - ], - UserDetailSource.KSERVER, - [ - ProfileBizType.KALL - ] - ); - let RetUser: User = { - ...profile.simpleInfo.coreInfo, - ...profile.simpleInfo.status, - ...profile.simpleInfo.vasInfo, - ...profile.commonExt, - ...profile.simpleInfo.baseInfo, - qqLevel: profile.commonExt.qqLevel, - pendantId: "" - }; - return RetUser; - } - async getUserDetailInfo(uid: string) { - if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { - return this.fetchUserDetailInfo(uid); + async setLongNick(longNick: string) { + return this.context.session.getProfileService().setLongNick(longNick); } - return this.getUserDetailInfoOld(uid); - } - async getUserDetailInfoOld(uid: string) { - type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo']; - type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged']; - let [_retData, profile] = await this.core.eventWrapper.CallNormalEvent - - ( - 'NodeIKernelProfileService/getUserDetailInfoWithBizInfo', - 'NodeIKernelProfileListener/onProfileDetailInfoChanged', - 2, - 5000, - (profile: User) => { - if (profile.uid === uid) { - return true; - } - return false; - }, - uid, - [0] - ); - return profile; - } - async modifySelfProfile(param: ModifyProfileParams) { - return this.context.session.getProfileService().modifyDesktopMiniProfile(param); - } - //需要异常处理 - async getCookies(domain: string) { - const ClientKeyData = await this.forceFetchClientKey(); - const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin + '&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + this.core.selfInfo.uin + '%2Finfocenter&keyindex=19%27' - let cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl); - return cookies; - } - async getPSkey(domainList: string[]) { - return await this.context.session.getTipOffService().getPskey(domainList, true); - } - async getRobotUinRange(): Promise> { - const robotUinRanges = await this.context.session.getRobotService().getRobotUinRange({ - justFetchMsgConfig: '1', - type: 1, - version: 0, - aioKeywordVersion: 0 - }); - // console.log(robotUinRanges?.response?.robotUinRanges); - return robotUinRanges?.response?.robotUinRanges; - } - //需要异常处理 - async getQzoneCookies() { - const ClientKeyData = await this.forceFetchClientKey(); - const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin + '&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2Fuser.qzone.qq.com%2F' + this.core.selfInfo.uin + '%2Finfocenter&keyindex=19%27' - let cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl); - return cookies; - } - //需要异常处理 + async setSelfOnlineStatus(status: number, extStatus: number, batteryStatus: number) { + return this.context.session.getMsgService().setStatus({ + status: status, + extStatus: extStatus, + batteryStatus: batteryStatus, + }); + } - async getSkey(): Promise { - const ClientKeyData = await this.forceFetchClientKey(); - if (ClientKeyData.result !== 0) { - throw new Error('getClientKey Error'); + async getBuddyRecommendContactArkJson(uin: string, sencenID = '') { + return this.context.session.getBuddyService().getBuddyRecommendContactArkJson(uin, sencenID); } - const clientKey = ClientKeyData.clientKey; - const keyIndex = ClientKeyData.keyIndex; - const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin + '&clientkey=' + clientKey + '&u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=19%27'; - let cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl); - const skey = cookies['skey']; - if (!skey) { - throw new Error('getSkey Skey is Empty'); - } - return skey; - } - async getUidByUin(Uin: string) { - //此代码仅临时使用,后期会被废弃 - if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { - return await this.getUidByUinV2(Uin); - } - return await this.getUidByUinV1(Uin); - } - async getUinByUid(Uid: string) { - //此代码仅临时使用,后期会被废弃 - if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { - return await this.getUinByUidV2(Uid); - } - return await this.getUinByUidV1(Uid); - } - //后期改成流水线处理 - async getUidByUinV2(Uin: string) { - let uid = (await this.context.session.getProfileService().getUidByUin('FriendsServiceImpl', [Uin])).get(Uin); - if (uid) return uid; - uid = (await this.context.session.getGroupService().getUidByUins([Uin])).uids.get(Uin); - if (uid) return uid; - uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin); - if (uid) return uid; - console.log((await this.core.getApiContext().FriendApi.getBuddyIdMapCache(true))); - uid = (await this.core.getApiContext().FriendApi.getBuddyIdMapCache(true)).getValue(Uin);//从Buddy缓存获取Uid - if (uid) return uid; - uid = (await this.core.getApiContext().FriendApi.getBuddyIdMap(true)).getValue(Uin); - if (uid) return uid; - let unveifyUid = (await this.getUserDetailInfoByUinV2(Uin)).detail.uid;//从QQ Native 特殊转换 - if (unveifyUid.indexOf("*") == -1) uid = unveifyUid; - //if (uid) return uid; - return uid; - } - //后期改成流水线处理 - async getUinByUidV2(Uid: string) { - let uin = (await this.context.session.getProfileService().getUinByUid('FriendsServiceImpl', [Uid])).get(Uid); - if (uin) return uin; - uin = (await this.context.session.getGroupService().getUinByUids([Uid])).uins.get(Uid); - if (uin) return uin; - uin = (await this.context.session.getUixConvertService().getUin([Uid])).uinInfo.get(Uid); - if (uin) return uin; - uin = (await this.core.getApiContext().FriendApi.getBuddyIdMapCache(true)).getKey(Uid);//从Buddy缓存获取Uin - if (uin) return uin; - uin = (await this.core.getApiContext().FriendApi.getBuddyIdMap(true)).getKey(Uid); - if (uin) return uin; - uin = (await this.getUserDetailInfo(Uid)).uin; //从QQ Native 转换 - return uin; - } + async like(uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number }> { + return this.context.session.getProfileLikeService().setBuddyProfileLike({ + friendUid: uid, + sourceId: 71, + doLikeCount: count, + doLikeTollCount: 0, + }); + } - async getUidByUinV1(Uin: string) { - // 通用转换开始尝试 - let uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin); - if (!uid) { - let unveifyUid = (await this.getUserDetailInfoByUin(Uin)).info.uid;//从QQ Native 特殊转换 方法三 - if (unveifyUid.indexOf("*") == -1) { - uid = unveifyUid; - } + async setQQAvatar(filePath: string) { + type setQQAvatarRet = { result: number, errMsg: string }; + const ret = await this.context.session.getProfileService().setHeader(filePath) as setQQAvatarRet; + return { result: ret?.result, errMsg: ret?.errMsg }; } - return uid; - } - async getUinByUidV1(Uid: string) { - let ret = await this.core.eventWrapper.callNoListenerEvent - <(Uin: string[]) => Promise<{ uinInfo: Map }>>( - 'NodeIKernelUixConvertService/getUin', - 5000, - [Uid] - ); - let uin = ret.uinInfo.get(Uid); - if (!uin) { - uin = (await this.getUserDetailInfo(Uid)).uin; //从QQ Native 转换 + + async setGroupAvatar(gc: string, filePath: string) { + return this.context.session.getGroupService().setHeader(gc, filePath); + } + + async fetchUserDetailInfos(uids: string[]) { + //26702 以上使用新接口 .Dev Mlikiowa + type EventService = NodeIKernelProfileService['fetchUserDetailInfo']; + type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']; + const retData: User[] = []; + const [_retData, _retListener] = await this.core.eventWrapper.CallNormalEvent< + EventService, EventListener + >( + 'NodeIKernelProfileService/fetchUserDetailInfo', + 'NodeIKernelProfileListener/onUserDetailInfoChanged', + uids.length, + 5000, + (profile) => { + if (uids.includes(profile.uid)) { + const RetUser: User = { + ...profile.simpleInfo.coreInfo, + ...profile.simpleInfo.status, + ...profile.simpleInfo.vasInfo, + ...profile.commonExt, + ...profile.simpleInfo.baseInfo, + qqLevel: profile.commonExt.qqLevel, + pendantId: '', + }; + retData.push(RetUser); + return true; + } + return false; + }, + 'BuddyProfileStore', + uids, + UserDetailSource.KSERVER, + [ProfileBizType.KALL], + ); + + return retData; + } + + async fetchUserDetailInfo(uid: string) { + type EventService = NodeIKernelProfileService['fetchUserDetailInfo']; + type EventListener = NodeIKernelProfileListener['onUserDetailInfoChanged']; + const [_retData, profile] = await this.core.eventWrapper.CallNormalEvent( + 'NodeIKernelProfileService/fetchUserDetailInfo', + 'NodeIKernelProfileListener/onUserDetailInfoChanged', + 1, + 5000, + (profile) => profile.uid === uid, + 'BuddyProfileStore', + [uid], + UserDetailSource.KSERVER, + [ProfileBizType.KALL], + ); + const RetUser: User = { + ...profile.simpleInfo.coreInfo, + ...profile.simpleInfo.status, + ...profile.simpleInfo.vasInfo, + ...profile.commonExt, + ...profile.simpleInfo.baseInfo, + qqLevel: profile.commonExt.qqLevel, + pendantId: '', + }; + return RetUser; + } + + async getUserDetailInfo(uid: string) { + if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { + return this.fetchUserDetailInfo(uid); + } + return this.getUserDetailInfoOld(uid); + } + + async getUserDetailInfoOld(uid: string) { + type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo']; + type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged']; + const [_retData, profile] = await this.core.eventWrapper.CallNormalEvent( + 'NodeIKernelProfileService/getUserDetailInfoWithBizInfo', + 'NodeIKernelProfileListener/onProfileDetailInfoChanged', + 2, + 5000, + (profile) => profile.uid === uid, + uid, + [0], + ); + return profile; + } + + async modifySelfProfile(param: ModifyProfileParams) { + return this.context.session.getProfileService().modifyDesktopMiniProfile(param); + } + + //需要异常处理 + async getCookies(domain: string) { + const ClientKeyData = await this.forceFetchClientKey(); + const requestUrl = `https://ssl.ptlogin2.qq.com/jump?${ + new URLSearchParams({ + ptlang: '1033', + clientuin: this.core.selfInfo.uin, + clientkey: ClientKeyData.clientKey, + u1: `https://user.qzone.qq.com/${this.core.selfInfo.uin}/infocenter`, + keyindex: '19', + }) + }`; + return await RequestUtil.HttpsGetCookies(requestUrl); + } + + async getPSkey(domainList: string[]) { + return await this.context.session.getTipOffService().getPskey(domainList, true); + } + + async getRobotUinRange(): Promise> { + const robotUinRanges = await this.context.session.getRobotService().getRobotUinRange({ + justFetchMsgConfig: '1', + type: 1, + version: 0, + aioKeywordVersion: 0, + }); + // console.log(robotUinRanges?.response?.robotUinRanges); + return robotUinRanges?.response?.robotUinRanges; + } + + //需要异常处理 + + async getQzoneCookies() { + const ClientKeyData = await this.forceFetchClientKey(); + const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin + '&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2Fuser.qzone.qq.com%2F' + this.core.selfInfo.uin + '%2Finfocenter&keyindex=19%27'; + const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl); + return cookies; + } + + //需要异常处理 + + async getSkey(): Promise { + const ClientKeyData = await this.forceFetchClientKey(); + if (ClientKeyData.result !== 0) { + throw new Error('getClientKey Error'); + } + const clientKey = ClientKeyData.clientKey; + const keyIndex = ClientKeyData.keyIndex; + const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + this.core.selfInfo.uin + '&clientkey=' + clientKey + '&u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=19%27'; + const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl); + const skey = cookies['skey']; + if (!skey) { + throw new Error('getSkey Skey is Empty'); + } + return skey; + } + + /** + * @deprecated + */ + async getUidByUin(Uin: string) { + if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { + return await this.getUidByUinV2(Uin); + } + return await this.getUidByUinV1(Uin); + } + + /** + * @deprecated + */ + async getUinByUid(Uid: string) { + if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { + return await this.getUinByUidV2(Uid); + } + return await this.getUinByUidV1(Uid); + } + + //后期改成流水线处理 + async getUidByUinV2(Uin: string) { + let uid = (await this.context.session.getProfileService().getUidByUin('FriendsServiceImpl', [Uin])).get(Uin); + if (uid) return uid; + uid = (await this.context.session.getGroupService().getUidByUins([Uin])).uids.get(Uin); + if (uid) return uid; + uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin); + if (uid) return uid; + console.log((await this.core.getApiContext().FriendApi.getBuddyIdMapCache(true))); + uid = (await this.core.getApiContext().FriendApi.getBuddyIdMapCache(true)).getValue(Uin);//从Buddy缓存获取Uid + if (uid) return uid; + uid = (await this.core.getApiContext().FriendApi.getBuddyIdMap(true)).getValue(Uin); + if (uid) return uid; + const unveifyUid = (await this.getUserDetailInfoByUinV2(Uin)).detail.uid;//从QQ Native 特殊转换 + if (unveifyUid.indexOf('*') == -1) uid = unveifyUid; + //if (uid) return uid; + return uid; + } + + //后期改成流水线处理 + async getUinByUidV2(Uid: string) { + let uin = (await this.context.session.getProfileService().getUinByUid('FriendsServiceImpl', [Uid])).get(Uid); + if (uin) return uin; + uin = (await this.context.session.getGroupService().getUinByUids([Uid])).uins.get(Uid); + if (uin) return uin; + uin = (await this.context.session.getUixConvertService().getUin([Uid])).uinInfo.get(Uid); + if (uin) return uin; + uin = (await this.core.getApiContext().FriendApi.getBuddyIdMapCache(true)).getKey(Uid);//从Buddy缓存获取Uin + if (uin) return uin; + uin = (await this.core.getApiContext().FriendApi.getBuddyIdMap(true)).getKey(Uid); + if (uin) return uin; + uin = (await this.getUserDetailInfo(Uid)).uin; //从QQ Native 转换 + return uin; + } + + async getUidByUinV1(Uin: string) { + // 通用转换开始尝试 + let uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin); + if (!uid) { + const unveifyUid = (await this.getUserDetailInfoByUin(Uin)).info.uid;//从QQ Native 特殊转换 方法三 + if (unveifyUid.indexOf('*') == -1) { + uid = unveifyUid; + } + } + return uid; + } + + async getUinByUidV1(Uid: string) { + const ret = await this.core.eventWrapper.callNoListenerEvent<(Uin: string[]) => Promise<{ uinInfo: Map }>> + ('NodeIKernelUixConvertService/getUin', 5000, [Uid]); + let uin = ret.uinInfo.get(Uid); + if (!uin) { + uin = (await this.getUserDetailInfo(Uid)).uin; //从QQ Native 转换 + } + // if (!uin) { + // uin = (await NTQQFriendApi.getFriends(false)).find((t) => { t.uid == Uid })?.uin; //从QQ Native 缓存转换 + // } + // if (!uin) { + // uin = (await NTQQFriendApi.getFriends(true)).find((t) => { t.uid == Uid })?.uin; //从QQ Native 非缓存转换 + // } + return uin; + } + + async getRecentContactListSnapShot(count: number) { + return await this.context.session.getRecentContactService().getRecentContactListSnapShot(count); + } + + async getRecentContactListSyncLimit(count: number) { + return await this.context.session.getRecentContactService().getRecentContactListSyncLimit(count); + } + + async getRecentContactListSync() { + return await this.context.session.getRecentContactService().getRecentContactListSync(); + } + + async getRecentContactList() { + return await this.context.session.getRecentContactService().getRecentContactList(); + } + + async getUserDetailInfoByUinV2(Uin: string) { + return await this.core.eventWrapper.callNoListenerEvent<(Uin: string) => Promise> + ('NodeIKernelProfileService/getUserDetailInfoByUin', 5000, Uin); + } + + async getUserDetailInfoByUin(Uin: string) { + return this.core.eventWrapper.callNoListenerEvent<(Uin: string) => Promise> + ('NodeIKernelProfileService/getUserDetailInfoByUin', 5000, Uin); + } + async forceFetchClientKey() { + return await this.context.session.getTicketService().forceFetchClientKey(''); } - // if (!uin) { - // uin = (await NTQQFriendApi.getFriends(false)).find((t) => { t.uid == Uid })?.uin; //从QQ Native 缓存转换 - // } - // if (!uin) { - // uin = (await NTQQFriendApi.getFriends(true)).find((t) => { t.uid == Uid })?.uin; //从QQ Native 非缓存转换 - // } - return uin; - } - async getRecentContactListSnapShot(count: number) { - return await this.context.session.getRecentContactService().getRecentContactListSnapShot(count); - } - async getRecentContactListSyncLimit(count: number) { - return await this.context.session.getRecentContactService().getRecentContactListSyncLimit(count); - } - async getRecentContactListSync() { - return await this.context.session.getRecentContactService().getRecentContactListSync(); - } - async getRecentContactList() { - return await this.context.session.getRecentContactService().getRecentContactList(); - } - async getUserDetailInfoByUinV2(Uin: string) { - return await this.core.eventWrapper.callNoListenerEvent - <(Uin: string) => Promise>( - 'NodeIKernelProfileService/getUserDetailInfoByUin', - 5000, - Uin - ); - } - async getUserDetailInfoByUin(Uin: string) { - return this.core.eventWrapper.callNoListenerEvent - <(Uin: string) => Promise>( - 'NodeIKernelProfileService/getUserDetailInfoByUin', - 5000, - Uin - ); - } - async forceFetchClientKey() { - return await this.context.session.getTicketService().forceFetchClientKey(''); - } }