diff --git a/src/ntqqapi/api/file.ts b/src/ntqqapi/api/file.ts index 5f7dfe6..b233621 100644 --- a/src/ntqqapi/api/file.ts +++ b/src/ntqqapi/api/file.ts @@ -28,6 +28,7 @@ import { OnRichMediaDownloadCompleteParams } from '@/ntqqapi/listeners' import { Time } from 'cosmokit' export class NTQQFileApi { + /** 27187 TODO */ static async getVideoUrl(peer: Peer, msgId: string, elementId: string) { const session = getSession() return (await session?.getRichMediaService().getVideoPlayUrlV2(peer, diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts index f05d320..df028ea 100644 --- a/src/ntqqapi/api/group.ts +++ b/src/ntqqapi/api/group.ts @@ -1,6 +1,6 @@ import { ReceiveCmdS } from '../hook' import { Group, GroupMember, GroupMemberRole, GroupNotifies, GroupRequestOperateTypes, GroupNotify } from '../types' -import { invoke, NTMethod } from '../ntcall' +import { invoke, NTClass, NTMethod } from '../ntcall' import { GeneralCallResult } from '../services' import { NTQQWindowApi, NTQQWindows } from './window' import { getSession } from '../wrapper' @@ -10,18 +10,31 @@ import { NodeIKernelGroupService } from '../services' export class NTQQGroupApi { static async getGroups(forced = false): Promise { - type ListenerType = NodeIKernelGroupListener['onGroupListUpdate'] - const [, , groupList] = await NTEventDispatch.CallNormalEvent - <(force: boolean) => Promise, ListenerType> - ( - 'NodeIKernelGroupService/getGroupList', - 'NodeIKernelGroupListener/onGroupListUpdate', - 1, - 5000, - () => true, - forced - ) - return groupList + if (NTEventDispatch.initialised) { + type ListenerType = NodeIKernelGroupListener['onGroupListUpdate'] + const [, , groupList] = await NTEventDispatch.CallNormalEvent + <(force: boolean) => Promise, ListenerType> + ( + 'NodeIKernelGroupService/getGroupList', + 'NodeIKernelGroupListener/onGroupListUpdate', + 1, + 5000, + () => true, + forced + ) + return groupList + } else { + const result = await invoke<{ + updateType: number + groupList: Group[] + }>({ + className: NTClass.NODE_STORE_API, + methodName: 'getGroupList', + cbCmd: ReceiveCmdS.GROUPS_STORE, + afterFirstCmd: false, + }) + return result.groupList + } } static async getGroupMembers(groupQQ: string, num = 3000): Promise> { @@ -60,23 +73,8 @@ export class NTQQGroupApi { return result.result.infos } - static async getGroupNotifies() { - // 获取管理员变更 - // 加群通知,退出通知,需要管理员权限 - invoke({ - methodName: ReceiveCmdS.GROUP_NOTIFY, - classNameIsRegister: true, - }).then() - return await invoke({ - methodName: NTMethod.GET_GROUP_NOTICE, - cbCmd: ReceiveCmdS.GROUP_NOTIFY, - afterFirstCmd: false, - args: [{ doubt: false, startSeq: '', number: 14 }, null], - }) - } - static async getGroupIgnoreNotifies() { - await NTQQGroupApi.getGroupNotifies() + await NTQQGroupApi.getSingleScreenNotifies(14) return await NTQQWindowApi.openWindow( NTQQWindows.GroupNotifyFilterWindow, [], @@ -85,50 +83,86 @@ export class NTQQGroupApi { } static async getSingleScreenNotifies(num: number) { - const [_retData, _doubt, _seq, notifies] = await NTEventDispatch.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 + if (NTEventDispatch.initialised) { + const [_retData, _doubt, _seq, notifies] = await NTEventDispatch.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 + } else { + return await invoke({ + methodName: NTMethod.GET_GROUP_NOTICE, + cbCmd: ReceiveCmdS.GROUP_NOTIFY, + afterFirstCmd: false, + args: [{ doubt: false, startSeq: '', number: num }, null], + }) + } } + /** 27187 TODO */ static async delGroupFile(groupCode: string, files: string[]) { const session = getSession() return session?.getRichMediaService().deleteGroupFile(groupCode, [102], files)! } - static DelGroupFile = NTQQGroupApi.delGroupFile - static 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]) const session = getSession() - return session?.getGroupService().operateSysNotify( - false, - { - 'operateType': operateType, // 2 拒绝 - 'targetMsg': { - 'seq': seq, // 通知序列号 - 'type': type, - 'groupCode': groupCode, - 'postscript': reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格 - } + if (session) { + return session.getGroupService().operateSysNotify( + false, + { + 'operateType': operateType, // 2 拒绝 + 'targetMsg': { + 'seq': seq, // 通知序列号 + 'type': type, + 'groupCode': groupCode, + 'postscript': reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格 + } + }) + } else { + return await invoke({ + methodName: NTMethod.HANDLE_GROUP_REQUEST, + args: [ + { + doubt: false, + operateMsg: { + operateType, + targetMsg: { + seq, + type, + groupCode, + postscript: reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格 + }, + }, + }, + null, + ], }) + } } static async quitGroup(groupQQ: string) { const session = getSession() - return session?.getGroupService().quitGroup(groupQQ) + if (session) { + return session.getGroupService().quitGroup(groupQQ) + } else { + return await invoke({ + methodName: NTMethod.QUIT_GROUP, + args: [{ groupCode: groupQQ }, null], + }) + } } static async kickMember( @@ -138,33 +172,113 @@ export class NTQQGroupApi { kickReason = '', ) { const session = getSession() - return session?.getGroupService().kickMember(groupQQ, kickUids, refuseForever, kickReason) + if (session) { + return session.getGroupService().kickMember(groupQQ, kickUids, refuseForever, kickReason) + } else { + return await invoke({ + methodName: NTMethod.KICK_MEMBER, + args: [ + { + groupCode: groupQQ, + kickUids, + refuseForever, + kickReason, + }, + ], + }) + } } static async banMember(groupQQ: string, memList: Array<{ uid: string, timeStamp: number }>) { // timeStamp为秒数, 0为解除禁言 const session = getSession() - return session?.getGroupService().setMemberShutUp(groupQQ, memList) + if (session) { + return session.getGroupService().setMemberShutUp(groupQQ, memList) + } else { + return await invoke({ + methodName: NTMethod.MUTE_MEMBER, + args: [ + { + groupCode: groupQQ, + memList, + }, + ], + }) + } } static async banGroup(groupQQ: string, shutUp: boolean) { const session = getSession() - return session?.getGroupService().setGroupShutUp(groupQQ, shutUp) + if (session) { + return session.getGroupService().setGroupShutUp(groupQQ, shutUp) + } else { + return await invoke({ + methodName: NTMethod.MUTE_GROUP, + args: [ + { + groupCode: groupQQ, + shutUp, + }, + null, + ], + }) + } } static async setMemberCard(groupQQ: string, memberUid: string, cardName: string) { const session = getSession() - return session?.getGroupService().modifyMemberCardName(groupQQ, memberUid, cardName) + if (session) { + return session.getGroupService().modifyMemberCardName(groupQQ, memberUid, cardName) + } else { + return await invoke({ + methodName: NTMethod.SET_MEMBER_CARD, + args: [ + { + groupCode: groupQQ, + uid: memberUid, + cardName, + }, + null, + ], + }) + } } static async setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole) { const session = getSession() - return session?.getGroupService().modifyMemberRole(groupQQ, memberUid, role) + if (session) { + return session.getGroupService().modifyMemberRole(groupQQ, memberUid, role) + } else { + return await invoke({ + methodName: NTMethod.SET_MEMBER_ROLE, + args: [ + { + groupCode: groupQQ, + uid: memberUid, + role, + }, + null, + ], + }) + } } static async setGroupName(groupQQ: string, groupName: string) { const session = getSession() - return session?.getGroupService().modifyGroupName(groupQQ, groupName, false) + if (session) { + return session.getGroupService().modifyGroupName(groupQQ, groupName, false) + } else { + return await invoke({ + methodName: NTMethod.SET_GROUP_NAME, + args: [ + { + groupCode: groupQQ, + groupName, + }, + null, + ], + }) + } } static async getGroupAtAllRemainCount(groupCode: string) { @@ -189,6 +303,7 @@ export class NTQQGroupApi { }) } + /** 27187 TODO */ static async removeGroupEssence(GroupCode: string, msgId: string) { const session = getSession() // 代码没测过 @@ -203,6 +318,7 @@ export class NTQQGroupApi { return session?.getGroupService().removeGroupEssence(param) } + /** 27187 TODO */ static async addGroupEssence(GroupCode: string, msgId: string) { const session = getSession() // 代码没测过 diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts index 168f3e2..8f4781a 100644 --- a/src/ntqqapi/ntcall.ts +++ b/src/ntqqapi/ntcall.ts @@ -118,63 +118,57 @@ export function invoke(params: InvokeParams) { } const apiArgs = [params.methodName, ...(params.args ?? [])] //log('callNTQQApi', channel, eventName, apiArgs, uuid) - return new Promise((resolve: (data: ReturnType) => void, reject) => { - let success = false - if (!params.cbCmd) { - // QQ后端会返回结果,并且可以根据uuid识别 - hookApiCallbacks[uuid] = (r: ReturnType) => { - success = true - resolve(r) + return Promise.race([ + new Promise((_, reject) => setTimeout(() => { + log(`ntqq api timeout ${channel}, ${eventName}, ${params.methodName}`, apiArgs) + reject(`ntqq api timeout ${channel}, ${eventName}, ${params.methodName}, ${apiArgs}`) + }, timeout)), + new Promise((resolve: (data: ReturnType) => void, reject) => { + if (!params.cbCmd) { + // QQ后端会返回结果,并且可以根据uuid识别 + hookApiCallbacks[uuid] = (r: ReturnType) => { + resolve(r) + } } - } - else { - // 这里的callback比较特殊,QQ后端先返回是否调用成功,再返回一条结果数据 - const secondCallback = () => { - const hookId = registerReceiveHook(params.cbCmd!, (payload) => { - // log(methodName, "second callback", cbCmd, payload, cmdCB); - if (!!params.cmdCB) { - if (params.cmdCB(payload)) { + else { + // 这里的callback比较特殊,QQ后端先返回是否调用成功,再返回一条结果数据 + const secondCallback = () => { + const hookId = registerReceiveHook(params.cbCmd!, (payload) => { + // log(methodName, "second callback", cbCmd, payload, cmdCB); + if (!!params.cmdCB) { + if (params.cmdCB(payload)) { + removeReceiveHook(hookId) + resolve(payload) + } + } + else { removeReceiveHook(hookId) - success = true resolve(payload) } + }) + } + !afterFirstCmd && secondCallback() + hookApiCallbacks[uuid] = (result: GeneralCallResult) => { + log(`${params.methodName} callback`, result) + if (result?.result === 0 || result === undefined) { + afterFirstCmd && secondCallback() } else { - removeReceiveHook(hookId) - success = true - resolve(payload) + reject(`ntqq api call failed, ${result.errMsg}`) } - }) - } - !afterFirstCmd && secondCallback() - hookApiCallbacks[uuid] = (result: GeneralCallResult) => { - log(`${params.methodName} callback`, result) - if (result?.result === 0 || result === undefined) { - afterFirstCmd && secondCallback() - } - else { - success = true - reject(`ntqq api call failed, ${result.errMsg}`) } } - } - setTimeout(() => { - if (!success) { - log(`ntqq api timeout ${channel}, ${eventName}, ${params.methodName}`, apiArgs) - reject(`ntqq api timeout ${channel}, ${eventName}, ${params.methodName}, ${apiArgs}`) - } - }, timeout) - - ipcMain.emit( - channel, - { - sender: { - send: (..._args: unknown[]) => { + ipcMain.emit( + channel, + { + sender: { + send: (..._args: unknown[]) => { + }, }, }, - }, - { type: 'request', callbackId: uuid, eventName }, - apiArgs, - ) - }) + { type: 'request', callbackId: uuid, eventName }, + apiArgs, + ) + }) + ]) } \ No newline at end of file