This commit is contained in:
idranme 2024-08-29 18:06:53 +08:00
parent c71885a29e
commit 6954551cb7
No known key found for this signature in database
GPG Key ID: 926F7B5B668E495F
12 changed files with 193 additions and 59 deletions

View File

@ -199,14 +199,16 @@ function onLoad() {
// 创建窗口时触发 // 创建窗口时触发
function onBrowserWindowCreated(window: BrowserWindow) { function onBrowserWindowCreated(window: BrowserWindow) {
if (window.id !== 2) { if (![2, 4].includes(window.id)) {
return return
} }
mainWindow = window if (window.id === 2) {
mainWindow = window
}
log('window create', window.webContents.getURL().toString()) log('window create', window.webContents.getURL().toString())
try { try {
hookNTQQApiCall(window) hookNTQQApiCall(window, window.id !== 2)
hookNTQQApiReceive(window) hookNTQQApiReceive(window, window.id !== 2)
} catch (e: any) { } catch (e: any) {
log('LLOneBot hook error: ', e.toString()) log('LLOneBot hook error: ', e.toString())
} }

View File

@ -382,4 +382,30 @@ export class NTQQGroupApi extends Service {
// GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数 // GetMsgByShoretID(ShoretID) -> MsgService.getMsgs(Peer,MsgId,1,false) -> 组出参数
return session?.getGroupService().addGroupEssence(param) return session?.getGroupService().addGroupEssence(param)
} }
async createGroupFileFolder(groupId: string, folderName: string) {
return await invoke({
methodName: 'nodeIKernelRichMediaService/createGroupFolder',
args: [
{
groupId,
folderName
},
null,
],
})
}
async deleteGroupFileFolder(groupId: string, folderId: string) {
return await invoke({
methodName: 'nodeIKernelRichMediaService/deleteGroupFolder',
args: [
{
groupId,
folderId
},
null,
],
})
}
} }

View File

@ -33,7 +33,6 @@ declare module 'cordis' {
'nt/group-notify': (input: GroupNotify[]) => void 'nt/group-notify': (input: GroupNotify[]) => void
'nt/friend-request': (input: FriendRequest[]) => void 'nt/friend-request': (input: FriendRequest[]) => void
'nt/group-member-info-updated': (input: { groupCode: string; members: GroupMember[] }) => void 'nt/group-member-info-updated': (input: { groupCode: string; members: GroupMember[] }) => void
'nt/friend-list-updated': (input: { groupCode: string; members: GroupMember[] }) => void
} }
} }

View File

