From da0ebd3f804be4336437be4d502e6e58e5954e69 Mon Sep 17 00:00:00 2001 From: idranme Date: Sun, 8 Sep 2024 23:37:20 +0800 Subject: [PATCH 1/4] refactor --- src/ntqqapi/api/window.ts | 4 +- src/ntqqapi/hook.ts | 150 ++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 91 deletions(-) diff --git a/src/ntqqapi/api/window.ts b/src/ntqqapi/api/window.ts index 0c0f742..e63be71 100644 --- a/src/ntqqapi/api/window.ts +++ b/src/ntqqapi/api/window.ts @@ -1,6 +1,6 @@ import { invoke, NTClass, NTMethod } from '../ntcall' import { GeneralCallResult } from '../services' -import { ReceiveCmd } from '../hook' +import { ReceiveCmdS } from '../hook' import { BrowserWindow } from 'electron' import { Service, Context } from 'cordis' @@ -39,7 +39,7 @@ export class NTQQWindowApi extends Service { async openWindow( ntQQWindow: NTQQWindow, args: unknown[], - cbCmd: ReceiveCmd | undefined, + cbCmd: ReceiveCmdS | undefined, autoCloseSeconds: number = 2, ) { const result = await invoke( diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index c99b3cf..8c1a6b0 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -6,48 +6,46 @@ import { Dict } from 'cosmokit' export const hookApiCallbacks: Record void> = {} -export const ReceiveCmdS = { - RECENT_CONTACT: 'nodeIKernelRecentContactListener/onRecentContactListChangedVer2', - UPDATE_MSG: 'nodeIKernelMsgListener/onMsgInfoListUpdate', - UPDATE_ACTIVE_MSG: 'nodeIKernelMsgListener/onActiveMsgInfoUpdate', - NEW_MSG: `nodeIKernelMsgListener/onRecvMsg`, - NEW_ACTIVE_MSG: `nodeIKernelMsgListener/onRecvActiveMsg`, - SELF_SEND_MSG: 'nodeIKernelMsgListener/onAddSendMsg', - USER_INFO: 'nodeIKernelProfileListener/onProfileSimpleChanged', - USER_DETAIL_INFO: 'nodeIKernelProfileListener/onProfileDetailInfoChanged', - GROUPS: 'nodeIKernelGroupListener/onGroupListUpdate', - GROUPS_STORE: 'onGroupListUpdate', - GROUP_MEMBER_INFO_UPDATE: 'nodeIKernelGroupListener/onMemberInfoChange', - FRIENDS: 'onBuddyListChange', - MEDIA_DOWNLOAD_COMPLETE: 'nodeIKernelMsgListener/onRichMediaDownloadComplete', - UNREAD_GROUP_NOTIFY: 'nodeIKernelGroupListener/onGroupNotifiesUnreadCountUpdated', - GROUP_NOTIFY: 'nodeIKernelGroupListener/onGroupSingleScreenNotifies', - FRIEND_REQUEST: 'nodeIKernelBuddyListener/onBuddyReqChange', - SELF_STATUS: 'nodeIKernelProfileListener/onSelfStatusChanged', - CACHE_SCAN_FINISH: 'nodeIKernelStorageCleanListener/onFinishScan', - MEDIA_UPLOAD_COMPLETE: 'nodeIKernelMsgListener/onRichMediaUploadComplete', - SKEY_UPDATE: 'onSkeyUpdate', -} as const +export enum ReceiveCmdS { + RECENT_CONTACT = 'nodeIKernelRecentContactListener/onRecentContactListChangedVer2', + UPDATE_MSG = 'nodeIKernelMsgListener/onMsgInfoListUpdate', + UPDATE_ACTIVE_MSG = 'nodeIKernelMsgListener/onActiveMsgInfoUpdate', + NEW_MSG = `nodeIKernelMsgListener/onRecvMsg`, + NEW_ACTIVE_MSG = `nodeIKernelMsgListener/onRecvActiveMsg`, + SELF_SEND_MSG = 'nodeIKernelMsgListener/onAddSendMsg', + USER_INFO = 'nodeIKernelProfileListener/onProfileSimpleChanged', + USER_DETAIL_INFO = 'nodeIKernelProfileListener/onProfileDetailInfoChanged', + GROUPS = 'nodeIKernelGroupListener/onGroupListUpdate', + GROUPS_STORE = 'onGroupListUpdate', + GROUP_MEMBER_INFO_UPDATE = 'nodeIKernelGroupListener/onMemberInfoChange', + FRIENDS = 'onBuddyListChange', + MEDIA_DOWNLOAD_COMPLETE = 'nodeIKernelMsgListener/onRichMediaDownloadComplete', + UNREAD_GROUP_NOTIFY = 'nodeIKernelGroupListener/onGroupNotifiesUnreadCountUpdated', + GROUP_NOTIFY = 'nodeIKernelGroupListener/onGroupSingleScreenNotifies', + FRIEND_REQUEST = 'nodeIKernelBuddyListener/onBuddyReqChange', + SELF_STATUS = 'nodeIKernelProfileListener/onSelfStatusChanged', + CACHE_SCAN_FINISH = 'nodeIKernelStorageCleanListener/onFinishScan', + MEDIA_UPLOAD_COMPLETE = 'nodeIKernelMsgListener/onRichMediaUploadComplete', + SKEY_UPDATE = 'onSkeyUpdate', +} -export type ReceiveCmd = string - -interface NTQQApiReturnData extends Array { - 0: { +type NTReturnData = [ + { type: 'request' eventName: NTClass callbackId?: string - } - 1: { - cmdName: ReceiveCmd + }, + { + cmdName: ReceiveCmdS cmdType: 'event' payload: unknown }[] -} +] const logHook = false const receiveHooks: Array<{ - method: ReceiveCmd[] + method: ReceiveCmdS[] hookFunc: (payload: any) => void | Promise id: string }> = [] @@ -58,62 +56,45 @@ const callHooks: Array<{ }> = [] export function hookNTQQApiReceive(window: BrowserWindow, onlyLog: boolean) { - const originalSend = window.webContents.send - const patchSend = (channel: string, ...args: NTQQApiReturnData) => { - try { - const isLogger = args[0]?.eventName?.startsWith('ns-LoggerApi') - if (logHook && !isLogger) { - log(`received ntqq api message: ${channel}`, args) - } - } catch { } - if (!onlyLog) { - if (args?.[1] instanceof Array) { - for (const receiveData of args[1]) { - const ntQQApiMethodName = receiveData.cmdName - // log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData)) - for (const hook of receiveHooks) { - if (hook.method.includes(ntQQApiMethodName)) { - new Promise(resolve => { - try { - hook.hookFunc(receiveData.payload) - } catch (e) { - log('hook error', ntQQApiMethodName, (e as Error).stack?.toString()) - } - resolve(undefined) - }).then() + window.webContents.send = new Proxy(window.webContents.send, { + apply(target, thisArg, args: [channel: string, ...args: NTReturnData]) { + try { + if (logHook && !args[1]?.eventName?.startsWith('ns-LoggerApi')) { + log(`received ntqq api message: ${args[0]}`, args) + } + } catch { } + if (!onlyLog) { + if (args[2] instanceof Array) { + for (const receiveData of args[2]) { + const ntMethodName = receiveData.cmdName + for (const hook of receiveHooks) { + if (hook.method.includes(ntMethodName)) { + Promise.resolve(hook.hookFunc(receiveData.payload)) + } } } } - } - if (args[0]?.callbackId) { - // log("hookApiCallback", hookApiCallbacks, args) - const callbackId = args[0].callbackId - if (hookApiCallbacks[callbackId]) { - new Promise(resolve => { - hookApiCallbacks[callbackId](args[1]) - resolve(undefined) - }).then() - delete hookApiCallbacks[callbackId] + if (args[1]?.callbackId) { + const callbackId = args[1].callbackId + if (hookApiCallbacks[callbackId]) { + Promise.resolve(hookApiCallbacks[callbackId](args[2])) + delete hookApiCallbacks[callbackId] + } } } - } - originalSend.call(window.webContents, channel, ...args) - } - window.webContents.send = patchSend + const ret = target.apply(thisArg, args) + return ret + }, + }) } export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { - // 监听调用NTQQApi const webContents = window.webContents as Dict const ipc_message_proxy = webContents._events['-ipc-message']?.[0] || webContents._events['-ipc-message'] const proxyIpcMsg = new Proxy(ipc_message_proxy, { apply(target, thisArg, args) { - // console.log(thisArg, args); - let isLogger = false - try { - isLogger = args[3][0].eventName.startsWith('ns-LoggerApi') - } catch (e) { } + const isLogger = args[3]?.[0]?.eventName?.startsWith('ns-LoggerApi') if (!isLogger) { try { logHook && log('call NTQQ api', thisArg, args) @@ -125,17 +106,10 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { const callParams = _args.slice(1) callHooks.forEach((hook) => { if (hook.method.includes(cmdName)) { - new Promise(resolve => { - try { - hook.hookFunc(callParams) - } catch (e) { - log('hook call error', e, _args) - } - resolve(undefined) - }).then() + Promise.resolve(hook.hookFunc(callParams)) } }) - } catch (e) { } + } catch { } } } return target.apply(thisArg, args) @@ -147,7 +121,7 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { webContents._events['-ipc-message'] = proxyIpcMsg } - const ipc_invoke_proxy = webContents._events['-ipc-invoke']?.[0] || webContents._events['-ipc-invoke'] + /*const ipc_invoke_proxy = webContents._events['-ipc-invoke']?.[0] || webContents._events['-ipc-invoke'] const proxyIpcInvoke = new Proxy(ipc_invoke_proxy, { apply(target, thisArg, args) { //HOOK_LOG && log('call NTQQ invoke api', thisArg, args) @@ -157,9 +131,7 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { }, }) const ret = target.apply(thisArg, args) - /*try { - HOOK_LOG && log('call NTQQ invoke api return', ret) - } catch (e) { }*/ + //HOOK_LOG && log('call NTQQ invoke api return', ret) return ret }, }) @@ -167,11 +139,11 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { webContents._events['-ipc-invoke'][0] = proxyIpcInvoke } else { webContents._events['-ipc-invoke'] = proxyIpcInvoke - } + }*/ } export function registerReceiveHook( - method: ReceiveCmd | ReceiveCmd[], + method: ReceiveCmdS | ReceiveCmdS[], hookFunc: (payload: PayloadType) => void, ): string { const id = randomUUID() From 3de054600c0db6e0ce76dfc321d3fba1a5496e51 Mon Sep 17 00:00:00 2001 From: idranme Date: Mon, 9 Sep 2024 17:06:33 +0800 Subject: [PATCH 2/4] chore --- src/ntqqapi/hook.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index 8c1a6b0..06b715f 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -10,8 +10,8 @@ export enum ReceiveCmdS { RECENT_CONTACT = 'nodeIKernelRecentContactListener/onRecentContactListChangedVer2', UPDATE_MSG = 'nodeIKernelMsgListener/onMsgInfoListUpdate', UPDATE_ACTIVE_MSG = 'nodeIKernelMsgListener/onActiveMsgInfoUpdate', - NEW_MSG = `nodeIKernelMsgListener/onRecvMsg`, - NEW_ACTIVE_MSG = `nodeIKernelMsgListener/onRecvActiveMsg`, + NEW_MSG = 'nodeIKernelMsgListener/onRecvMsg', + NEW_ACTIVE_MSG = 'nodeIKernelMsgListener/onRecvActiveMsg', SELF_SEND_MSG = 'nodeIKernelMsgListener/onAddSendMsg', USER_INFO = 'nodeIKernelProfileListener/onProfileSimpleChanged', USER_DETAIL_INFO = 'nodeIKernelProfileListener/onProfileDetailInfoChanged', @@ -60,7 +60,7 @@ export function hookNTQQApiReceive(window: BrowserWindow, onlyLog: boolean) { apply(target, thisArg, args: [channel: string, ...args: NTReturnData]) { try { if (logHook && !args[1]?.eventName?.startsWith('ns-LoggerApi')) { - log(`received ntqq api message: ${args[0]}`, args) + log('received ntqq api message', args) } } catch { } if (!onlyLog) { @@ -102,7 +102,7 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { if (!onlyLog) { try { const _args: unknown[] = args[3][1] - const cmdName: NTMethod = _args[0] as NTMethod + const cmdName = _args[0] as NTMethod const callParams = _args.slice(1) callHooks.forEach((hook) => { if (hook.method.includes(cmdName)) { From 9738c3f63c0bfa9ab133f9f6f58007a5f674722d Mon Sep 17 00:00:00 2001 From: idranme Date: Tue, 10 Sep 2024 13:36:00 +0800 Subject: [PATCH 3/4] feat: GetProfileLike --- src/ntqqapi/api/user.ts | 15 +++++++++++++++ src/ntqqapi/core.ts | 6 ------ src/ntqqapi/hook.ts | 7 +++---- src/ntqqapi/ntcall.ts | 1 - .../services/NodeIKernelProfileLikeService.ts | 15 +++++++++++++-- src/onebot11/action/index.ts | 2 ++ src/onebot11/action/llonebot/GetProfileLike.ts | 17 +++++++++++++++++ src/onebot11/action/types.ts | 1 + 8 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 src/onebot11/action/llonebot/GetProfileLike.ts diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts index 3fa39cf..f6836af 100644 --- a/src/ntqqapi/api/user.ts +++ b/src/ntqqapi/api/user.ts @@ -296,4 +296,19 @@ export class NTQQUserApi extends Service { } }, null]) } + + async getProfileLike(uid: string) { + return await invoke('nodeIKernelProfileLikeService/getBuddyProfileLike', [{ + req: { + friendUids: [uid], + basic: 1, + vote: 1, + favorite: 0, + userProfile: 1, + type: 2, + start: 0, + limit: 20, + } + }, null]) + } } diff --git a/src/ntqqapi/core.ts b/src/ntqqapi/core.ts index 156c7be..402abba 100644 --- a/src/ntqqapi/core.ts +++ b/src/ntqqapi/core.ts @@ -185,12 +185,6 @@ class Core extends Service { }) registerReceiveHook<{ msgRecord: RawMessage }>(ReceiveCmdS.SELF_SEND_MSG, payload => { - const { msgId, chatType, peerUid } = payload.msgRecord - const peer = { - chatType, - peerUid - } - MessageUnique.createMsg(peer, msgId) if (!this.config.reportSelfMessage) { return } diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index 06b715f..eddfa16 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -82,8 +82,7 @@ export function hookNTQQApiReceive(window: BrowserWindow, onlyLog: boolean) { } } } - const ret = target.apply(thisArg, args) - return ret + return target.apply(thisArg, args) }, }) } @@ -143,7 +142,7 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) { } export function registerReceiveHook( - method: ReceiveCmdS | ReceiveCmdS[], + method: string | string[], hookFunc: (payload: PayloadType) => void, ): string { const id = randomUUID() @@ -151,7 +150,7 @@ export function registerReceiveHook( method = [method] } receiveHooks.push({ - method, + method: method as ReceiveCmdS[], hookFunc, id, }) diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts index 0148d89..de47f0d 100644 --- a/src/ntqqapi/ntcall.ts +++ b/src/ntqqapi/ntcall.ts @@ -136,7 +136,6 @@ export function invoke< // 这里的callback比较特殊,QQ后端先返回是否调用成功,再返回一条结果数据 const secondCallback = () => { const hookId = registerReceiveHook(options.cbCmd!, (payload) => { - // log(methodName, "second callback", cbCmd, payload, cmdCB); if (options.cmdCB) { if (options.cmdCB(payload, result)) { removeReceiveHook(hookId) diff --git a/src/ntqqapi/services/NodeIKernelProfileLikeService.ts b/src/ntqqapi/services/NodeIKernelProfileLikeService.ts index 52835f9..da29f2c 100644 --- a/src/ntqqapi/services/NodeIKernelProfileLikeService.ts +++ b/src/ntqqapi/services/NodeIKernelProfileLikeService.ts @@ -1,5 +1,6 @@ import { BuddyProfileLikeReq } from '../types' import { GeneralCallResult } from './common' +import { Dict } from 'cosmokit' export interface NodeIKernelProfileLikeService { addKernelProfileLikeListener(listener: NodeIKernelProfileLikeService): void @@ -10,8 +11,18 @@ export interface NodeIKernelProfileLikeService { getBuddyProfileLike(req: BuddyProfileLikeReq): Promise, - friendMaxVotes: number, + userLikeInfos: { + uid: string + time: string + favoriteInfo: { + total_count: number + last_time: number + today_count: number + userInfos: Dict[] + } + voteInfo: Dict + }[] + friendMaxVotes: number start: number } }> diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts index be36f77..756246b 100644 --- a/src/onebot11/action/index.ts +++ b/src/onebot11/action/index.ts @@ -62,6 +62,7 @@ import { GetGroupAtAllRemain } from './go-cqhttp/GetGroupAtAllRemain' import { GetGroupRootFiles } from './go-cqhttp/GetGroupRootFiles' import { SetOnlineStatus } from './llonebot/SetOnlineStatus' import { SendGroupNotice } from './go-cqhttp/SendGroupNotice' +import { GetProfileLike } from './llonebot/GetProfileLike' export function initActionMap(adapter: Adapter) { const actionHandlers = [ @@ -74,6 +75,7 @@ export function initActionMap(adapter: Adapter) { new GetFriendWithCategory(adapter), new GetEvent(adapter), new SetOnlineStatus(adapter), + new GetProfileLike(adapter), // onebot11 new SendLike(adapter), new GetMsg(adapter), diff --git a/src/onebot11/action/llonebot/GetProfileLike.ts b/src/onebot11/action/llonebot/GetProfileLike.ts new file mode 100644 index 0000000..af08e02 --- /dev/null +++ b/src/onebot11/action/llonebot/GetProfileLike.ts @@ -0,0 +1,17 @@ +import BaseAction from '../BaseAction' +import { ActionName } from '../types' +import { selfInfo } from '@/common/globalVars' +import { Dict } from 'cosmokit' + +export class GetProfileLike extends BaseAction { + actionName = ActionName.GetProfileLike + + async _handle() { + const ret = await this.ctx.ntUserApi.getProfileLike(selfInfo.uid) + const listdata = ret.info.userLikeInfos[0].favoriteInfo.userInfos + for (const item of listdata) { + item.uin = Number(await this.ctx.ntUserApi.getUinByUid(item.uid)) || 0 + } + return listdata + } +} \ No newline at end of file diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts index 382ee69..13c151b 100644 --- a/src/onebot11/action/types.ts +++ b/src/onebot11/action/types.ts @@ -20,6 +20,7 @@ export enum ActionName { GetFriendsWithCategory = 'get_friends_with_category', GetEvent = 'get_event', SetOnlineStatus = 'set_online_status', + GetProfileLike = 'get_profile_like', // onebot 11 SendLike = 'send_like', GetLoginInfo = 'get_login_info', From 319b275e4f5991c50d53961ff6c0b1af7c8c6f6f Mon Sep 17 00:00:00 2001 From: idranme Date: Tue, 10 Sep 2024 13:39:12 +0800 Subject: [PATCH 4/4] chore: v3.32.1 --- manifest.json | 2 +- src/version.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manifest.json b/manifest.json index e9c7d7a..10dc727 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "LLOneBot", "slug": "LLOneBot", "description": "实现 OneBot 11 协议,用于 QQ 机器人开发", - "version": "3.32.0", + "version": "3.32.1", "icon": "./icon.webp", "authors": [ { diff --git a/src/version.ts b/src/version.ts index daf7c9a..3aad3a2 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const version = '3.32.0' +export const version = '3.32.1'