diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts index fe59da8..126a440 100644 --- a/src/ntqqapi/api/msg.ts +++ b/src/ntqqapi/api/msg.ts @@ -298,10 +298,26 @@ export class NTQQMsgApi { throw new Error('转发消息超时') } - /** 27187 TODO */ static async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) { const session = getSession() - return await session?.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z) + if (session) { + return await session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z) + } else { + return await invoke({ + methodName: 'nodeIKernelMsgService/getMsgsBySeqAndCount', + args: [ + { + peer, + cnt: count, + msgSeq: seq, + queryOrder: desc + }, + null, + ], + }) + } } /** 27187 TODO */ @@ -320,9 +336,23 @@ export class NTQQMsgApi { return ret } - /** 27187 TODO */ static async getSingleMsg(peer: Peer, seq: string) { const session = getSession() - return await session?.getMsgService().getSingleMsg(peer, seq) + if (session) { + return await session.getMsgService().getSingleMsg(peer, seq) + } else { + return await invoke({ + methodName: 'nodeIKernelMsgService/getSingleMsg', + args: [ + { + peer, + msgSeq: seq, + }, + null, + ], + }) + } } } diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts index e88495a..16ab690 100644 --- a/src/ntqqapi/api/user.ts +++ b/src/ntqqapi/api/user.ts @@ -78,25 +78,42 @@ export class NTQQUserApi { if (getBuildVersion() >= 26702) { return NTQQUserApi.fetchUserDetailInfo(uid) } - type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo'] - type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged'] - const [_retData, profile] = await NTEventDispatch.CallNormalEvent - - ( - 'NodeIKernelProfileService/getUserDetailInfoWithBizInfo', - 'NodeIKernelProfileListener/onProfileDetailInfoChanged', - 2, - 5000, - (profile) => profile.uid === uid, - uid, - [0] - ) - return profile + if (NTEventDispatch.initialised) { + type EventService = NodeIKernelProfileService['getUserDetailInfoWithBizInfo'] + type EventListener = NodeIKernelProfileListener['onProfileDetailInfoChanged'] + const [_retData, profile] = await NTEventDispatch.CallNormalEvent + + ( + 'NodeIKernelProfileService/getUserDetailInfoWithBizInfo', + 'NodeIKernelProfileListener/onProfileDetailInfoChanged', + 2, + 5000, + (profile) => profile.uid === uid, + uid, + [0] + ) + return profile + } else { + const result = await invoke<{ info: User }>({ + methodName: 'nodeIKernelProfileService/getUserDetailInfoWithBizInfo', + cbCmd: 'nodeIKernelProfileListener/onProfileDetailInfoChanged', + afterFirstCmd: false, + cmdCB: (payload) => payload.info.uid === uid, + args: [ + { + uid, + bizList: [0] + }, + null, + ], + }) + return result.info + } } static async getSkey(): Promise { - const clientKeyData = await NTQQUserApi.getClientKey() - if (clientKeyData.result !== 0) { + const clientKeyData = await NTQQUserApi.forceFetchClientKey() + if (clientKeyData?.result !== 0) { throw new Error('获取clientKey失败') } const url = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + getSelfUin() @@ -107,9 +124,12 @@ export class NTQQUserApi { @CacheClassFuncAsync(1800 * 1000) static async getCookies(domain: string) { - const ClientKeyData = await NTQQUserApi.forceFetchClientKey() + const clientKeyData = await NTQQUserApi.forceFetchClientKey() + if (clientKeyData?.result !== 0) { + throw new Error('获取clientKey失败') + } const uin = getSelfUin() - const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + uin + '&clientkey=' + ClientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + uin + '%2Finfocenter&keyindex=19%27' + const requestUrl = 'https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=' + uin + '&clientkey=' + clientKeyData.clientKey + '&u1=https%3A%2F%2F' + domain + '%2F' + uin + '%2Finfocenter&keyindex=19%27' const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl) return cookies } @@ -126,6 +146,7 @@ export class NTQQUserApi { return (hash & 0x7fffffff).toString() } + /** 27187 TODO */ static async getPSkey(domains: string[]): Promise> { const session = getSession() const res = await session?.getTipOffService().getPskey(domains, true) @@ -135,19 +156,15 @@ export class NTQQUserApi { return res.domainPskeyMap } - static async getClientKey() { - const session = getSession() - return await session?.getTicketService().forceFetchClientKey('')! - } - - static async like(uid: string, count = 1): Promise<{ result: number, errMsg: string, succCounts: number }> { + /** 27187 TODO */ + static async like(uid: string, count = 1) { const session = getSession() return session?.getProfileLikeService().setBuddyProfileLike({ friendUid: uid, sourceId: 71, doLikeCount: count, doLikeTollCount: 0 - })! + }) } static async getUidByUinV1(Uin: string) { @@ -182,17 +199,45 @@ export class NTQQUserApi { } static async getUidByUinV2(uin: string) { - const session = getSession()! - let uid = (await session.getGroupService().getUidByUins([uin])).uids.get(uin) - if (uid) return uid - uid = (await session.getProfileService().getUidByUin('FriendsServiceImpl', [uin])).get(uin) - if (uid) return uid - uid = (await session.getUixConvertService().getUid([uin])).uidInfo.get(uin) - if (uid) return uid + const session = getSession() + if (session) { + let uid = (await session.getGroupService().getUidByUins([uin])).uids.get(uin) + if (uid) return uid + uid = (await session.getProfileService().getUidByUin('FriendsServiceImpl', [uin])).get(uin) + if (uid) return uid + uid = (await session.getUixConvertService().getUid([uin])).uidInfo.get(uin) + if (uid) return uid + } else { + let uid = (await invoke<{ uids: Map }>({ + methodName: 'nodeIKernelGroupService/getUidByUins', + args: [ + { uin: [uin] }, + null, + ], + })).uids.get(uin) + if (uid) return uid + uid = (await invoke>({ + methodName: 'nodeIKernelProfileService/getUidByUin', + args: [ + { + callFrom: 'FriendsServiceImpl', + uin: [uin], + }, + null, + ], + })).get(uin) + if (uid) return uid + uid = (await invoke<{ uidInfo: Map }>({ + methodName: 'nodeIKernelUixConvertService/getUid', + args: [ + { uin: [uin] }, + null, + ], + })).uidInfo.get(uin) + if (uid) return uid + } const unveifyUid = (await NTQQUserApi.getUserDetailInfoByUinV2(uin)).detail.uid //从QQ Native 特殊转换 - if (unveifyUid.indexOf('*') == -1) uid = unveifyUid - //if (uid) return uid - return uid + if (unveifyUid.indexOf('*') == -1) return unveifyUid } static async getUidByUin(Uin: string) { @@ -202,14 +247,25 @@ export class NTQQUserApi { return await NTQQUserApi.getUidByUinV1(Uin) } - static async getUserDetailInfoByUinV2(Uin: string) { - return await NTEventDispatch.CallNoListenerEvent - <(Uin: string) => Promise>( - 'NodeIKernelProfileService/getUserDetailInfoByUin', - 5000, - Uin - ) + static async getUserDetailInfoByUinV2(uin: string) { + if (NTEventDispatch.initialised) { + return await NTEventDispatch.CallNoListenerEvent + <(Uin: string) => Promise>( + 'NodeIKernelProfileService/getUserDetailInfoByUin', + 5000, + uin + ) + } else { + return await invoke({ + methodName: 'nodeIKernelProfileService/getUserDetailInfoByUin', + args: [ + { uin }, + null, + ], + }) + } } + static async getUserDetailInfoByUin(Uin: string) { return NTEventDispatch.CallNoListenerEvent <(Uin: string) => Promise>( @@ -242,29 +298,59 @@ export class NTQQUserApi { } static async getUinByUidV2(uid: string) { - const session = getSession()! - let uin = (await session.getGroupService().getUinByUids([uid])).uins.get(uid) - if (uin) return uin - uin = (await session.getProfileService().getUinByUid('FriendsServiceImpl', [uid])).get(uid) - if (uin) return uin - uin = (await session.getUixConvertService().getUin([uid])).uinInfo.get(uid) - if (uin) return uin - uin = (await NTQQFriendApi.getBuddyIdMap(true)).getKey(uid) + const session = getSession() + if (session) { + let uin = (await session.getGroupService().getUinByUids([uid])).uins.get(uid) + if (uin) return uin + uin = (await session.getProfileService().getUinByUid('FriendsServiceImpl', [uid])).get(uid) + if (uin) return uin + uin = (await session.getUixConvertService().getUin([uid])).uinInfo.get(uid) + if (uin) return uin + return uin + } else { + let uin = (await invoke<{ uins: Map }>({ + methodName: 'nodeIKernelGroupService/getUinByUids', + args: [ + { uid: [uid] }, + null, + ], + })).uins.get(uid) + if (uin) return uin + uin = (await invoke>({ + methodName: 'nodeIKernelProfileService/getUinByUid', + args: [ + { + callFrom: 'FriendsServiceImpl', + uid: [uid], + }, + null, + ], + })).get(uid) + if (uin) return uin + uin = (await invoke<{ uinInfo: Map }>({ + methodName: 'nodeIKernelUixConvertService/getUin', + args: [ + { uid: [uid] }, + null, + ], + })).uinInfo.get(uid) + if (uin) return uin + } + let uin = (await NTQQFriendApi.getBuddyIdMap(true)).getKey(uid) if (uin) return uin uin = (await NTQQUserApi.getUserDetailInfo(uid)).uin //从QQ Native 转换 - return uin } static async getUinByUid(Uid: string) { if (getBuildVersion() >= 26702) { - return await NTQQUserApi.getUinByUidV2(Uid) + return (await NTQQUserApi.getUinByUidV2(Uid))! } return await NTQQUserApi.getUinByUidV1(Uid) } - @CacheClassFuncAsync(3600 * 1000, 'ClientKey') + /** 27187 TODO */ static async forceFetchClientKey() { const session = getSession() - return await session?.getTicketService().forceFetchClientKey('')! + return await session?.getTicketService().forceFetchClientKey('') } } diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts index 8f4781a..086eb56 100644 --- a/src/ntqqapi/ntcall.ts +++ b/src/ntqqapi/ntcall.ts @@ -118,57 +118,63 @@ export function invoke(params: InvokeParams) { } const apiArgs = [params.methodName, ...(params.args ?? [])] //log('callNTQQApi', channel, eventName, apiArgs, uuid) - 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) - } + return new Promise((resolve: (data: ReturnType) => void, reject) => { + let success = false + if (!params.cbCmd) { + // QQ后端会返回结果,并且可以根据uuid识别 + hookApiCallbacks[uuid] = (r: ReturnType) => { + success = true + 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)) { - removeReceiveHook(hookId) - resolve(payload) - } - } - else { + } + 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) + success = true resolve(payload) } - }) - } - !afterFirstCmd && secondCallback() - hookApiCallbacks[uuid] = (result: GeneralCallResult) => { - log(`${params.methodName} callback`, result) - if (result?.result === 0 || result === undefined) { - afterFirstCmd && secondCallback() } else { - reject(`ntqq api call failed, ${result.errMsg}`) + removeReceiveHook(hookId) + success = true + resolve(payload) } + }) + } + !afterFirstCmd && secondCallback() + hookApiCallbacks[uuid] = (result: GeneralCallResult) => { + if (result?.result === 0 || result === undefined) { + log(`${params.methodName} callback`, result) + afterFirstCmd && secondCallback() + } + else { + log('ntqq api call failed', result) + reject(`ntqq api call failed, ${result.errMsg}`) } } - ipcMain.emit( - channel, - { - sender: { - send: (..._args: unknown[]) => { - }, + } + 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[]) => { }, }, - { type: 'request', callbackId: uuid, eventName }, - apiArgs, - ) - }) - ]) + }, + { type: 'request', callbackId: uuid, eventName }, + apiArgs, + ) + }) } \ No newline at end of file diff --git a/src/onebot11/action/user/SendLike.ts b/src/onebot11/action/user/SendLike.ts index 4048814..b22c512 100644 --- a/src/onebot11/action/user/SendLike.ts +++ b/src/onebot11/action/user/SendLike.ts @@ -15,8 +15,8 @@ export default class SendLike extends BaseAction { const qq = payload.user_id.toString() const uid: string = await NTQQUserApi.getUidByUin(qq) || '' const result = await NTQQUserApi.like(uid, parseInt(payload.times?.toString()) || 1) - if (result.result !== 0) { - throw Error(result.errMsg) + if (result?.result !== 0) { + throw Error(result?.errMsg) } } catch (e) { throw `点赞失败 ${e}` diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index 7cdaacc..ad613ee 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -170,8 +170,7 @@ export class OB11Constructor { if ((!replyMsg || records.msgRandom !== replyMsg.msgRandom) && msg.peerUin !== '284840486') { throw new Error('回复消息消息验证失败') } - if (!replyMsg) throw new Error('找不到回复消息') - message_data['data']['id'] = MessageUnique.createMsg({ + message_data['data']['id'] = replyMsg && MessageUnique.createMsg({ peerUid: msg.peerUid, guildId: '', chatType: msg.chatType,