@ -56,7 +56,7 @@ const callHooks: Array<{
hookFunc: (callParams: unknown[]) => void | Promise<void> hookFunc: (callParams: unknown[]) => void | Promise<void>
}> = [] }> = []
export function hookNTQQApiReceive(window: BrowserWindow) { export function hookNTQQApiReceive(window: BrowserWindow, onlyLog: boolean) {
const originalSend = window.webContents.send const originalSend = window.webContents.send
const patchSend = (channel: string, ...args: NTQQApiReturnData) => { const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
try { try {
@ -65,34 +65,36 @@ export function hookNTQQApiReceive(window: BrowserWindow) {
log(`received ntqq api message: ${channel}`, args) log(`received ntqq api message: ${channel}`, args)
} }
} catch { } } catch { }
if (args?.[1] instanceof Array) { if (!onlyLog) {
for (const receiveData of args?.[1]) { if (args?.[1] instanceof Array) {
const ntQQApiMethodName = receiveData.cmdName for (const receiveData of args?.[1]) {
// log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData)) const ntQQApiMethodName = receiveData.cmdName
for (const hook of receiveHooks) { // log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData))
if (hook.method.includes(ntQQApiMethodName)) { for (const hook of receiveHooks) {
new Promise((resolve, reject) => { if (hook.method.includes(ntQQApiMethodName)) {
try { new Promise((resolve, reject) => {
hook.hookFunc(receiveData.payload) try {
} catch (e: any) { hook.hookFunc(receiveData.payload)
log('hook error', ntQQApiMethodName, e.stack.toString()) } catch (e: any) {
} log('hook error', ntQQApiMethodName, e.stack.toString())
resolve(undefined) }
}).then() resolve(undefined)
}).then()
}
} }
} }
} }
} if (args[0]?.callbackId) {
if (args[0]?.callbackId) { // log("hookApiCallback", hookApiCallbacks, args)
// log("hookApiCallback", hookApiCallbacks, args) const callbackId = args[0].callbackId
const callbackId = args[0].callbackId if (hookApiCallbacks[callbackId]) {
if (hookApiCallbacks[callbackId]) { // log("callback found")
// log("callback found") new Promise((resolve, reject) => {
new Promise((resolve, reject) => { hookApiCallbacks[callbackId](args[1])
hookApiCallbacks[callbackId](args[1]) resolve(undefined)
resolve(undefined) }).then()
}).then() delete hookApiCallbacks[callbackId]
delete hookApiCallbacks[callbackId] }
} }
} }
originalSend.call(window.webContents, channel, ...args) originalSend.call(window.webContents, channel, ...args)
@ -100,7 +102,7 @@ export function hookNTQQApiReceive(window: BrowserWindow) {
window.webContents.send = patchSend window.webContents.send = patchSend
} }
export function hookNTQQApiCall(window: BrowserWindow) { export function hookNTQQApiCall(window: BrowserWindow, onlyLog: boolean) {
// 监听调用NTQQApi // 监听调用NTQQApi
let webContents = window.webContents as any let webContents = window.webContents as any
const ipc_message_proxy = webContents._events['-ipc-message']?.[0] || webContents._events['-ipc-message'] const ipc_message_proxy = webContents._events['-ipc-message']?.[0] || webContents._events['-ipc-message']
@ -116,23 +118,25 @@ export function hookNTQQApiCall(window: BrowserWindow) {
try { try {
logHook && log('call NTQQ api', thisArg, args) logHook && log('call NTQQ api', thisArg, args)
} catch (e) { } } catch (e) { }
try { if (!onlyLog) {
const _args: unknown[] = args[3][1] try {
const cmdName: NTMethod = _args[0] as NTMethod const _args: unknown[] = args[3][1]
const callParams = _args.slice(1) const cmdName: NTMethod = _args[0] as NTMethod
callHooks.forEach((hook) => { const callParams = _args.slice(1)
if (hook.method.includes(cmdName)) { callHooks.forEach((hook) => {
new Promise((resolve, reject) => { if (hook.method.includes(cmdName)) {
try { new Promise((resolve, reject) => {
hook.hookFunc(callParams) try {
} catch (e: any) { hook.hookFunc(callParams)
log('hook call error', e, _args) } catch (e: any) {
} log('hook call error', e, _args)
resolve(undefined) }
}).then() resolve(undefined)
} }).then()
}) }
} catch (e) { } })
} catch (e) { }
}
} }
return target.apply(thisArg, args) return target.apply(thisArg, args)
}, },

View File

