mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: clean cache api
This commit is contained in:
commit
354ee389bc
@ -1,72 +1,73 @@
|
|||||||
import {type BrowserWindow} from 'electron'
|
import {BrowserWindow} from 'electron';
|
||||||
import {getConfigUtil, log, sleep} from '../common/utils'
|
import {getConfigUtil, log, sleep} from "../common/utils";
|
||||||
import {NTQQApi, type NTQQApiClass, sendMessagePool} from './ntcall'
|
import {NTQQApi, NTQQApiClass, sendMessagePool} from "./ntcall";
|
||||||
import {type Group, type RawMessage, type User} from './types'
|
import {Group, RawMessage, User} from "./types";
|
||||||
import {friends, groups, selfInfo, tempGroupCodeMap} from '../common/data'
|
import {friends, groups, selfInfo, tempGroupCodeMap} from "../common/data";
|
||||||
import {OB11GroupDecreaseEvent} from '../onebot11/event/notice/OB11GroupDecreaseEvent'
|
import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent";
|
||||||
import {OB11GroupIncreaseEvent} from '../onebot11/event/notice/OB11GroupIncreaseEvent'
|
import {OB11GroupIncreaseEvent} from "../onebot11/event/notice/OB11GroupIncreaseEvent";
|
||||||
import {v4 as uuidv4} from 'uuid'
|
import {v4 as uuidv4} from "uuid"
|
||||||
import {postOB11Event} from '../onebot11/server/postOB11Event'
|
import {postOB11Event} from "../onebot11/server/postOB11Event";
|
||||||
import {HOOK_LOG} from '../common/config'
|
import {HOOK_LOG} from "../common/config";
|
||||||
import fs from 'fs'
|
import fs from "fs";
|
||||||
import {dbUtil} from "../common/db";
|
import {dbUtil} from "../common/db";
|
||||||
|
|
||||||
export const hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
|
export let hookApiCallbacks: Record<string, (apiReturn: any) => void> = {}
|
||||||
|
|
||||||
export enum ReceiveCmd {
|
export enum ReceiveCmd {
|
||||||
UPDATE_MSG = 'nodeIKernelMsgListener/onMsgInfoListUpdate',
|
UPDATE_MSG = "nodeIKernelMsgListener/onMsgInfoListUpdate",
|
||||||
NEW_MSG = 'nodeIKernelMsgListener/onRecvMsg',
|
NEW_MSG = "nodeIKernelMsgListener/onRecvMsg",
|
||||||
SELF_SEND_MSG = 'nodeIKernelMsgListener/onAddSendMsg',
|
SELF_SEND_MSG = "nodeIKernelMsgListener/onAddSendMsg",
|
||||||
USER_INFO = 'nodeIKernelProfileListener/onProfileSimpleChanged',
|
USER_INFO = "nodeIKernelProfileListener/onProfileSimpleChanged",
|
||||||
USER_DETAIL_INFO = 'nodeIKernelProfileListener/onProfileDetailInfoChanged',
|
USER_DETAIL_INFO = "nodeIKernelProfileListener/onProfileDetailInfoChanged",
|
||||||
GROUPS = 'nodeIKernelGroupListener/onGroupListUpdate',
|
GROUPS = "nodeIKernelGroupListener/onGroupListUpdate",
|
||||||
GROUPS_UNIX = 'onGroupListUpdate',
|
GROUPS_UNIX = "onGroupListUpdate",
|
||||||
FRIENDS = 'onBuddyListChange',
|
FRIENDS = "onBuddyListChange",
|
||||||
MEDIA_DOWNLOAD_COMPLETE = 'nodeIKernelMsgListener/onRichMediaDownloadComplete',
|
MEDIA_DOWNLOAD_COMPLETE = "nodeIKernelMsgListener/onRichMediaDownloadComplete",
|
||||||
UNREAD_GROUP_NOTIFY = 'nodeIKernelGroupListener/onGroupNotifiesUnreadCountUpdated',
|
UNREAD_GROUP_NOTIFY = "nodeIKernelGroupListener/onGroupNotifiesUnreadCountUpdated",
|
||||||
GROUP_NOTIFY = 'nodeIKernelGroupListener/onGroupSingleScreenNotifies',
|
GROUP_NOTIFY = "nodeIKernelGroupListener/onGroupSingleScreenNotifies",
|
||||||
FRIEND_REQUEST = 'nodeIKernelBuddyListener/onBuddyReqChange',
|
FRIEND_REQUEST = "nodeIKernelBuddyListener/onBuddyReqChange",
|
||||||
SELF_STATUS = 'nodeIKernelProfileListener/onSelfStatusChanged',
|
SELF_STATUS = 'nodeIKernelProfileListener/onSelfStatusChanged',
|
||||||
|
CACHE_SCAN_FINISH = "nodeIKernelStorageCleanListener/onFinishScan",
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NTQQApiReturnData<PayloadType = unknown> extends Array<any> {
|
interface NTQQApiReturnData<PayloadType = unknown> extends Array<any> {
|
||||||
0: {
|
0: {
|
||||||
'type': 'request'
|
"type": "request",
|
||||||
'eventName': NTQQApiClass
|
"eventName": NTQQApiClass,
|
||||||
'callbackId'?: string
|
"callbackId"?: string
|
||||||
}
|
},
|
||||||
1:
|
1:
|
||||||
Array<{
|
{
|
||||||
cmdName: ReceiveCmd
|
cmdName: ReceiveCmd,
|
||||||
cmdType: 'event'
|
cmdType: "event",
|
||||||
payload: PayloadType
|
payload: PayloadType
|
||||||
}>
|
}[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const receiveHooks: Array<{
|
let receiveHooks: Array<{
|
||||||
method: ReceiveCmd
|
method: ReceiveCmd,
|
||||||
hookFunc: ((payload: any) => void | Promise<void>)
|
hookFunc: ((payload: any) => void | Promise<void>)
|
||||||
id: string
|
id: string
|
||||||
}> = []
|
}> = []
|
||||||
|
|
||||||
export function hookNTQQApiReceive(window: BrowserWindow) {
|
export function hookNTQQApiReceive(window: BrowserWindow) {
|
||||||
const originalSend = window.webContents.send
|
const originalSend = window.webContents.send;
|
||||||
const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
|
const patchSend = (channel: string, ...args: NTQQApiReturnData) => {
|
||||||
HOOK_LOG && log(`received ntqq api message: ${channel}`, JSON.stringify(args))
|
HOOK_LOG && log(`received ntqq api message: ${channel}`, JSON.stringify(args))
|
||||||
if (args?.[1] instanceof Array) {
|
if (args?.[1] instanceof Array) {
|
||||||
for (const receiveData of args?.[1]) {
|
for (let receiveData of args?.[1]) {
|
||||||
const ntQQApiMethodName = receiveData.cmdName
|
const ntQQApiMethodName = receiveData.cmdName;
|
||||||
// log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData))
|
// log(`received ntqq api message: ${channel} ${ntQQApiMethodName}`, JSON.stringify(receiveData))
|
||||||
for (const hook of receiveHooks) {
|
for (let hook of receiveHooks) {
|
||||||
if (hook.method === ntQQApiMethodName) {
|
if (hook.method === ntQQApiMethodName) {
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
const _ = hook.hookFunc(receiveData.payload)
|
let _ = hook.hookFunc(receiveData.payload)
|
||||||
if (hook.hookFunc.constructor.name === 'AsyncFunction') {
|
if (hook.hookFunc.constructor.name === "AsyncFunction") {
|
||||||
(_ as Promise<void>).then()
|
(_ as Promise<void>).then()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('hook error', e, receiveData.payload)
|
log("hook error", e, receiveData.payload)
|
||||||
}
|
}
|
||||||
}).then()
|
}).then()
|
||||||
}
|
}
|
||||||
@ -75,35 +76,35 @@ export function hookNTQQApiReceive(window: BrowserWindow) {
|
|||||||
}
|
}
|
||||||
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]);
|
||||||
}).then()
|
}).then()
|
||||||
delete hookApiCallbacks[callbackId]
|
delete hookApiCallbacks[callbackId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return originalSend.call(window.webContents, channel, ...args)
|
return originalSend.call(window.webContents, channel, ...args);
|
||||||
}
|
}
|
||||||
window.webContents.send = patchSend
|
window.webContents.send = patchSend;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hookNTQQApiCall(window: BrowserWindow) {
|
export function hookNTQQApiCall(window: BrowserWindow) {
|
||||||
// 监听调用NTQQApi
|
// 监听调用NTQQApi
|
||||||
const 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"];
|
||||||
|
|
||||||
const proxyIpcMsg = new Proxy(ipc_message_proxy, {
|
const proxyIpcMsg = new Proxy(ipc_message_proxy, {
|
||||||
apply(target, thisArg, args) {
|
apply(target, thisArg, args) {
|
||||||
HOOK_LOG && log('call NTQQ api', thisArg, args)
|
HOOK_LOG && log("call NTQQ api", thisArg, args);
|
||||||
return target.apply(thisArg, args)
|
return target.apply(thisArg, args);
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
if (webContents._events['-ipc-message']?.[0]) {
|
if (webContents._events["-ipc-message"]?.[0]) {
|
||||||
webContents._events['-ipc-message'][0] = proxyIpcMsg
|
webContents._events["-ipc-message"][0] = proxyIpcMsg;
|
||||||
} else {
|
} else {
|
||||||
webContents._events['-ipc-message'] = proxyIpcMsg
|
webContents._events["-ipc-message"] = proxyIpcMsg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,29 +115,29 @@ export function registerReceiveHook<PayloadType>(method: ReceiveCmd, hookFunc: (
|
|||||||
hookFunc,
|
hookFunc,
|
||||||
id
|
id
|
||||||
})
|
})
|
||||||
return id
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function removeReceiveHook(id: string) {
|
export function removeReceiveHook(id: string) {
|
||||||
const index = receiveHooks.findIndex(h => h.id === id)
|
const index = receiveHooks.findIndex(h => h.id === id)
|
||||||
receiveHooks.splice(index, 1)
|
receiveHooks.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
|
async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
|
||||||
for (const group of _groups) {
|
for (let group of _groups) {
|
||||||
let existGroup = groups.find(g => g.groupCode == group.groupCode)
|
let existGroup = groups.find(g => g.groupCode == group.groupCode);
|
||||||
if (existGroup) {
|
if (existGroup) {
|
||||||
Object.assign(existGroup, group)
|
Object.assign(existGroup, group);
|
||||||
} else {
|
} else {
|
||||||
groups.push(group)
|
groups.push(group);
|
||||||
existGroup = group
|
existGroup = group;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needUpdate) {
|
if (needUpdate) {
|
||||||
const members = await NTQQApi.getGroupMembers(group.groupCode)
|
const members = await NTQQApi.getGroupMembers(group.groupCode);
|
||||||
|
|
||||||
if (members) {
|
if (members) {
|
||||||
existGroup.members = members
|
existGroup.members = members;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,83 +145,84 @@ async function updateGroups(_groups: Group[], needUpdate: boolean = true) {
|
|||||||
|
|
||||||
async function processGroupEvent(payload) {
|
async function processGroupEvent(payload) {
|
||||||
try {
|
try {
|
||||||
const newGroupList = payload.groupList
|
const newGroupList = payload.groupList;
|
||||||
for (const group of newGroupList) {
|
for (const group of newGroupList) {
|
||||||
const existGroup = groups.find(g => g.groupCode == group.groupCode)
|
let existGroup = groups.find(g => g.groupCode == group.groupCode);
|
||||||
if (existGroup) {
|
if (existGroup) {
|
||||||
if (existGroup.memberCount > group.memberCount) {
|
if (existGroup.memberCount > group.memberCount) {
|
||||||
const oldMembers = existGroup.members
|
const oldMembers = existGroup.members;
|
||||||
|
|
||||||
await sleep(200) // 如果请求QQ API的速度过快,通常无法正确拉取到最新的群信息,因此这里人为引入一个延时
|
await sleep(200); // 如果请求QQ API的速度过快,通常无法正确拉取到最新的群信息,因此这里人为引入一个延时
|
||||||
const newMembers = await NTQQApi.getGroupMembers(group.groupCode)
|
const newMembers = await NTQQApi.getGroupMembers(group.groupCode);
|
||||||
|
|
||||||
group.members = newMembers
|
group.members = newMembers;
|
||||||
const newMembersSet = new Set<string>() // 建立索引降低时间复杂度
|
const newMembersSet = new Set<string>(); // 建立索引降低时间复杂度
|
||||||
|
|
||||||
for (const member of newMembers) {
|
for (const member of newMembers) {
|
||||||
newMembersSet.add(member.uin)
|
newMembersSet.add(member.uin);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const member of oldMembers) {
|
for (const member of oldMembers) {
|
||||||
if (!newMembersSet.has(member.uin)) {
|
if (!newMembersSet.has(member.uin)) {
|
||||||
postOB11Event(new OB11GroupDecreaseEvent(group.groupCode, parseInt(member.uin)))
|
postOB11Event(new OB11GroupDecreaseEvent(group.groupCode, parseInt(member.uin)));
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (existGroup.memberCount < group.memberCount) {
|
} else if (existGroup.memberCount < group.memberCount) {
|
||||||
const oldMembers = existGroup.members
|
const oldMembers = existGroup.members;
|
||||||
const oldMembersSet = new Set<string>()
|
const oldMembersSet = new Set<string>();
|
||||||
for (const member of oldMembers) {
|
for (const member of oldMembers) {
|
||||||
oldMembersSet.add(member.uin)
|
oldMembersSet.add(member.uin);
|
||||||
}
|
}
|
||||||
|
|
||||||
await sleep(200)
|
await sleep(200);
|
||||||
const newMembers = await NTQQApi.getGroupMembers(group.groupCode)
|
const newMembers = await NTQQApi.getGroupMembers(group.groupCode);
|
||||||
|
|
||||||
group.members = newMembers
|
group.members = newMembers;
|
||||||
for (const member of newMembers) {
|
for (const member of newMembers) {
|
||||||
if (!oldMembersSet.has(member.uin)) {
|
if (!oldMembersSet.has(member.uin)) {
|
||||||
postOB11Event(new OB11GroupIncreaseEvent(group.groupCode, parseInt(member.uin)))
|
postOB11Event(new OB11GroupIncreaseEvent(group.groupCode, parseInt(member.uin)));
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGroups(newGroupList, false).then()
|
updateGroups(newGroupList, false).then();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
updateGroups(payload.groupList).then()
|
updateGroups(payload.groupList).then();
|
||||||
console.log(e)
|
console.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerReceiveHook<{ groupList: Group[], updateType: number }>(ReceiveCmd.GROUPS, (payload) => {
|
registerReceiveHook<{ groupList: Group[], updateType: number }>(ReceiveCmd.GROUPS, (payload) => {
|
||||||
if (payload.updateType != 2) {
|
if (payload.updateType != 2) {
|
||||||
updateGroups(payload.groupList).then()
|
updateGroups(payload.groupList).then();
|
||||||
} else {
|
} else {
|
||||||
if (process.platform == 'win32') {
|
if (process.platform == "win32") {
|
||||||
processGroupEvent(payload).then()
|
processGroupEvent(payload).then();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
registerReceiveHook<{ groupList: Group[], updateType: number }>(ReceiveCmd.GROUPS_UNIX, (payload) => {
|
registerReceiveHook<{ groupList: Group[], updateType: number }>(ReceiveCmd.GROUPS_UNIX, (payload) => {
|
||||||
if (payload.updateType != 2) {
|
if (payload.updateType != 2) {
|
||||||
updateGroups(payload.groupList).then()
|
updateGroups(payload.groupList).then();
|
||||||
} else {
|
} else {
|
||||||
if (process.platform != 'win32') {
|
if (process.platform != "win32") {
|
||||||
processGroupEvent(payload).then()
|
processGroupEvent(payload).then();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
registerReceiveHook<{
|
registerReceiveHook<{
|
||||||
data: Array<{ categoryId: number, categroyName: string, categroyMbCount: number, buddyList: User[] }>
|
data: { categoryId: number, categroyName: string, categroyMbCount: number, buddyList: User[] }[]
|
||||||
}>(ReceiveCmd.FRIENDS, payload => {
|
}>(ReceiveCmd.FRIENDS, payload => {
|
||||||
for (const fData of payload.data) {
|
for (const fData of payload.data) {
|
||||||
const _friends = fData.buddyList
|
const _friends = fData.buddyList;
|
||||||
for (const friend of _friends) {
|
for (let friend of _friends) {
|
||||||
const existFriend = friends.find(f => f.uin == friend.uin)
|
let existFriend = friends.find(f => f.uin == friend.uin)
|
||||||
if (!existFriend) {
|
if (!existFriend) {
|
||||||
friends.push(friend)
|
friends.push(friend)
|
||||||
} else {
|
} else {
|
||||||
@ -230,8 +232,8 @@ registerReceiveHook<{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
registerReceiveHook<{ msgList: RawMessage[] }>(ReceiveCmd.NEW_MSG, (payload) => {
|
registerReceiveHook<{ msgList: Array<RawMessage> }>(ReceiveCmd.NEW_MSG, (payload) => {
|
||||||
const {autoDeleteFile, autoDeleteFileSecond} = getConfigUtil().getConfig()
|
const {autoDeleteFile} = getConfigUtil().getConfig();
|
||||||
for (const message of payload.msgList) {
|
for (const message of payload.msgList) {
|
||||||
// log("收到新消息,push到历史记录", message.msgSeq)
|
// log("收到新消息,push到历史记录", message.msgSeq)
|
||||||
dbUtil.addMsg(message).then()
|
dbUtil.addMsg(message).then()
|
||||||
@ -255,27 +257,27 @@ registerReceiveHook<{ msgList: RawMessage[] }>(ReceiveCmd.NEW_MSG, (payload) =>
|
|||||||
for (const path of pathList) {
|
for (const path of pathList) {
|
||||||
if (path) {
|
if (path) {
|
||||||
fs.unlink(picPath, () => {
|
fs.unlink(picPath, () => {
|
||||||
log('删除文件成功', path)
|
log("删除文件成功", path)
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, autoDeleteFileSecond * 1000)
|
}, 60 * 1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
registerReceiveHook<{ msgRecord: RawMessage }>(ReceiveCmd.SELF_SEND_MSG, ({msgRecord}) => {
|
registerReceiveHook<{ msgRecord: RawMessage }>(ReceiveCmd.SELF_SEND_MSG, ({msgRecord}) => {
|
||||||
const message = msgRecord
|
const message = msgRecord;
|
||||||
const peerUid = message.peerUid
|
const peerUid = message.peerUid;
|
||||||
// log("收到自己发送成功的消息", Object.keys(sendMessagePool), message);
|
// log("收到自己发送成功的消息", Object.keys(sendMessagePool), message);
|
||||||
// log("收到自己发送成功的消息", message);
|
// log("收到自己发送成功的消息", message);
|
||||||
dbUtil.addMsg(message).then()
|
dbUtil.addMsg(message).then()
|
||||||
const sendCallback = sendMessagePool[peerUid]
|
const sendCallback = sendMessagePool[peerUid]
|
||||||
if (sendCallback) {
|
if (sendCallback) {
|
||||||
try {
|
try {
|
||||||
sendCallback(message)
|
sendCallback(message);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('receive self msg error', e.stack)
|
log("receive self msg error", e.stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1,25 +1,29 @@
|
|||||||
import {ipcMain} from 'electron'
|
import {ipcMain} from "electron";
|
||||||
import {hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook} from './hook'
|
import {hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook} from "./hook";
|
||||||
import {log, sleep} from '../common/utils'
|
import {log, sleep} from "../common/utils";
|
||||||
import {
|
import {
|
||||||
type ChatType,
|
ChatType,
|
||||||
ElementType,
|
ElementType,
|
||||||
type Friend,
|
Friend,
|
||||||
type FriendRequest,
|
FriendRequest,
|
||||||
type Group, GroupMember,
|
Group,
|
||||||
type GroupMemberRole,
|
GroupMember,
|
||||||
type GroupNotifies,
|
GroupMemberRole,
|
||||||
type GroupNotify,
|
GroupNotifies,
|
||||||
type GroupRequestOperateTypes,
|
GroupNotify,
|
||||||
type RawMessage,
|
GroupRequestOperateTypes,
|
||||||
type SelfInfo,
|
RawMessage,
|
||||||
type SendMessageElement,
|
SelfInfo,
|
||||||
type User
|
SendMessageElement,
|
||||||
} from './types'
|
User,
|
||||||
import * as fs from 'node:fs'
|
CacheScanResult,
|
||||||
import {friendRequests, groupNotifies, selfInfo, uidMaps} from '../common/data'
|
ChatCacheList, ChatCacheListItemBasic,
|
||||||
import {v4 as uuidv4} from 'uuid'
|
CacheFileList, CacheFileListItem, CacheFileType,
|
||||||
import path from 'path'
|
} from "./types";
|
||||||
|
import * as fs from "fs";
|
||||||
|
import {friendRequests, groupNotifies, selfInfo, uidMaps} from "../common/data";
|
||||||
|
import {v4 as uuidv4} from "uuid"
|
||||||
|
import path from "path";
|
||||||
import {dbUtil} from "../common/db";
|
import {dbUtil} from "../common/db";
|
||||||
|
|
||||||
interface IPCReceiveEvent {
|
interface IPCReceiveEvent {
|
||||||
@ -35,89 +39,104 @@ export type IPCReceiveDetail = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export enum NTQQApiClass {
|
export enum NTQQApiClass {
|
||||||
NT_API = 'ns-ntApi',
|
NT_API = "ns-ntApi",
|
||||||
FS_API = 'ns-FsApi',
|
FS_API = "ns-FsApi",
|
||||||
GLOBAL_DATA = 'ns-GlobalDataApi'
|
OS_API = "ns-OsApi",
|
||||||
|
HOTUPDATE_API = "ns-HotUpdateApi",
|
||||||
|
BUSINESS_API = "ns-BusinessApi",
|
||||||
|
GLOBAL_DATA = "ns-GlobalDataApi"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum NTQQApiMethod {
|
export enum NTQQApiMethod {
|
||||||
LIKE_FRIEND = 'nodeIKernelProfileLikeService/setBuddyProfileLike',
|
LIKE_FRIEND = "nodeIKernelProfileLikeService/setBuddyProfileLike",
|
||||||
SELF_INFO = 'fetchAuthData',
|
SELF_INFO = "fetchAuthData",
|
||||||
FRIENDS = 'nodeIKernelBuddyService/getBuddyList',
|
FRIENDS = "nodeIKernelBuddyService/getBuddyList",
|
||||||
GROUPS = 'nodeIKernelGroupService/getGroupList',
|
GROUPS = "nodeIKernelGroupService/getGroupList",
|
||||||
GROUP_MEMBER_SCENE = 'nodeIKernelGroupService/createMemberListScene',
|
GROUP_MEMBER_SCENE = "nodeIKernelGroupService/createMemberListScene",
|
||||||
GROUP_MEMBERS = 'nodeIKernelGroupService/getNextMemberList',
|
GROUP_MEMBERS = "nodeIKernelGroupService/getNextMemberList",
|
||||||
USER_INFO = 'nodeIKernelProfileService/getUserSimpleInfo',
|
USER_INFO = "nodeIKernelProfileService/getUserSimpleInfo",
|
||||||
USER_DETAIL_INFO = 'nodeIKernelProfileService/getUserDetailInfo',
|
USER_DETAIL_INFO = "nodeIKernelProfileService/getUserDetailInfo",
|
||||||
FILE_TYPE = 'getFileType',
|
FILE_TYPE = "getFileType",
|
||||||
FILE_MD5 = 'getFileMd5',
|
FILE_MD5 = "getFileMd5",
|
||||||
FILE_COPY = 'copyFile',
|
FILE_COPY = "copyFile",
|
||||||
IMAGE_SIZE = 'getImageSizeFromPath',
|
IMAGE_SIZE = "getImageSizeFromPath",
|
||||||
FILE_SIZE = 'getFileSize',
|
FILE_SIZE = "getFileSize",
|
||||||
MEDIA_FILE_PATH = 'nodeIKernelMsgService/getRichMediaFilePathForGuild',
|
MEDIA_FILE_PATH = "nodeIKernelMsgService/getRichMediaFilePathForGuild",
|
||||||
RECALL_MSG = 'nodeIKernelMsgService/recallMsg',
|
RECALL_MSG = "nodeIKernelMsgService/recallMsg",
|
||||||
SEND_MSG = 'nodeIKernelMsgService/sendMsg',
|
SEND_MSG = "nodeIKernelMsgService/sendMsg",
|
||||||
DOWNLOAD_MEDIA = 'nodeIKernelMsgService/downloadRichMedia',
|
DOWNLOAD_MEDIA = "nodeIKernelMsgService/downloadRichMedia",
|
||||||
FORWARD_MSG = "nodeIKernelMsgService/forwardMsgWithComment", // 逐条转发
|
FORWARD_MSG = "nodeIKernelMsgService/forwardMsgWithComment",
|
||||||
MULTI_FORWARD_MSG = 'nodeIKernelMsgService/multiForwardMsgWithComment', // 合并转发
|
MULTI_FORWARD_MSG = "nodeIKernelMsgService/multiForwardMsgWithComment", // 合并转发
|
||||||
GET_GROUP_NOTICE = 'nodeIKernelGroupService/getSingleScreenNotifies',
|
GET_GROUP_NOTICE = "nodeIKernelGroupService/getSingleScreenNotifies",
|
||||||
HANDLE_GROUP_REQUEST = 'nodeIKernelGroupService/operateSysNotify',
|
HANDLE_GROUP_REQUEST = "nodeIKernelGroupService/operateSysNotify",
|
||||||
QUIT_GROUP = 'nodeIKernelGroupService/quitGroup',
|
QUIT_GROUP = "nodeIKernelGroupService/quitGroup",
|
||||||
// READ_FRIEND_REQUEST = "nodeIKernelBuddyListener/onDoubtBuddyReqUnreadNumChange"
|
// READ_FRIEND_REQUEST = "nodeIKernelBuddyListener/onDoubtBuddyReqUnreadNumChange"
|
||||||
HANDLE_FRIEND_REQUEST = 'nodeIKernelBuddyService/approvalFriendRequest',
|
HANDLE_FRIEND_REQUEST = "nodeIKernelBuddyService/approvalFriendRequest",
|
||||||
KICK_MEMBER = 'nodeIKernelGroupService/kickMember',
|
KICK_MEMBER = "nodeIKernelGroupService/kickMember",
|
||||||
MUTE_MEMBER = 'nodeIKernelGroupService/setMemberShutUp',
|
MUTE_MEMBER = "nodeIKernelGroupService/setMemberShutUp",
|
||||||
MUTE_GROUP = 'nodeIKernelGroupService/setGroupShutUp',
|
MUTE_GROUP = "nodeIKernelGroupService/setGroupShutUp",
|
||||||
SET_MEMBER_CARD = 'nodeIKernelGroupService/modifyMemberCardName',
|
SET_MEMBER_CARD = "nodeIKernelGroupService/modifyMemberCardName",
|
||||||
SET_MEMBER_ROLE = 'nodeIKernelGroupService/modifyMemberRole',
|
SET_MEMBER_ROLE = "nodeIKernelGroupService/modifyMemberRole",
|
||||||
PUBLISH_GROUP_BULLETIN = 'nodeIKernelGroupService/publishGroupBulletinBulletin',
|
PUBLISH_GROUP_BULLETIN = "nodeIKernelGroupService/publishGroupBulletinBulletin",
|
||||||
SET_GROUP_NAME = 'nodeIKernelGroupService/modifyGroupName',
|
SET_GROUP_NAME = "nodeIKernelGroupService/modifyGroupName",
|
||||||
|
|
||||||
|
CACHE_SET_SILENCE = 'nodeIKernelStorageCleanService/setSilentScan',
|
||||||
|
CACHE_ADD_SCANNED_PATH = 'nodeIKernelStorageCleanService/addCacheScanedPaths',
|
||||||
|
CACHE_PATH_HOT_UPDATE = 'getHotUpdateCachePath',
|
||||||
|
CACHE_PATH_DESKTOP_TEMP = 'getDesktopTmpPath',
|
||||||
|
CACHE_PATH_SESSION = 'getCleanableAppSessionPathList',
|
||||||
|
CACHE_SCAN = 'nodeIKernelStorageCleanService/scanCache',
|
||||||
|
CACHE_CLEAR = 'nodeIKernelStorageCleanService/clearCacheDataByKeys',
|
||||||
|
|
||||||
|
CACHE_CHAT_GET = 'nodeIKernelStorageCleanService/getChatCacheInfo',
|
||||||
|
CACHE_FILE_GET = 'nodeIKernelStorageCleanService/getFileCacheInfo',
|
||||||
|
CACHE_CHAT_CLEAR = 'nodeIKernelStorageCleanService/clearChatCacheInfo',
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NTQQApiChannel {
|
enum NTQQApiChannel {
|
||||||
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_1 = "IPC_UP_1",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Peer {
|
export interface Peer {
|
||||||
chatType: ChatType
|
chatType: ChatType
|
||||||
peerUid: string // 如果是群聊uid为群号,私聊uid就是加密的字符串
|
peerUid: string // 如果是群聊uid为群号,私聊uid就是加密的字符串
|
||||||
guildId?: ''
|
guildId?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NTQQApiParams {
|
interface NTQQApiParams {
|
||||||
methodName: NTQQApiMethod | string
|
methodName: NTQQApiMethod | string,
|
||||||
className?: NTQQApiClass
|
className?: NTQQApiClass,
|
||||||
channel?: NTQQApiChannel
|
channel?: NTQQApiChannel,
|
||||||
classNameIsRegister?: boolean
|
classNameIsRegister?: boolean
|
||||||
args?: unknown[]
|
args?: unknown[],
|
||||||
cbCmd?: ReceiveCmd | null
|
cbCmd?: ReceiveCmd | null,
|
||||||
cmdCB?: (payload: any) => boolean
|
cmdCB?: (payload: any) => boolean;
|
||||||
afterFirstCmd?: boolean // 是否在methodName调用完之后再去hook cbCmd
|
afterFirstCmd?: boolean, // 是否在methodName调用完之后再去hook cbCmd
|
||||||
timeoutSecond?: number
|
timeoutSecond?: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
async function callNTQQApi<ReturnType>(params: NTQQApiParams) {
|
function callNTQQApi<ReturnType>(params: NTQQApiParams) {
|
||||||
let {
|
let {
|
||||||
className, methodName, channel, args,
|
className, methodName, channel, args,
|
||||||
cbCmd, timeoutSecond: timeout,
|
cbCmd, timeoutSecond: timeout,
|
||||||
classNameIsRegister, cmdCB, afterFirstCmd
|
classNameIsRegister, cmdCB, afterFirstCmd
|
||||||
} = params
|
} = params;
|
||||||
className = className ?? NTQQApiClass.NT_API
|
className = className ?? NTQQApiClass.NT_API;
|
||||||
channel = channel ?? NTQQApiChannel.IPC_UP_2
|
channel = channel ?? NTQQApiChannel.IPC_UP_2;
|
||||||
args = args ?? []
|
args = args ?? [];
|
||||||
timeout = timeout ?? 5
|
timeout = timeout ?? 5;
|
||||||
afterFirstCmd = afterFirstCmd ?? true
|
afterFirstCmd = afterFirstCmd ?? true;
|
||||||
const uuid = uuidv4()
|
const uuid = uuidv4();
|
||||||
// log("callNTQQApi", channel, className, methodName, args, uuid)
|
// log("callNTQQApi", channel, className, methodName, args, uuid)
|
||||||
return await new Promise((resolve: (data: ReturnType) => void, reject) => {
|
return new Promise((resolve: (data: ReturnType) => void, reject) => {
|
||||||
// log("callNTQQApiPromise", channel, className, methodName, args, uuid)
|
// log("callNTQQApiPromise", channel, className, methodName, args, uuid)
|
||||||
const _timeout = timeout * 1000
|
const _timeout = timeout * 1000
|
||||||
let success = false
|
let success = false
|
||||||
let eventName = className + '-' + channel[channel.length - 1]
|
let eventName = className + "-" + channel[channel.length - 1];
|
||||||
if (classNameIsRegister) {
|
if (classNameIsRegister) {
|
||||||
eventName += '-register'
|
eventName += "-register";
|
||||||
}
|
}
|
||||||
const apiArgs = [methodName, ...args]
|
const apiArgs = [methodName, ...args]
|
||||||
if (!cbCmd) {
|
if (!cbCmd) {
|
||||||
@ -125,40 +144,40 @@ async function callNTQQApi<ReturnType>(params: NTQQApiParams) {
|
|||||||
hookApiCallbacks[uuid] = (r: ReturnType) => {
|
hookApiCallbacks[uuid] = (r: ReturnType) => {
|
||||||
success = true
|
success = true
|
||||||
resolve(r)
|
resolve(r)
|
||||||
}
|
};
|
||||||
} else {
|
} else {
|
||||||
// 这里的callback比较特殊,QQ后端先返回是否调用成功,再返回一条结果数据
|
// 这里的callback比较特殊,QQ后端先返回是否调用成功,再返回一条结果数据
|
||||||
const secondCallback = () => {
|
const secondCallback = () => {
|
||||||
const hookId = registerReceiveHook<ReturnType>(cbCmd, (payload) => {
|
const hookId = registerReceiveHook<ReturnType>(cbCmd, (payload) => {
|
||||||
// log(methodName, "second callback", cbCmd, payload, cmdCB);
|
// log(methodName, "second callback", cbCmd, payload, cmdCB);
|
||||||
if (cmdCB) {
|
if (!!cmdCB) {
|
||||||
if (cmdCB(payload)) {
|
if (cmdCB(payload)) {
|
||||||
removeReceiveHook(hookId)
|
removeReceiveHook(hookId);
|
||||||
success = true
|
success = true
|
||||||
resolve(payload)
|
resolve(payload);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
removeReceiveHook(hookId)
|
removeReceiveHook(hookId);
|
||||||
success = true
|
success = true
|
||||||
resolve(payload)
|
resolve(payload);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
!afterFirstCmd && secondCallback()
|
!afterFirstCmd && secondCallback();
|
||||||
hookApiCallbacks[uuid] = (result: GeneralCallResult) => {
|
hookApiCallbacks[uuid] = (result: GeneralCallResult) => {
|
||||||
log(`${methodName} callback`, result)
|
log(`${methodName} callback`, result)
|
||||||
if (result?.result == 0 || result === undefined) {
|
if (result?.result == 0 || result === undefined) {
|
||||||
afterFirstCmd && secondCallback()
|
afterFirstCmd && secondCallback();
|
||||||
} else {
|
} else {
|
||||||
success = true
|
success = true
|
||||||
reject(`ntqq api call failed, ${result.errMsg}`)
|
reject(`ntqq api call failed, ${result.errMsg}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// log("ntqq api timeout", success, channel, className, methodName)
|
// log("ntqq api timeout", success, channel, className, methodName)
|
||||||
if (!success) {
|
if (!success) {
|
||||||
log(`ntqq api timeout ${channel}, ${eventName}, ${methodName}`, apiArgs)
|
log(`ntqq api timeout ${channel}, ${eventName}, ${methodName}`, apiArgs);
|
||||||
reject(`ntqq api timeout ${channel}, ${eventName}, ${methodName}, ${apiArgs}`)
|
reject(`ntqq api timeout ${channel}, ${eventName}, ${methodName}, ${apiArgs}`)
|
||||||
}
|
}
|
||||||
}, _timeout)
|
}, _timeout)
|
||||||
@ -172,13 +191,15 @@ async function callNTQQApi<ReturnType>(params: NTQQApiParams) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sendMessagePool: Record<string, ((sendSuccessMsg: RawMessage) => void) | null> = {}// peerUid: callbackFunnc
|
|
||||||
|
export let sendMessagePool: Record<string, ((sendSuccessMsg: RawMessage) => void) | null> = {}// peerUid: callbackFunnc
|
||||||
|
|
||||||
interface GeneralCallResult {
|
interface GeneralCallResult {
|
||||||
result: number // 0: success
|
result: number, // 0: success
|
||||||
errMsg: string
|
errMsg: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class NTQQApi {
|
export class NTQQApi {
|
||||||
// static likeFriend = defineNTQQApi<void>(NTQQApiChannel.IPC_UP_2, NTQQApiClass.NT_API, NTQQApiMethod.LIKE_FRIEND)
|
// static likeFriend = defineNTQQApi<void>(NTQQApiChannel.IPC_UP_2, NTQQApiClass.NT_API, NTQQApiMethod.LIKE_FRIEND)
|
||||||
static async likeFriend(uid: string, count = 1) {
|
static async likeFriend(uid: string, count = 1) {
|
||||||
@ -198,9 +219,7 @@ export class NTQQApi {
|
|||||||
static async getSelfInfo() {
|
static async getSelfInfo() {
|
||||||
return await callNTQQApi<SelfInfo>({
|
return await callNTQQApi<SelfInfo>({
|
||||||
className: NTQQApiClass.GLOBAL_DATA,
|
className: NTQQApiClass.GLOBAL_DATA,
|
||||||
// channel: NTQQApiChannel.IPC_UP_3,
|
methodName: NTQQApiMethod.SELF_INFO, timeoutSecond: 2
|
||||||
methodName: NTQQApiMethod.SELF_INFO,
|
|
||||||
timeoutSecond: 2
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,19 +254,19 @@ export class NTQQApi {
|
|||||||
|
|
||||||
static async getFriends(forced = false) {
|
static async getFriends(forced = false) {
|
||||||
const data = await callNTQQApi<{
|
const data = await callNTQQApi<{
|
||||||
data: Array<{
|
data: {
|
||||||
categoryId: number
|
categoryId: number,
|
||||||
categroyName: string
|
categroyName: string,
|
||||||
categroyMbCount: number
|
categroyMbCount: number,
|
||||||
buddyList: Friend[]
|
buddyList: Friend[]
|
||||||
}>
|
}[]
|
||||||
}>(
|
}>(
|
||||||
{
|
{
|
||||||
methodName: NTQQApiMethod.FRIENDS,
|
methodName: NTQQApiMethod.FRIENDS,
|
||||||
args: [{force_update: forced}, undefined],
|
args: [{force_update: forced}, undefined],
|
||||||
cbCmd: ReceiveCmd.FRIENDS
|
cbCmd: ReceiveCmd.FRIENDS
|
||||||
})
|
})
|
||||||
const _friends: Friend[] = []
|
let _friends: Friend[] = [];
|
||||||
for (const fData of data.data) {
|
for (const fData of data.data) {
|
||||||
_friends.push(...fData.buddyList)
|
_friends.push(...fData.buddyList)
|
||||||
}
|
}
|
||||||
@ -256,11 +275,11 @@ export class NTQQApi {
|
|||||||
|
|
||||||
static async getGroups(forced = false) {
|
static async getGroups(forced = false) {
|
||||||
let cbCmd = ReceiveCmd.GROUPS
|
let cbCmd = ReceiveCmd.GROUPS
|
||||||
if (process.platform != 'win32') {
|
if (process.platform != "win32") {
|
||||||
cbCmd = ReceiveCmd.GROUPS_UNIX
|
cbCmd = ReceiveCmd.GROUPS_UNIX
|
||||||
}
|
}
|
||||||
const result = await callNTQQApi<{
|
const result = await callNTQQApi<{
|
||||||
updateType: number
|
updateType: number,
|
||||||
groupList: Group[]
|
groupList: Group[]
|
||||||
}>({methodName: NTQQApiMethod.GROUPS, args: [{force_update: forced}, undefined], cbCmd})
|
}>({methodName: NTQQApiMethod.GROUPS, args: [{force_update: forced}, undefined], cbCmd})
|
||||||
return result.groupList
|
return result.groupList
|
||||||
@ -271,7 +290,7 @@ export class NTQQApi {
|
|||||||
methodName: NTQQApiMethod.GROUP_MEMBER_SCENE,
|
methodName: NTQQApiMethod.GROUP_MEMBER_SCENE,
|
||||||
args: [{
|
args: [{
|
||||||
groupCode: groupQQ,
|
groupCode: groupQQ,
|
||||||
scene: 'groupMemberList_MainWindow'
|
scene: "groupMemberList_MainWindow"
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
// log("get group member sceneId", sceneId);
|
// log("get group member sceneId", sceneId);
|
||||||
@ -281,8 +300,8 @@ export class NTQQApi {
|
|||||||
}>({
|
}>({
|
||||||
methodName: NTQQApiMethod.GROUP_MEMBERS,
|
methodName: NTQQApiMethod.GROUP_MEMBERS,
|
||||||
args: [{
|
args: [{
|
||||||
sceneId,
|
sceneId: sceneId,
|
||||||
num
|
num: num
|
||||||
},
|
},
|
||||||
null
|
null
|
||||||
]
|
]
|
||||||
@ -343,35 +362,35 @@ export class NTQQApi {
|
|||||||
|
|
||||||
// 上传文件到QQ的文件夹
|
// 上传文件到QQ的文件夹
|
||||||
static async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC) {
|
static async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC) {
|
||||||
const md5 = await NTQQApi.getFileMd5(filePath)
|
const md5 = await NTQQApi.getFileMd5(filePath);
|
||||||
let ext = (await NTQQApi.getFileType(filePath))?.ext
|
let ext = (await NTQQApi.getFileType(filePath))?.ext
|
||||||
if (ext) {
|
if (ext) {
|
||||||
ext = '.' + ext
|
ext = "." + ext
|
||||||
} else {
|
} else {
|
||||||
ext = ''
|
ext = ""
|
||||||
}
|
}
|
||||||
let fileName = `${path.basename(filePath)}`
|
let fileName = `${path.basename(filePath)}`;
|
||||||
if (!fileName.includes('.')) {
|
if (fileName.indexOf(".") === -1) {
|
||||||
fileName += ext
|
fileName += ext;
|
||||||
}
|
}
|
||||||
const mediaPath = await callNTQQApi<string>({
|
const mediaPath = await callNTQQApi<string>({
|
||||||
methodName: NTQQApiMethod.MEDIA_FILE_PATH,
|
methodName: NTQQApiMethod.MEDIA_FILE_PATH,
|
||||||
args: [{
|
args: [{
|
||||||
path_info: {
|
path_info: {
|
||||||
md5HexStr: md5,
|
md5HexStr: md5,
|
||||||
fileName,
|
fileName: fileName,
|
||||||
elementType,
|
elementType: elementType,
|
||||||
elementSubType: 0,
|
elementSubType: 0,
|
||||||
thumbSize: 0,
|
thumbSize: 0,
|
||||||
needCreate: true,
|
needCreate: true,
|
||||||
downloadType: 1,
|
downloadType: 1,
|
||||||
file_uuid: ''
|
file_uuid: ""
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
log('media path', mediaPath)
|
log("media path", mediaPath)
|
||||||
await NTQQApi.copyFile(filePath, mediaPath)
|
await NTQQApi.copyFile(filePath, mediaPath);
|
||||||
const fileSize = await NTQQApi.getFileSize(filePath)
|
const fileSize = await NTQQApi.getFileSize(filePath);
|
||||||
return {
|
return {
|
||||||
md5,
|
md5,
|
||||||
fileName,
|
fileName,
|
||||||
@ -388,16 +407,16 @@ export class NTQQApi {
|
|||||||
const apiParams = [
|
const apiParams = [
|
||||||
{
|
{
|
||||||
getReq: {
|
getReq: {
|
||||||
msgId,
|
msgId: msgId,
|
||||||
chatType,
|
chatType: chatType,
|
||||||
peerUid,
|
peerUid: peerUid,
|
||||||
elementId,
|
elementId: elementId,
|
||||||
thumbSize: 0,
|
thumbSize: 0,
|
||||||
downloadType: 1,
|
downloadType: 1,
|
||||||
filePath: thumbPath
|
filePath: thumbPath,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
undefined
|
undefined,
|
||||||
]
|
]
|
||||||
// log("需要下载media", sourcePath);
|
// log("需要下载media", sourcePath);
|
||||||
await callNTQQApi({
|
await callNTQQApi({
|
||||||
@ -406,7 +425,7 @@ export class NTQQApi {
|
|||||||
cbCmd: ReceiveCmd.MEDIA_DOWNLOAD_COMPLETE,
|
cbCmd: ReceiveCmd.MEDIA_DOWNLOAD_COMPLETE,
|
||||||
cmdCB: (payload: { notifyInfo: { filePath: string } }) => {
|
cmdCB: (payload: { notifyInfo: { filePath: string } }) => {
|
||||||
// log("media 下载完成判断", payload.notifyInfo.filePath, sourcePath);
|
// log("media 下载完成判断", payload.notifyInfo.filePath, sourcePath);
|
||||||
return payload.notifyInfo.filePath == sourcePath
|
return payload.notifyInfo.filePath == sourcePath;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return sourcePath
|
return sourcePath
|
||||||
@ -426,30 +445,30 @@ export class NTQQApi {
|
|||||||
const peerUid = peer.peerUid
|
const peerUid = peer.peerUid
|
||||||
|
|
||||||
// 等待上一个相同的peer发送完
|
// 等待上一个相同的peer发送完
|
||||||
let checkLastSendUsingTime = 0
|
let checkLastSendUsingTime = 0;
|
||||||
const waitLastSend = async () => {
|
const waitLastSend = async () => {
|
||||||
if (checkLastSendUsingTime > timeout) {
|
if (checkLastSendUsingTime > timeout) {
|
||||||
throw ('发送超时')
|
throw ("发送超时")
|
||||||
}
|
}
|
||||||
const lastSending = sendMessagePool[peer.peerUid]
|
let lastSending = sendMessagePool[peer.peerUid]
|
||||||
if (lastSending) {
|
if (lastSending) {
|
||||||
// log("有正在发送的消息,等待中...")
|
// log("有正在发送的消息,等待中...")
|
||||||
await sleep(500)
|
await sleep(500);
|
||||||
checkLastSendUsingTime += 500
|
checkLastSendUsingTime += 500;
|
||||||
return await waitLastSend()
|
return await waitLastSend();
|
||||||
} else {
|
} else {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await waitLastSend()
|
await waitLastSend();
|
||||||
|
|
||||||
let sentMessage: RawMessage = null
|
let sentMessage: RawMessage = null;
|
||||||
sendMessagePool[peerUid] = async (rawMessage: RawMessage) => {
|
sendMessagePool[peerUid] = async (rawMessage: RawMessage) => {
|
||||||
delete sendMessagePool[peerUid]
|
delete sendMessagePool[peerUid];
|
||||||
sentMessage = rawMessage
|
sentMessage = rawMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
let checkSendCompleteUsingTime = 0
|
let checkSendCompleteUsingTime = 0;
|
||||||
const checkSendComplete = async (): Promise<RawMessage> => {
|
const checkSendComplete = async (): Promise<RawMessage> => {
|
||||||
if (sentMessage) {
|
if (sentMessage) {
|
||||||
if (waitComplete) {
|
if (waitComplete) {
|
||||||
@ -469,14 +488,13 @@ export class NTQQApi {
|
|||||||
await sleep(500)
|
await sleep(500)
|
||||||
return await checkSendComplete()
|
return await checkSendComplete()
|
||||||
}
|
}
|
||||||
log("开始发送消息", peer, msgElements)
|
|
||||||
callNTQQApi({
|
callNTQQApi({
|
||||||
methodName: NTQQApiMethod.SEND_MSG,
|
methodName: NTQQApiMethod.SEND_MSG,
|
||||||
args: [{
|
args: [{
|
||||||
msgId: '0',
|
msgId: "0",
|
||||||
peer,
|
peer, msgElements,
|
||||||
msgElements,
|
msgAttributeInfos: new Map(),
|
||||||
msgAttributeInfos: new Map()
|
|
||||||
}, null]
|
}, null]
|
||||||
}).then()
|
}).then()
|
||||||
return await checkSendComplete()
|
return await checkSendComplete()
|
||||||
@ -512,13 +530,13 @@ export class NTQQApi {
|
|||||||
commentElements: [],
|
commentElements: [],
|
||||||
msgAttributeInfos: new Map()
|
msgAttributeInfos: new Map()
|
||||||
},
|
},
|
||||||
null
|
null,
|
||||||
]
|
]
|
||||||
return await new Promise<RawMessage>((resolve, reject) => {
|
return await new Promise<RawMessage>((resolve, reject) => {
|
||||||
let complete = false
|
let complete = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!complete) {
|
if (!complete) {
|
||||||
reject('转发消息超时')
|
reject("转发消息超时");
|
||||||
}
|
}
|
||||||
}, 5000)
|
}, 5000)
|
||||||
registerReceiveHook(ReceiveCmd.SELF_SEND_MSG, async (payload: { msgRecord: RawMessage }) => {
|
registerReceiveHook(ReceiveCmd.SELF_SEND_MSG, async (payload: { msgRecord: RawMessage }) => {
|
||||||
@ -544,10 +562,10 @@ export class NTQQApi {
|
|||||||
methodName: NTQQApiMethod.MULTI_FORWARD_MSG,
|
methodName: NTQQApiMethod.MULTI_FORWARD_MSG,
|
||||||
args: apiArgs
|
args: apiArgs
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
log('转发消息结果:', result, apiArgs)
|
log("转发消息结果:", result, apiArgs)
|
||||||
if (result.result !== 0) {
|
if (result.result !== 0) {
|
||||||
complete = true
|
complete = true;
|
||||||
reject('转发消息失败,' + JSON.stringify(result))
|
reject("转发消息失败," + JSON.stringify(result));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -558,56 +576,56 @@ export class NTQQApi {
|
|||||||
// 加群通知,退出通知,需要管理员权限
|
// 加群通知,退出通知,需要管理员权限
|
||||||
callNTQQApi<GeneralCallResult>({
|
callNTQQApi<GeneralCallResult>({
|
||||||
methodName: ReceiveCmd.GROUP_NOTIFY,
|
methodName: ReceiveCmd.GROUP_NOTIFY,
|
||||||
classNameIsRegister: true
|
classNameIsRegister: true,
|
||||||
}).then()
|
}).then()
|
||||||
return await callNTQQApi<GroupNotifies>({
|
return await callNTQQApi<GroupNotifies>({
|
||||||
methodName: NTQQApiMethod.GET_GROUP_NOTICE,
|
methodName: NTQQApiMethod.GET_GROUP_NOTICE,
|
||||||
cbCmd: ReceiveCmd.GROUP_NOTIFY,
|
cbCmd: ReceiveCmd.GROUP_NOTIFY,
|
||||||
afterFirstCmd: false,
|
afterFirstCmd: false,
|
||||||
args: [
|
args: [
|
||||||
{doubt: false, startSeq: '', number: 14},
|
{"doubt": false, "startSeq": "", "number": 14},
|
||||||
null
|
null
|
||||||
]
|
]
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async handleGroupRequest(seq: string, operateType: GroupRequestOperateTypes, reason?: string) {
|
static async handleGroupRequest(seq: string, operateType: GroupRequestOperateTypes, reason?: string) {
|
||||||
const notify: GroupNotify = groupNotifies[seq]
|
const notify: GroupNotify = groupNotifies[seq];
|
||||||
if (!notify) {
|
if (!notify) {
|
||||||
throw `${seq}对应的加群通知不存在`
|
throw `${seq}对应的加群通知不存在`
|
||||||
}
|
}
|
||||||
delete groupNotifies[seq]
|
delete groupNotifies[seq];
|
||||||
return await callNTQQApi<GeneralCallResult>({
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.HANDLE_GROUP_REQUEST,
|
methodName: NTQQApiMethod.HANDLE_GROUP_REQUEST,
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
doubt: false,
|
"doubt": false,
|
||||||
operateMsg: {
|
"operateMsg": {
|
||||||
operateType, // 2 拒绝
|
"operateType": operateType, // 2 拒绝
|
||||||
targetMsg: {
|
"targetMsg": {
|
||||||
seq, // 通知序列号
|
"seq": seq, // 通知序列号
|
||||||
type: notify.type,
|
"type": notify.type,
|
||||||
groupCode: notify.group.groupCode,
|
"groupCode": notify.group.groupCode,
|
||||||
postscript: reason
|
"postscript": reason
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
null
|
null
|
||||||
]
|
]
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async quitGroup(groupQQ: string) {
|
static async quitGroup(groupQQ: string) {
|
||||||
await callNTQQApi<GeneralCallResult>({
|
await callNTQQApi<GeneralCallResult>({
|
||||||
methodName: NTQQApiMethod.QUIT_GROUP,
|
methodName: NTQQApiMethod.QUIT_GROUP,
|
||||||
args: [
|
args: [
|
||||||
{groupCode: groupQQ},
|
{"groupCode": groupQQ},
|
||||||
null
|
null
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async handleFriendRequest(sourceId: number, accept: boolean) {
|
static async handleFriendRequest(sourceId: number, accept: boolean,) {
|
||||||
const request: FriendRequest = friendRequests[sourceId]
|
const request: FriendRequest = friendRequests[sourceId]
|
||||||
if (!request) {
|
if (!request) {
|
||||||
throw `sourceId ${sourceId}, 对应的好友请求不存在`
|
throw `sourceId ${sourceId}, 对应的好友请求不存在`
|
||||||
@ -616,16 +634,16 @@ export class NTQQApi {
|
|||||||
methodName: NTQQApiMethod.HANDLE_FRIEND_REQUEST,
|
methodName: NTQQApiMethod.HANDLE_FRIEND_REQUEST,
|
||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
approvalInfo: {
|
"approvalInfo": {
|
||||||
friendUid: request.friendUid,
|
"friendUid": request.friendUid,
|
||||||
reqTime: request.reqTime,
|
"reqTime": request.reqTime,
|
||||||
accept
|
accept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
delete friendRequests[sourceId]
|
delete friendRequests[sourceId];
|
||||||
return result
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') {
|
static async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') {
|
||||||
@ -637,7 +655,7 @@ export class NTQQApi {
|
|||||||
groupCode: groupQQ,
|
groupCode: groupQQ,
|
||||||
kickUids,
|
kickUids,
|
||||||
refuseForever,
|
refuseForever,
|
||||||
kickReason
|
kickReason,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -652,7 +670,7 @@ export class NTQQApi {
|
|||||||
args: [
|
args: [
|
||||||
{
|
{
|
||||||
groupCode: groupQQ,
|
groupCode: groupQQ,
|
||||||
memList
|
memList,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -712,4 +730,107 @@ export class NTQQApi {
|
|||||||
static publishGroupBulletin(groupQQ: string, title: string, content: string) {
|
static publishGroupBulletin(groupQQ: string, title: string, content: string) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
static async setCacheSilentScan(isSilent: boolean = true) {
|
||||||
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
|
methodName: NTQQApiMethod.CACHE_SET_SILENCE,
|
||||||
|
args: [{
|
||||||
|
isSilent
|
||||||
|
}, null]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static addCacheScannedPaths(pathMap: object = {}) {
|
||||||
|
return callNTQQApi<GeneralCallResult>({
|
||||||
|
methodName: NTQQApiMethod.CACHE_ADD_SCANNED_PATH,
|
||||||
|
args: [{
|
||||||
|
pathMap: {...pathMap},
|
||||||
|
}, null]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static scanCache() {
|
||||||
|
callNTQQApi<GeneralCallResult>({
|
||||||
|
methodName: ReceiveCmd.CACHE_SCAN_FINISH,
|
||||||
|
classNameIsRegister: true,
|
||||||
|
}).then();
|
||||||
|
return callNTQQApi<CacheScanResult>({
|
||||||
|
methodName: NTQQApiMethod.CACHE_SCAN,
|
||||||
|
args: [null, null],
|
||||||
|
timeoutSecond: 300,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static getHotUpdateCachePath() {
|
||||||
|
return callNTQQApi<string>({
|
||||||
|
className: NTQQApiClass.HOTUPDATE_API,
|
||||||
|
methodName: NTQQApiMethod.CACHE_PATH_HOT_UPDATE
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDesktopTmpPath() {
|
||||||
|
return callNTQQApi<string>({
|
||||||
|
className: NTQQApiClass.BUSINESS_API,
|
||||||
|
methodName: NTQQApiMethod.CACHE_PATH_DESKTOP_TEMP
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static getCacheSessionPathList() {
|
||||||
|
return callNTQQApi<{
|
||||||
|
key: string,
|
||||||
|
value: string
|
||||||
|
}[]>({
|
||||||
|
className: NTQQApiClass.OS_API,
|
||||||
|
methodName: NTQQApiMethod.CACHE_PATH_SESSION,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static clearCache(cacheKeys: Array<string> = [ 'tmp', 'hotUpdate' ]) {
|
||||||
|
return callNTQQApi<any>({ // TODO: 目前还不知道真正的返回值是什么
|
||||||
|
methodName: NTQQApiMethod.CACHE_CLEAR,
|
||||||
|
args: [{
|
||||||
|
keys: cacheKeys
|
||||||
|
}, null]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) {
|
||||||
|
return new Promise<ChatCacheList>((res, rej) => {
|
||||||
|
callNTQQApi<ChatCacheList>({
|
||||||
|
methodName: NTQQApiMethod.CACHE_CHAT_GET,
|
||||||
|
args: [{
|
||||||
|
chatType: type,
|
||||||
|
pageSize,
|
||||||
|
order: 1,
|
||||||
|
pageIndex
|
||||||
|
}, null]
|
||||||
|
}).then(list => res(list))
|
||||||
|
.catch(e => rej(e));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) {
|
||||||
|
const _lastRecord = lastRecord ? lastRecord : { fileType: fileType };
|
||||||
|
|
||||||
|
return callNTQQApi<CacheFileList>({
|
||||||
|
methodName: NTQQApiMethod.CACHE_FILE_GET,
|
||||||
|
args: [{
|
||||||
|
fileType: fileType,
|
||||||
|
restart: true,
|
||||||
|
pageSize: pageSize,
|
||||||
|
order: 1,
|
||||||
|
lastRecord: _lastRecord,
|
||||||
|
}, null]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
|
||||||
|
return await callNTQQApi<GeneralCallResult>({
|
||||||
|
methodName: NTQQApiMethod.CACHE_CHAT_CLEAR,
|
||||||
|
args: [{
|
||||||
|
chats,
|
||||||
|
fileKeys
|
||||||
|
}, null]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -403,4 +403,68 @@ export interface FriendRequestNotify {
|
|||||||
unreadNums: number,
|
unreadNums: number,
|
||||||
buddyReqs: FriendRequest[]
|
buddyReqs: FriendRequest[]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CacheScanResult {
|
||||||
|
result: number,
|
||||||
|
size: [ // 单位为字节
|
||||||
|
string, // 系统总存储空间
|
||||||
|
string, // 系统可用存储空间
|
||||||
|
string, // 系统已用存储空间
|
||||||
|
string, // QQ总大小
|
||||||
|
string, // 「聊天与文件」大小
|
||||||
|
string, // 未知
|
||||||
|
string, // 「缓存数据」大小
|
||||||
|
string, // 「其他数据」大小
|
||||||
|
string, // 未知
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChatCacheList {
|
||||||
|
pageCount: number,
|
||||||
|
infos: ChatCacheListItem[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChatCacheListItem {
|
||||||
|
chatType: ChatType,
|
||||||
|
basicChatCacheInfo: ChatCacheListItemBasic,
|
||||||
|
guildChatCacheInfo: unknown[] // TODO: 没用过频道所以不知道这里边的详细内容
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChatCacheListItemBasic {
|
||||||
|
chatSize: string,
|
||||||
|
chatTime: string,
|
||||||
|
uid: string,
|
||||||
|
uin: string,
|
||||||
|
remarkName: string,
|
||||||
|
nickName: string,
|
||||||
|
chatType?: ChatType,
|
||||||
|
isChecked?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum CacheFileType {
|
||||||
|
IMAGE = 0,
|
||||||
|
VIDEO = 1,
|
||||||
|
AUDIO = 2,
|
||||||
|
DOCUMENT = 3,
|
||||||
|
OTHER = 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CacheFileList {
|
||||||
|
infos: CacheFileListItem[],
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CacheFileListItem {
|
||||||
|
fileSize: string,
|
||||||
|
fileTime: string,
|
||||||
|
fileKey: string,
|
||||||
|
elementId: string,
|
||||||
|
elementIdStr: string,
|
||||||
|
fileType: CacheFileType,
|
||||||
|
path: string,
|
||||||
|
fileName: string,
|
||||||
|
senderId: string,
|
||||||
|
previewPath: string,
|
||||||
|
senderName: string,
|
||||||
|
isChecked?: boolean,
|
||||||
|
}
|
||||||
|
103
src/onebot11/action/CleanCache.ts
Normal file
103
src/onebot11/action/CleanCache.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import BaseAction from "./BaseAction";
|
||||||
|
import {ActionName} from "./types";
|
||||||
|
import {NTQQApi} from "../../ntqqapi/ntcall";
|
||||||
|
import fs from "fs";
|
||||||
|
import Path from "path";
|
||||||
|
import {
|
||||||
|
ChatType,
|
||||||
|
ChatCacheListItemBasic,
|
||||||
|
CacheFileType
|
||||||
|
} from '../../ntqqapi/types';
|
||||||
|
|
||||||
|
export default class CleanCache extends BaseAction<void, void> {
|
||||||
|
actionName = ActionName.CleanCache
|
||||||
|
|
||||||
|
protected _handle(): Promise<void> {
|
||||||
|
return new Promise<void>(async (res, rej) => {
|
||||||
|
try {
|
||||||
|
const cacheFilePaths: string[] = [];
|
||||||
|
|
||||||
|
await NTQQApi.setCacheSilentScan(false);
|
||||||
|
|
||||||
|
cacheFilePaths.push((await NTQQApi.getHotUpdateCachePath()));
|
||||||
|
cacheFilePaths.push((await NTQQApi.getDesktopTmpPath()));
|
||||||
|
(await NTQQApi.getCacheSessionPathList()).forEach(e => cacheFilePaths.push(e.value));
|
||||||
|
|
||||||
|
// await NTQQApi.addCacheScannedPaths(); // XXX: 调用就崩溃,原因目前还未知
|
||||||
|
const cacheScanResult = await NTQQApi.scanCache();
|
||||||
|
const cacheSize = parseInt(cacheScanResult.size[6]);
|
||||||
|
|
||||||
|
if (cacheScanResult.result !== 0) {
|
||||||
|
throw('Something went wrong while scanning cache. Code: ' + cacheScanResult.result);
|
||||||
|
}
|
||||||
|
|
||||||
|
await NTQQApi.setCacheSilentScan(true);
|
||||||
|
if (cacheSize > 0 && cacheFilePaths.length > 2) { // 存在缓存文件且大小不为 0 时执行清理动作
|
||||||
|
// await NTQQApi.clearCache([ 'tmp', 'hotUpdate', ...cacheScanResult ]) // XXX: 也是调用就崩溃,调用 fs 删除得了
|
||||||
|
deleteCachePath(cacheFilePaths);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取聊天记录列表
|
||||||
|
// NOTE: 以防有人不需要删除聊天记录,暂时先注释掉,日后加个开关
|
||||||
|
// const privateChatCache = await getCacheList(ChatType.friend); // 私聊消息
|
||||||
|
// const groupChatCache = await getCacheList(ChatType.group); // 群聊消息
|
||||||
|
// const chatCacheList = [ ...privateChatCache, ...groupChatCache ];
|
||||||
|
const chatCacheList: ChatCacheListItemBasic[] = [];
|
||||||
|
|
||||||
|
// 获取聊天缓存文件列表
|
||||||
|
const cacheFileList: string[] = [];
|
||||||
|
|
||||||
|
for (const name in CacheFileType) {
|
||||||
|
if (!isNaN(parseInt(name))) continue;
|
||||||
|
|
||||||
|
const fileTypeAny: any = CacheFileType[name];
|
||||||
|
const fileType: CacheFileType = fileTypeAny;
|
||||||
|
|
||||||
|
cacheFileList.push(...(await NTQQApi.getFileCacheInfo(fileType)).infos.map(file => file.fileKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 一并清除
|
||||||
|
await NTQQApi.clearChatCache(chatCacheList, cacheFileList);
|
||||||
|
res();
|
||||||
|
} catch(e) {
|
||||||
|
console.error('清理缓存时发生了错误');
|
||||||
|
rej(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteCachePath(pathList: string[]) {
|
||||||
|
const emptyPath = (path: string) => {
|
||||||
|
if (!fs.existsSync(path)) return;
|
||||||
|
const files = fs.readdirSync(path);
|
||||||
|
files.forEach(file => {
|
||||||
|
const filePath = Path.resolve(path, file);
|
||||||
|
const stats = fs.statSync(filePath);
|
||||||
|
if (stats.isDirectory()) emptyPath(filePath);
|
||||||
|
else fs.unlinkSync(filePath);
|
||||||
|
});
|
||||||
|
fs.rmdirSync(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const path of pathList) {
|
||||||
|
emptyPath(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCacheList(type: ChatType) { // NOTE: 做这个方法主要是因为目前还不支持针对频道消息的清理
|
||||||
|
return new Promise<Array<ChatCacheListItemBasic>>((res, rej) => {
|
||||||
|
NTQQApi.getChatCacheList(type, 1000, 0)
|
||||||
|
.then(data => {
|
||||||
|
const list = data.infos.filter(e => e.chatType === type && parseInt(e.basicChatCacheInfo.chatSize) > 0);
|
||||||
|
const result = list.map(e => {
|
||||||
|
const result = { ...e.basicChatCacheInfo };
|
||||||
|
result.chatType = type;
|
||||||
|
result.isChecked = true;
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
res(result);
|
||||||
|
})
|
||||||
|
.catch(e => rej(e));
|
||||||
|
});
|
||||||
|
}
|
@ -31,6 +31,7 @@ import SetGroupCard from "./SetGroupCard";
|
|||||||
import GetImage from "./GetImage";
|
import GetImage from "./GetImage";
|
||||||
import GetRecord from "./GetRecord";
|
import GetRecord from "./GetRecord";
|
||||||
import GoCQHTTPMarkMsgAsRead from "./MarkMsgAsRead";
|
import GoCQHTTPMarkMsgAsRead from "./MarkMsgAsRead";
|
||||||
|
import CleanCache from "./CleanCache";
|
||||||
|
|
||||||
export const actionHandlers = [
|
export const actionHandlers = [
|
||||||
new Debug(),
|
new Debug(),
|
||||||
@ -56,6 +57,7 @@ export const actionHandlers = [
|
|||||||
new SetGroupCard(),
|
new SetGroupCard(),
|
||||||
new GetImage(),
|
new GetImage(),
|
||||||
new GetRecord(),
|
new GetRecord(),
|
||||||
|
new CleanCache(),
|
||||||
|
|
||||||
//以下为go-cqhttp api
|
//以下为go-cqhttp api
|
||||||
new GoCQHTTPSendGroupForwardMsg(),
|
new GoCQHTTPSendGroupForwardMsg(),
|
||||||
|
@ -42,6 +42,7 @@ export enum ActionName {
|
|||||||
SetGroupName = "set_group_name",
|
SetGroupName = "set_group_name",
|
||||||
GetImage = "get_image",
|
GetImage = "get_image",
|
||||||
GetRecord = "get_record",
|
GetRecord = "get_record",
|
||||||
|
CleanCache = "clean_cache",
|
||||||
// 以下为go-cqhttp api
|
// 以下为go-cqhttp api
|
||||||
GoCQHTTP_SendGroupForwardMsg = "send_group_forward_msg",
|
GoCQHTTP_SendGroupForwardMsg = "send_group_forward_msg",
|
||||||
GoCQHTTP_SendPrivateForwardMsg = "send_private_forward_msg",
|
GoCQHTTP_SendPrivateForwardMsg = "send_private_forward_msg",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user