diff --git a/manifest.json b/manifest.json index c94e72e..e8133ca 100644 --- a/manifest.json +++ b/manifest.json @@ -1,10 +1,10 @@ { "manifest_version": 4, "type": "extension", - "name": "LLOneBot v3.16.0", + "name": "LLOneBot v3.17.0", "slug": "LLOneBot", "description": "LiteLoaderQQNT的OneBotApi,不支持商店在线更新", - "version": "3.16.0", + "version": "3.17.0", "icon": "./icon.jpg", "authors": [ { diff --git a/src/common/utils/file.ts b/src/common/utils/file.ts index 530cc43..6963191 100644 --- a/src/common/utils/file.ts +++ b/src/common/utils/file.ts @@ -6,11 +6,12 @@ import util from "util"; import {encode, getDuration, isWav} from "silk-wasm"; import path from "node:path"; import {v4 as uuidv4} from "uuid"; -import {DATA_DIR, log, TEMP_DIR} from "./index"; +import {checkFfmpeg, DATA_DIR, log, TEMP_DIR} from "./index"; import {getConfigUtil} from "../config"; import {dbUtil} from "../db"; import * as fileType from "file-type"; import {net} from "electron"; +import config from "../../../electron.vite.config"; export function isGIF(path: string) { @@ -66,28 +67,6 @@ export async function file2base64(path: string) { return result; } -export function checkFfmpeg(newPath: string = null): Promise { - return new Promise((resolve, reject) => { - log("开始检查ffmpeg", newPath); - if (newPath) { - ffmpeg.setFfmpegPath(newPath); - } - try { - ffmpeg.getAvailableFormats((err, formats) => { - if (err) { - log('ffmpeg is not installed or not found in PATH:', err); - resolve(false) - } else { - log('ffmpeg is installed.'); - resolve(true); - } - }) - } catch (e) { - resolve(false); - } - }); -} - export async function encodeSilk(filePath: string) { const fsp = require("fs").promises diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts index 5898e52..04e2937 100644 --- a/src/common/utils/index.ts +++ b/src/common/utils/index.ts @@ -13,4 +13,5 @@ export const PLUGIN_DIR = global.LiteLoader.plugins["LLOneBot"].path.plugin; if (!fs.existsSync(TEMP_DIR)) { fs.mkdirSync(TEMP_DIR); } -export {getVideoInfo} from "./video"; \ No newline at end of file +export {getVideoInfo} from "./video"; +export {checkFfmpeg} from "./video"; \ No newline at end of file diff --git a/src/common/utils/video.ts b/src/common/utils/video.ts index 83a5f20..d2632d0 100644 --- a/src/common/utils/video.ts +++ b/src/common/utils/video.ts @@ -1,6 +1,7 @@ import {log} from "./log"; import ffmpeg from "fluent-ffmpeg"; import fs from "fs"; +import {getConfigUtil} from "../config"; const defaultVideoThumbB64 = "/9j/4AAQSkZJRgABAQAAAQABAAD//gAXR2VuZXJhdGVkIGJ5IFNuaXBhc3Rl/9sAhAAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47AQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAF/APADAREAAhEBAxEB/8QBogAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoLEAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+foBAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKCxEAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDiAayNxwagBwNAC5oAM0xBmgBM0ANJoAjY0AQsaBkTGgCM0DEpAFAC0AFMBaACgAoEJTASgQlACUwCgQ4UAOFADhQA4UAOFADxQIkBqDQUGgBwagBQaBC5pgGaAELUAMLUARs1AETGgBhNAxhoASkAUALQIKYxaBBQAUwEoAQ0CEoASmAUAOoEKKAHCgBwoAeKAHigQ7NZmoZpgLmgBd1Ahd1ABupgNLUAMLUAMY0AMJoAYaAENACUCCgAoAWgAoAWgBKYCUAJQISgApgLQAooEOFACigB4oAeKBDxQAVmaiZpgGaAFzQAbqAE3UAIWpgNJoAYTQIaaAEoAQ0CEoASgBaACgBaACmAUAJQAlAgoAKYC0AKKBCigB4FADgKBDwKAHigBuazNRM0DEzTAM0AJmgAzQAhNAhpNACGmA2gQlACUCEoAKACgBaAFpgFACUAJQAUCCmAUALQIcBQA4CgB4FADgKBDhQA4UAMzWZqNzTGJQAZoATNABmgBKAEoEIaYCUCEoASgQlABQAtABQAtMBKACgAoEFABimAYoEKBQA4CgB4FADwKBDgKAFFADhQBCazNhKAEpgFACUAFACUAFAhDTAbQISgAoEJQAUALQAtMAoAKADFABigQYoAMUALimIUCgBwFAh4FADgKAHUALQAtAENZmwlACUwEoAKAEoAKACgQlMBpoEJQAUCCgBcUAFABTAXFAC4oAMUAGKBBigAxQIKYCigQ8UAOFADhQAtAC0ALQBDWZqJQMSgBKYBQAlABQISgBKYCGgQlAC0CCgBcUAFABTAUCkA7FMAxQAYoEJQAUCCmAooEOFADxQA4UAFAC0ALQBDWZqJQAlACUxhQAlABQIKAEoASmISgBcUCCgBaACgBcUAKBQAuKYC0CEoAQ0AJQISmAooEPFADhQA4UALQAtAC0AQ1maiUAFACUAJTAKAEoAKAEoAMUxBigAxQIWgAoAKAFAoAWgBaYBQIQ0ANNACUCCmIUUAOFADxQA4UALQAtABQBFWZqFACUAFACYpgFACUAFACUAFAgxTEFABQAUALQAooAWgAoAKYDTQIaaAEpiCgQ4UAOFAh4oGOFAC0ALSAKYEdZmglABQAUDDFACUwEoASgAoAKBBQIKYBQAUALQAtAC0AJQAhpgNJoENJoATNMQCgQ8UCHigB4oAWgYtABQAUAMrM0CgAoAKADFACUxiUAJQAlAgoAKYgoAKACgYtAC0AFAhDTAQmgBhNAhpNACZpiFBoEPFAEi0CHigB1ABQAUDEoAbWZoFABQAtABTAQ0ANNAxDQAlAhaAEpiCgAoGFAC0AFABmgBCaYhpNADCaBDSaBBmgABpiJFNAEimgB4NADqAFzQAlACE0AJWZoFAC0AFAC0wEIoAaaAG0AJQAUCCgApjCgAoAKADNABmgBpNMQ0mgBpNAhhNAgzQAoNADwaAHqaAJAaBDgaYC5oATNACZoAWszQKACgBaBDqYCGgBpoAYaBiUCCgBKYBQMKACgAoAM0AITQIaTQA0mmA0mgQ3NAhKAHCgBwNADwaAHg0AOBpiFzQAZoATNAD6zNAoAKAFoEOpgBoAaaAGGmAw0AJmgAzQMM0AGaADNABmgBM0AITQIaTQAhNMQw0AJQIKAFFADhQA4GgBwNADs0xC5oAM0CDNAEtZmoUCCgBaAHUwCgBppgRtQAw0ANzQAZoAM0AGaADNABmgBKAEoAQ0ANNMQhoEJQAlMBaQDgaAFBoAcDTAdmgQuaADNAgzQBPWZqFAgoAWgBaYC0CGmmBG1AyM0ANJoATNACZoAXNABmgAzQAUAJQAhoAQ0xDTQISmAUALQAUgHA0AKDTAdmgQuaBBQAtAFiszQKACgBaAFFMAoEIaYEbUDI2oAYaAEoASgAzQAuaACgAoAKAENMQ00AJTEFAhKACgAoAXNACg0AOBoAWgQtAC0AWazNAoAKACgBaYBQIQ0AMNMYw0AMIoAbQAlMAoAKACgAzSAKYhKAENACUxBQIKACgBKACgBaAHCgQ4UALQAUAWqzNAoAKACgApgFACGgQ00xjTQAwigBCKAG4pgJQAlABQAUCCgBKACgBKYgoEFABQISgAoAWgBRQA4UALQAUCLdZmoUAFABQAlMAoASgBDQA00wENACYoATFMBpFADSKAEoEJQAUAFABQAlMQtAgoASgQUAJQAUAKKAHCgBaBBQBbrM1CgAoAKACmAUAJQAlADaYBQAlACYpgIRQA0igBpFAhtABQAUAFMAoEFABQIKAEoASgQUALQAooAWgQUAW81mbC0CCgApgFACUAIaAEpgJQAUAFABQAhFMBpFADSKAGkUCExQAYoAMUAGKADFMQYoAMUCExSATFABQIKYBQAtABQIt5qDYM0ALmgQtIApgIaAENADaACmAlAC0ALQAUwGkUANIoAaRQAmKBBigAxQAYoAMUAGKBBigBMUAJigQmKAExTAKBC0AFAFnNQaig0AKDQAtAgoASgBDQAlMBKACgAFADhQAtMBCKAGkUAIRQAmKADFABigQmKADFACYoAXFABigQmKAExQAmKBCYpgJigAoAnzUGgZoAcDQAuaBC0AJQAhoASmAlABQAtADhQAtMAoATFACEUAJigAxQAYoATFAhMUAFABQAuKADFABigBpWgBCKBCYpgJigB+ag0DNADgaBDgaAFzQITNACUAJTAKACgBRQAopgOoAWgBKAEoAKACgAoASgBpoEJQAooAWgBaBhigBMUCEIoAQigBMUAJSLCgBQaBDgaQC5oEFACUwCgBKACmAtADhQA4UALQAUAJQAUAJQAUAJQAhoENoAWgBRQAooGLQAUAGKAGkUAIRQIZSKEoGKKBDhQAUCCgAoAKBBQAUwFoGKKAHCgBaACgAoASgAoASgBCaAEoEJmgAoAUGgBQaAHZoGFABQAUANoAjpDEoAWgBaAFoEFACUALQAUCCmAUAOFAxRQAtAC0AJQAUAJQAmaBDSaAEzQAmaYBmgBQaAHA0gFzQAuaBhmgAzQAlAEdIYUALQAtAgoAKAEoEFAC0AFMAoAUUDFFAC0ALQAUAJQAhoENNACE0wEoATNABmgBc0ALmgBc0gDNAC5oATNABmgBKRQlACigB1AgoASgQlABTAWgBKACgBaBi0ALQAZoAM0AFACGgQ00wENACUAJQAUCFzQMM0ALmgAzQAZoAM0AGaQC0igoAUUALQIWgBDQISmAUAFACUAFABQAuaBi5oAM0AGaBBmgBKAEpgIaAG0AJQAUCFoAM0DDNAC5oATNABmgAzQBJUlBQAooAWgQtACGmIaaACgAoASgBKACgBc0DCgQUAGaADNABTASgBDQAlACUAFAgoAKBhQAUAFABQAlAE1SUFAxRQIWgQtMBDQIQ0AJQAlAhKBiUAFABmgBc0AGaADNABTAKACgBKAEoASgQlABQAUAFAC0AFACUAFAE1SaBQAUCHCgQtMBKBCUAJQISgBDQA00DEzQAuaADNMBc0AGaADNABQAUAJQAlABQISgAoAKACgBaACgBKAEoAnqTQSgBRQIcKBC0xCUAJQISgBKAENADDQAmaYwzQAuaADNAC0AFABQAUAFAhKACgBKACgAoAWgAoELQAlAxKAJqk0EoAWgQooELTEFADaBCUABoENNMY00ANNAwzQAZoAXNAC0AFAC0CFoASgAoASgBKACgAoAWgQtABQAUANNAyWpNAoAKBCimIWgQUCEoASmIQ0ANNADTQMaaAEoGLmgAzQAtADhQIWgBaACgQhoASgYlACUALQIWgBaACgBKAENAyWpNBKYBQIcKBC0CEoEJTAKBCUANNADDQMQ0ANoGFAC5oAUGgBwNAhRQIWgBaAENACGgBtAwoAKAFzQIXNABmgAoAQ0DJKRoJQAtAhRQSLQIKYCUCCgBDQA00AMNAxpoGNoAM0AGaAFBoAcDQIcKBDqACgBDQAhoAQ0DEoAKADNAC5oEGaBhmgAoAkpGgUCCgQooELQIKYhKACgBKAGmgBpoGMNAxDQAlAwzQIUUAOFAhwoAcKBC0AJQAhoGNNACUAFABQAZoAXNABQAUAS0ixKACgQoNAhaYgoEFACUABoAaaAGmgYw0DENAxtABQAooEOFADhQIcKAFoASgBDQAhoGJQAUAFACUALQIKBi0CJDSLEoATNAhc0CHZpiCgQUAJQIKBjTQAhoGNNAxpoATFABigBQKAHCgBwoAWgAoAKACgBKAEoASgAoASgBaAAUAOoEONIoaTQAZoAUGmIUGgQtAgzQISgAoAQ0DGmgYlAxKACgAxQAtACigBRQAtAxaACgAoATFABigBCKAG0CEoAWgBRTAUUAf//Z" @@ -16,6 +17,8 @@ export async function getVideoInfo(filePath: string) { size: number, filePath: string }>((resolve, reject) => { + let ffmpegPath = getConfigUtil().getConfig().ffmpeg + ffmpegPath && ffmpeg.setFfmpegPath(ffmpegPath) ffmpeg(filePath).ffprobe((err, metadata) => { if (err) { reject(err); @@ -60,4 +63,26 @@ export async function encodeMp4(filePath: string) { return await getVideoInfo(newPath) } return videoInfo +} + +export function checkFfmpeg(newPath: string = null): Promise { + return new Promise((resolve, reject) => { + log("开始检查ffmpeg", newPath); + if (newPath) { + ffmpeg.setFfmpegPath(newPath); + } + try { + ffmpeg.getAvailableFormats((err, formats) => { + if (err) { + log('ffmpeg is not installed or not found in PATH:', err); + resolve(false) + } else { + log('ffmpeg is installed.'); + resolve(true); + } + }) + } catch (e) { + resolve(false); + } + }); } \ No newline at end of file diff --git a/src/main/main.ts b/src/main/main.ts index d16b8c1..10e33f8 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -42,9 +42,9 @@ import {NTQQGroupApi} from "../ntqqapi/api/group"; import {registerPokeHandler} from "../ntqqapi/external/ccpoke"; import {OB11FriendPokeEvent, OB11GroupPokeEvent} from "../onebot11/event/notice/OB11PokeEvent"; import {checkVersion, upgradeLLOneBot} from "../common/utils/upgrade"; -import {checkFfmpeg} from "../common/utils/file"; import {log} from "../common/utils/log"; import {getConfigUtil} from "../common/config"; +import {checkFfmpeg} from "../common/utils/video"; let running = false; diff --git a/src/main/setConfig.ts b/src/main/setConfig.ts index b82af07..b98d2e4 100644 --- a/src/main/setConfig.ts +++ b/src/main/setConfig.ts @@ -4,6 +4,7 @@ import {ob11WebsocketServer} from "../onebot11/server/ws/WebsocketServer"; import {ob11ReverseWebsockets} from "../onebot11/server/ws/ReverseWebsocket"; import {llonebotError} from "../common/data"; import {getConfigUtil} from "../common/config"; +import {checkFfmpeg} from "../common/utils"; export async function setConfig(config: Config) { let oldConfig = getConfigUtil().getConfig(); @@ -51,4 +52,5 @@ export async function setConfig(config: Config) { } } } + checkFfmpeg(config.ffmpeg).then() } \ No newline at end of file diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts index aa30069..f727293 100644 --- a/src/ntqqapi/api/group.ts +++ b/src/ntqqapi/api/group.ts @@ -5,6 +5,7 @@ import {uidMaps} from "../../common/data"; import {BrowserWindow} from "electron"; import {dbUtil} from "../../common/db"; import {log} from "../../common/utils/log"; +import {NTQQWindowApi, NTQQWindows} from "./window"; export class NTQQGroupApi{ static async getGroups(forced = false) { @@ -74,25 +75,7 @@ export class NTQQGroupApi{ } static async getGroupIgnoreNotifies() { await NTQQGroupApi.getGroupNotifies(); - const result = callNTQQApi({ - className: NTQQApiClass.WINDOW_API, - methodName: NTQQApiMethod.OPEN_EXTRA_WINDOW, - cbCmd: ReceiveCmdS.GROUP_NOTIFY, - afterFirstCmd: false, - args: [ - "GroupNotifyFilterWindow" - ] - }) - // 关闭窗口 - setTimeout(() => { - for (const w of BrowserWindow.getAllWindows()) { - // log("close window", w.webContents.getURL()) - if (w.webContents.getURL().indexOf("#/notify-filter/") != -1) { - w.close(); - } - } - }, 2000); - return result; + return await NTQQWindowApi.openWindow(NTQQWindows.GroupNotifyFilterWindow, ReceiveCmdS.GROUP_NOTIFY); } static async handleGroupRequest(seq: string, operateType: GroupRequestOperateTypes, reason?: string) { const notify: GroupNotify = await dbUtil.getGroupNotify(seq) diff --git a/src/ntqqapi/api/user.ts b/src/ntqqapi/api/user.ts index 131d01a..0d00e8b 100644 --- a/src/ntqqapi/api/user.ts +++ b/src/ntqqapi/api/user.ts @@ -53,5 +53,4 @@ export class NTQQUserApi{ return info } - } \ No newline at end of file diff --git a/src/ntqqapi/api/window.ts b/src/ntqqapi/api/window.ts new file mode 100644 index 0000000..4dec26e --- /dev/null +++ b/src/ntqqapi/api/window.ts @@ -0,0 +1,45 @@ +import {callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod} from "../ntcall"; +import {ReceiveCmd} from "../hook"; +import {BrowserWindow} from "electron"; + +interface NTQQWindow{ + windowName: string, + windowUrlHash: string, +} + +export class NTQQWindows{ + static GroupHomeWorkWindow: NTQQWindow = { + windowName: "GroupHomeWorkWindow", + windowUrlHash: "#/group-home-work" + } + static GroupNotifyFilterWindow: NTQQWindow = { + windowName: "GroupNotifyFilterWindow", + windowUrlHash: "#/group-notify-filter" + } +} + +export class NTQQWindowApi{ + + // 打开窗口并获取对应的下发事件 + static async openWindow(ntQQWindow: NTQQWindow, args: any[], cbCmd: ReceiveCmd=null, autoCloseSeconds: number=2){ + const result = await callNTQQApi({ + className: NTQQApiClass.WINDOW_API, + methodName: NTQQApiMethod.OPEN_EXTRA_WINDOW, + cbCmd, + afterFirstCmd: false, + args: [ + ntQQWindow.windowName, + ...args + ] + }) + setTimeout(() => { + for (const w of BrowserWindow.getAllWindows()) { + // log("close window", w.webContents.getURL()) + if (w.webContents.getURL().indexOf(ntQQWindow.windowUrlHash) != -1) { + w.close(); + } + } + }, autoCloseSeconds * 1000); + return result; + } +} \ No newline at end of file diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index d9139db..a6ff49a 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -33,6 +33,7 @@ export let ReceiveCmdS = { SELF_STATUS: 'nodeIKernelProfileListener/onSelfStatusChanged', CACHE_SCAN_FINISH: "nodeIKernelStorageCleanListener/onFinishScan", MEDIA_UPLOAD_COMPLETE: "nodeIKernelMsgListener/onRichMediaUploadComplete", + SKEY_UPDATE: "onSkeyUpdate" } export type ReceiveCmd = typeof ReceiveCmdS[keyof typeof ReceiveCmdS] diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts index 15b86a2..f326727 100644 --- a/src/ntqqapi/ntcall.ts +++ b/src/ntqqapi/ntcall.ts @@ -1,8 +1,9 @@ import {ipcMain} from "electron"; -import {hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook} from "./hook"; +import {hookApiCallbacks, ReceiveCmd, ReceiveCmdS, registerReceiveHook, removeReceiveHook} from "./hook"; import {v4 as uuidv4} from "uuid" import {log} from "../common/utils/log"; +import {NTQQWindowApi, NTQQWindows} from "./api/window"; export enum NTQQApiClass { NT_API = "ns-ntApi", @@ -11,7 +12,9 @@ export enum NTQQApiClass { WINDOW_API = "ns-WindowApi", HOTUPDATE_API = "ns-HotUpdateApi", BUSINESS_API = "ns-BusinessApi", - GLOBAL_DATA = "ns-GlobalDataApi" + GLOBAL_DATA = "ns-GlobalDataApi", + SKEY_API = "ns-SkeyApi", + HOME_WORK = "ns-GroupHomeWork" } export enum NTQQApiMethod { @@ -65,7 +68,9 @@ export enum NTQQApiMethod { OPEN_EXTRA_WINDOW = 'openExternalWindow', - SET_QQ_AVATAR = 'nodeIKernelProfileService/setHeader' + SET_QQ_AVATAR = 'nodeIKernelProfileService/setHeader', + GET_SKEY = "nodeIKernelTipOffService/getPskey", + UPDATE_SKEY = "updatePskey" } enum NTQQApiChannel { @@ -178,4 +183,51 @@ export class NTQQApi { }) } + static async getSkey(groupCode: string, groupName: string) { + await NTQQWindowApi.openWindow(NTQQWindows.GroupHomeWorkWindow, [{ + groupName, + groupCode, + "source": "funcbar" + }], ReceiveCmdS.SKEY_UPDATE, 1); + return await callNTQQApi({ + className: NTQQApiClass.HOME_WORK, + methodName: NTQQApiMethod.UPDATE_SKEY, + args: [ + { + domain: "qun.qq.com" + } + ] + }) + // return await callNTQQApi({ + // methodName: NTQQApiMethod.GET_SKEY, + // args: [ + // { + // "domains": [ + // "qzone.qq.com", + // "qlive.qq.com", + // "qun.qq.com", + // "gamecenter.qq.com", + // "vip.qq.com", + // "qianbao.qq.com", + // "qidian.qq.com" + // ], + // "isForNewPCQQ": false + // }, + // null + // ] + // }) + } + + static async updateSkey() { + return await callNTQQApi({ + className: NTQQApiClass.HOME_WORK, + methodName: NTQQApiMethod.UPDATE_SKEY, + args: [ + { + domain: "qun.qq.com" + } + ] + }) + } + } \ No newline at end of file