@ -89,9 +89,10 @@ export enum NTMethod {
} }
export enum NTChannel { export enum NTChannel {
IPC_UP_1 = 'IPC_UP_1',
IPC_UP_2 = 'IPC_UP_2', IPC_UP_2 = 'IPC_UP_2',
IPC_UP_3 = 'IPC_UP_3', IPC_UP_3 = 'IPC_UP_3',
IPC_UP_1 = 'IPC_UP_1', IPC_UP_4 = 'IPC_UP_4'
} }
interface InvokeParams<ReturnType> { interface InvokeParams<ReturnType> {

View File

@ -17,17 +17,18 @@ export interface GroupNotifies {
} }
export enum GroupNotifyStatus { export enum GroupNotifyStatus {
IGNORE = 0, KINIT, // 初始化
WAIT_HANDLE = 1, KUNHANDLE, // 未处理
APPROVE = 2, KAGREED, // 同意
REJECT = 3, KREFUSED, // 拒绝
KIGNORED // 忽略
} }
export interface GroupNotify { export interface GroupNotify {
time: number // 自己添加的字段,时间戳,毫秒, 用于判断收到短时间内收到重复的notify time: number // 自己添加的字段,时间戳,毫秒, 用于判断收到短时间内收到重复的notify
seq: string // 唯一标识符转成数字再除以1000应该就是时间戳 seq: string // 唯一标识符转成数字再除以1000应该就是时间戳
type: GroupNotifyTypes type: GroupNotifyTypes
status: GroupNotifyStatus // 0是已忽略1是未处理2是已同意 status: GroupNotifyStatus
group: { groupCode: string; groupName: string } group: { groupCode: string; groupName: string }
user1: { uid: string; nickName: string } // 被设置管理员的人 user1: { uid: string; nickName: string } // 被设置管理员的人
user2: { uid: string; nickName: string } // 操作者 user2: { uid: string; nickName: string } // 操作者

View File

@ -0,0 +1,17 @@
import BaseAction from '../BaseAction'
import { ActionName } from '../types'
interface Payload {
group_id: number | string
name: string
parent_id?: '/'
}
export class GoCQHTTPCreateGroupFileFolder extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_CreateGroupFileFolder
async _handle(payload: Payload) {
await this.ctx.ntGroupApi.createGroupFileFolder(payload.group_id.toString(), payload.name)
return null
}
}

View File

@ -0,0 +1,16 @@
import BaseAction from '../BaseAction'
import { ActionName } from '../types'
interface Payload {
group_id: number | string
folder_id: string
}
export class GoCQHTTPDelGroupFolder extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_DelGroupFolder
async _handle(payload: Payload) {
await this.ctx.ntGroupApi.deleteGroupFileFolder(payload.group_id.toString(), payload.folder_id)
return null
}
}

View File

@ -0,0 +1,59 @@
import BaseAction from '../BaseAction'
import { GroupNotifyStatus } from '@/ntqqapi/types'
import { ActionName } from '../types'
interface Response {
invited_requests: {
request_id: number
invitor_uin: number
invitor_nick: string
group_id: number
group_name: string
checked: boolean
actor: number
}[]
join_requests: {
request_id: number
requester_uin: number
requester_nick: string
message: string
group_id: number
group_name: string
checked: boolean
actor: number
}[]
}
export class GoCQHTTPGetGroupSystemMsg extends BaseAction<void, Response> {
actionName = ActionName.GoCQHTTP_GetGroupSystemMsg
async _handle(payload: void) {
const singleScreenNotifies = await this.ctx.ntGroupApi.getSingleScreenNotifies(10)
const data: Response = { invited_requests: [], join_requests: [] }
for (const notify of singleScreenNotifies) {
if (notify.type == 1) {
data.invited_requests.push({
request_id: +notify.seq,
invitor_uin: Number(await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)),
invitor_nick: notify.user1.nickName,
group_id: +notify.group.groupCode,
group_name: notify.group.groupName,
checked: notify.status !== GroupNotifyStatus.KUNHANDLE,
actor: notify.user2?.uid ? Number(await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)) : 0
})
} else if (notify.type == 7) {
data.join_requests.push({
request_id: +notify.seq,
requester_uin: Number(await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)),
requester_nick: notify.user1.nickName,
message: notify.postscript,
group_id: +notify.group.groupCode,
group_name: notify.group.groupName,
checked: notify.status !== GroupNotifyStatus.KUNHANDLE,
actor: notify.user2?.uid ? Number(await this.ctx.ntUserApi.getUinByUid(notify.user2.uid)) : 0
})
}
}
return data
}
}

View File

