Merge pull request #407 from LLOneBot/dev

3.32.1
This commit is contained in:
idranme 2024-09-10 13:44:03 +08:00 committed by GitHub
commit ce6886011f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 114 additions and 104 deletions

View File

@ -4,7 +4,7 @@
"name": "LLOneBot",
"slug": "LLOneBot",
"description": "实现 OneBot 11 协议,用于 QQ 机器人开发",
"version": "3.32.0",
"version": "3.32.1",
"icon": "./icon.webp",
"authors": [
{

View File

@ -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])
}
}

View File

@ -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<R = GeneralCallResult>(
ntQQWindow: NTQQWindow,
args: unknown[],
cbCmd: ReceiveCmd | undefined,
cbCmd: ReceiveCmdS | undefined,
autoCloseSeconds: number = 2,
) {
const result = await invoke<R>(

View File

@ -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
}

View File

@ -6,48 +6,46 @@ import { Dict } from 'cosmokit'
export const hookApiCallbacks: Record<string, (res: any) => 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<unknown> {
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<void>
id: string
}> = []
@ -58,62 +56,44 @@ 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)
}
} 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
return target.apply(thisArg, args)
},
})
}
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)
@ -121,21 +101,14 @@ 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)) {
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 +120,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 +130,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 +138,11 @@ export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) {
webContents._events['-ipc-invoke'][0] = proxyIpcInvoke
} else {
webContents._events['-ipc-invoke'] = proxyIpcInvoke
}
}*/
}
export function registerReceiveHook<PayloadType>(
method: ReceiveCmd | ReceiveCmd[],
method: string | string[],
hookFunc: (payload: PayloadType) => void,
): string {
const id = randomUUID()
@ -179,7 +150,7 @@ export function registerReceiveHook<PayloadType>(
method = [method]
}
receiveHooks.push({
method,
method: method as ReceiveCmdS[],
hookFunc,
id,
})

View File

@ -136,7 +136,6 @@ export function invoke<
// 这里的callback比较特殊QQ后端先返回是否调用成功再返回一条结果数据
const secondCallback = () => {
const hookId = registerReceiveHook<R>(options.cbCmd!, (payload) => {
// log(methodName, "second callback", cbCmd, payload, cmdCB);
if (options.cmdCB) {
if (options.cmdCB(payload, result)) {
removeReceiveHook(hookId)

View File

@ -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<GeneralCallResult & {
info: {
userLikeInfos: Array<unknown>,
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
}
}>

View File

@ -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),

View File

@ -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<void, Dict[]> {
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
}
}

View File

@ -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',

View File

@ -1 +1 @@
export const version = '3.32.0'
export const version = '3.32.1'