diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index f7e2260f..d6d6ed33 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -3,164 +3,160 @@ import { GeneralCallResult, InstanceContext, NapCatCore, NodeIKernelGroupService 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) { + 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 - ); + ( + 'NodeIKernelGroupService/getGroupList', + 'NodeIKernelGroupListener/onGroupListUpdate', + 1, + 5000, + (updateType) => true, + forced + ); return groupList; - } - async getGroupMemberLatestSendTimeCache(GroupCode: string) { - return this.getGroupMemberLatestSendTime(GroupCode); - } - /** - * 通过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) { - 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 currentGroupMembers = groupMembers.get(GroupCode); - const PromiseData: Promise<({ + } + 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(); - if (!currentGroupMembers) { - return ret; - } - for (const member of currentGroupMembers.values()) { - PromiseData.push(getdata(member.uid).catch(() => undefined)); - } - const allRet = await runAllWithTimeout(PromiseData, 2500); - for (const PromiseDo of allRet) { - if (PromiseDo) { - ret.set(PromiseDo.sendUin, PromiseDo.sendTime); - } - } - return ret; + const ret: Map = new Map(); + for (const uid of uids) { + PromiseData.push(getdata(uid).catch(() => undefined)); } - 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; + const allRet = await runAllWithTimeout(PromiseData, 2500); + for (const PromiseDo of allRet) { + if (PromiseDo) { + ret.set(PromiseDo.sendUin, PromiseDo.sendTime); + } } - async getGroupMemberAll(GroupCode: string, forced = false) { - return this.context.session.getGroupService().getAllMemberList(GroupCode, forced); + 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); + } } - 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) { + 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) { + 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 + 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) { + ( + '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', @@ -168,27 +164,27 @@ export class NTQQGroupApi { 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 + '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); } - 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; + //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); @@ -196,134 +192,134 @@ export class NTQQGroupApi { return result; */ - } + } - async getGroupNotifies() { + 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 + } + 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 + '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 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 || ' ' // 仅传空值可能导致处理失败,故默认给个空格 - } - }); - } + 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 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 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 }>) { + async banMember(groupQQ: string, memList: Array<{ uid: string, timeStamp: number }>) { // timeStamp为秒数, 0为解除禁言 - return this.context.session.getGroupService().setMemberShutUp(groupQQ, memList); - } + return this.context.session.getGroupService().setMemberShutUp(groupQQ, memList); + } - async banGroup(groupQQ: string, shutUp: boolean) { - return this.context.session.getGroupService().setGroupShutUp(groupQQ, shutUp); - } + 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 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 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 setGroupName(groupQQ: string, groupName: string) { + return this.context.session.getGroupService().modifyGroupName(groupQQ, groupName, false); + } - // 头衔不可用 - async setGroupTitle(groupQQ: string, uid: string, title: string) { + // 头衔不可用 + 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) { + 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 - } - } - ); - } + 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/user.ts b/src/core/apis/user.ts index 1e8a919c..7cc13a54 100644 --- a/src/core/apis/user.ts +++ b/src/core/apis/user.ts @@ -253,24 +253,6 @@ export class NTQQUserApi { async getUidByUinV1(Uin: string) { // 通用转换开始尝试 let uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin); - // Uid 好友转 - if (!uid) { - Array.from(friends.values()).forEach((t) => { - if (t.uin == Uin) { - uid = t.uid; - } - }); - } - //Uid 群友列表转 - if (!uid) { - for (let groupMembersList of groupMembers.values()) { - for (let GroupMember of groupMembersList.values()) { - if (GroupMember.uin == Uin) { - uid = GroupMember.uid; - } - } - } - } if (!uid) { let unveifyUid = (await this.getUserDetailInfoByUin(Uin)).info.uid;//从QQ Native 特殊转换 方法三 if (unveifyUid.indexOf("*") == -1) { @@ -287,18 +269,9 @@ export class NTQQUserApi { [Uid] ); let uin = ret.uinInfo.get(Uid); - if (!uin) { - //从Buddy缓存获取Uin - Array.from(friends.values()).forEach((t) => { - if (t.uid == Uid) { - uin = t.uin; - } - }) - } 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 缓存转换 // }