@ -1,3 +1,4 @@
import type Adapter from '../adapter'
import GetMsg from './msg/GetMsg' import GetMsg from './msg/GetMsg'
import GetLoginInfo from './system/GetLoginInfo' import GetLoginInfo from './system/GetLoginInfo'
import { GetFriendList, GetFriendWithCategory } from './user/GetFriendList' import { GetFriendList, GetFriendWithCategory } from './user/GetFriendList'
@ -54,7 +55,9 @@ import GoCQHTTPSetEssenceMsg from './go-cqhttp/SetEssenceMsg'
import GoCQHTTPDelEssenceMsg from './go-cqhttp/DelEssenceMsg' import GoCQHTTPDelEssenceMsg from './go-cqhttp/DelEssenceMsg'
import GetEvent from './llonebot/GetEvent' import GetEvent from './llonebot/GetEvent'
import { GoCQHTTPDelGroupFile } from './go-cqhttp/DelGroupFile' import { GoCQHTTPDelGroupFile } from './go-cqhttp/DelGroupFile'
import type Adapter from '../adapter' import { GoCQHTTPGetGroupSystemMsg } from './go-cqhttp/GetGroupSystemMsg'
import { GoCQHTTPCreateGroupFileFolder } from './go-cqhttp/CreateGroupFileFolder'
import { GoCQHTTPDelGroupFolder } from './go-cqhttp/DelGroupFolder'
export function initActionMap(adapter: Adapter) { export function initActionMap(adapter: Adapter) {
const actionHandlers = [ const actionHandlers = [
@ -116,7 +119,10 @@ export function initActionMap(adapter: Adapter) {
new GoCQHTTHandleQuickOperation(adapter), new GoCQHTTHandleQuickOperation(adapter),
new GoCQHTTPSetEssenceMsg(adapter), new GoCQHTTPSetEssenceMsg(adapter),
new GoCQHTTPDelEssenceMsg(adapter), new GoCQHTTPDelEssenceMsg(adapter),
new GoCQHTTPDelGroupFile(adapter) new GoCQHTTPDelGroupFile(adapter),
new GoCQHTTPGetGroupSystemMsg(adapter),
new GoCQHTTPCreateGroupFileFolder(adapter),
new GoCQHTTPDelGroupFolder(adapter)
] ]
const actionMap = new Map<string, BaseAction<any, any>>() const actionMap = new Map<string, BaseAction<any, any>>()
for (const action of actionHandlers) { for (const action of actionHandlers) {

View File

@ -1,5 +1,5 @@
import { GroupNotify, GroupNotifyStatus } from '@/ntqqapi/types'
import BaseAction from '../BaseAction' import BaseAction from '../BaseAction'
import { GroupNotify, GroupNotifyStatus } from '@/ntqqapi/types'
import { ActionName } from '../types' import { ActionName } from '../types'
interface OB11GroupRequestNotify { interface OB11GroupRequestNotify {
@ -13,7 +13,7 @@ export default class GetGroupAddRequest extends BaseAction<null, OB11GroupReques
protected async _handle(payload: null): Promise<OB11GroupRequestNotify[]> { protected async _handle(payload: null): Promise<OB11GroupRequestNotify[]> {
const data = await this.ctx.ntGroupApi.getGroupIgnoreNotifies() const data = await this.ctx.ntGroupApi.getGroupIgnoreNotifies()
const notifies: GroupNotify[] = data.notifies.filter((notify) => notify.status === GroupNotifyStatus.WAIT_HANDLE) const notifies: GroupNotify[] = data.notifies.filter((notify) => notify.status === GroupNotifyStatus.KUNHANDLE)
const returnData: OB11GroupRequestNotify[] = [] const returnData: OB11GroupRequestNotify[] = []
for (const notify of notifies) { for (const notify of notifies) {
const uin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid) const uin = await this.ctx.ntUserApi.getUinByUid(notify.user1.uid)

View File

@ -74,4 +74,7 @@ export enum ActionName {
GoCQHTTP_SetEssenceMsg = 'set_essence_msg', GoCQHTTP_SetEssenceMsg = 'set_essence_msg',
GoCQHTTP_DelEssenceMsg = 'delete_essence_msg', GoCQHTTP_DelEssenceMsg = 'delete_essence_msg',
GoCQHTTP_DelGroupFile = 'delete_group_file', GoCQHTTP_DelGroupFile = 'delete_group_file',
GoCQHTTP_GetGroupSystemMsg = 'get_group_system_msg',
GoCQHTTP_CreateGroupFileFolder = 'create_group_file_folder',
GoCQHTTP_DelGroupFolder = 'delete_group_folder'
} }