From 4c6bd3df0b9b362ab0e33b9099198b6d7f831bf1 Mon Sep 17 00:00:00 2001 From: linyuchen Date: Mon, 18 Mar 2024 11:07:08 +0800 Subject: [PATCH] refactor: utils structure --- src/common/config.ts | 11 +- src/common/data.ts | 3 +- src/common/db.ts | 3 +- src/common/server/http.ts | 3 +- src/common/server/websocket.ts | 3 +- src/common/utils/file.ts | 263 +++++++++++++ src/common/utils/helper.ts | 46 +++ src/common/utils/index.ts | 344 +----------------- src/common/utils/log.ts | 34 ++ src/main/main.ts | 5 +- src/main/setConfig.ts | 3 +- src/ntqqapi/api/file.ts | 2 +- src/ntqqapi/api/group.ts | 2 +- src/ntqqapi/api/msg.ts | 3 +- src/ntqqapi/constructor.ts | 4 +- src/ntqqapi/external/ccpoke/index.ts | 2 +- src/ntqqapi/hook.ts | 7 +- src/ntqqapi/ntcall.ts | 2 +- src/onebot11/action/BaseAction.ts | 3 +- src/onebot11/action/Debug.ts | 3 +- src/onebot11/action/GetFile.ts | 2 +- src/onebot11/action/GetGroupMemberInfo.ts | 3 +- src/onebot11/action/SendGroupMsg.ts | 3 +- src/onebot11/action/SendLike.ts | 2 +- src/onebot11/action/SendMsg.ts | 3 +- src/onebot11/action/SetGroupLeave.ts | 2 +- src/onebot11/action/llonebot/Config.ts | 2 +- .../action/llonebot/GetGroupAddRequest.ts | 2 +- src/onebot11/action/llonebot/SetQQAvatar.ts | 2 +- src/onebot11/action/utils.ts | 3 +- src/onebot11/constructor.ts | 4 +- src/onebot11/server/http.ts | 2 +- src/onebot11/server/postOB11Event.ts | 3 +- src/onebot11/server/ws/ReverseWebsocket.ts | 5 +- src/onebot11/server/ws/WebsocketServer.ts | 3 +- src/onebot11/server/ws/reply.ts | 3 +- src/onebot11/utils.ts | 4 +- 37 files changed, 419 insertions(+), 375 deletions(-) create mode 100644 src/common/utils/file.ts create mode 100644 src/common/utils/helper.ts create mode 100644 src/common/utils/log.ts diff --git a/src/common/config.ts b/src/common/config.ts index 16c854b..39269cb 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -1,6 +1,10 @@ import fs from "fs"; import {Config, OB11Config} from './types'; -import {mergeNewProperties} from "./utils"; + +import {mergeNewProperties} from "./utils/helper"; +import path from "node:path"; +import {selfInfo} from "./data"; +import {DATA_DIR} from "./utils"; export const HOOK_LOG = false; @@ -85,3 +89,8 @@ export class ConfigUtil { } } } + +export function getConfigUtil() { + const configFilePath = path.join(DATA_DIR, `config_${selfInfo.uin}.json`) + return new ConfigUtil(configFilePath) +} \ No newline at end of file diff --git a/src/common/data.ts b/src/common/data.ts index d342124..5bfb876 100644 --- a/src/common/data.ts +++ b/src/common/data.ts @@ -6,8 +6,9 @@ import { type SelfInfo } from '../ntqqapi/types' import {type FileCache, type LLOneBotError} from './types' -import {isNumeric, log} from "./utils"; import {NTQQGroupApi} from "../ntqqapi/api/group"; +import {log} from "./utils/log"; +import {isNumeric} from "./utils/helper"; export const selfInfo: SelfInfo = { uid: '', diff --git a/src/common/db.ts b/src/common/db.ts index 3da7967..8dbc859 100644 --- a/src/common/db.ts +++ b/src/common/db.ts @@ -1,8 +1,9 @@ import {Level} from "level"; import {type GroupNotify, RawMessage} from "../ntqqapi/types"; -import {DATA_DIR, log} from "./utils"; +import {DATA_DIR} from "./utils"; import {selfInfo} from "./data"; import {FileCache} from "./types"; +import {log} from "./utils/log"; type ReceiveTempUinMap = Record; diff --git a/src/common/server/http.ts b/src/common/server/http.ts index 7194649..32dd4bb 100644 --- a/src/common/server/http.ts +++ b/src/common/server/http.ts @@ -1,6 +1,7 @@ import express, {Express, json, Request, Response} from "express"; -import {getConfigUtil, log} from "../utils"; import http from "http"; +import {log} from "../utils/log"; +import {getConfigUtil} from "../config"; type RegisterHandler = (res: Response, payload: any) => Promise diff --git a/src/common/server/websocket.ts b/src/common/server/websocket.ts index f3f912e..0920b01 100644 --- a/src/common/server/websocket.ts +++ b/src/common/server/websocket.ts @@ -1,7 +1,8 @@ import {WebSocket, WebSocketServer} from "ws"; -import {getConfigUtil, log} from "../utils"; import urlParse from "url"; import {IncomingMessage} from "node:http"; +import {log} from "../utils/log"; +import {getConfigUtil} from "../config"; class WebsocketClientBase { private wsClient: WebSocket diff --git a/src/common/utils/file.ts b/src/common/utils/file.ts new file mode 100644 index 0000000..f473aef --- /dev/null +++ b/src/common/utils/file.ts @@ -0,0 +1,263 @@ +import fs from "fs"; +import crypto from "crypto"; +import ffmpeg from "fluent-ffmpeg"; +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} from "./index"; +import {log} from "./log"; +import {getConfigUtil} from "../config"; + +export function isGIF(path: string) { + const buffer = Buffer.alloc(4); + const fd = fs.openSync(path, 'r'); + fs.readSync(fd, buffer, 0, 4, 0); + fs.closeSync(fd); + return buffer.toString() === 'GIF8' +} + +// 定义一个异步函数来检查文件是否存在 +export function checkFileReceived(path: string, timeout: number = 3000): Promise { + return new Promise((resolve, reject) => { + const startTime = Date.now(); + + function check() { + if (fs.existsSync(path)) { + resolve(); + } else if (Date.now() - startTime > timeout) { + reject(new Error(`文件不存在: ${path}`)); + } else { + setTimeout(check, 100); + } + } + + check(); + }); +} + +export async function file2base64(path: string) { + const readFile = util.promisify(fs.readFile); + let result = { + err: "", + data: "" + } + try { + // 读取文件内容 + // if (!fs.existsSync(path)){ + // path = path.replace("\\Ori\\", "\\Thumb\\"); + // } + try { + await checkFileReceived(path, 5000); + } catch (e: any) { + result.err = e.toString(); + return result; + } + const data = await readFile(path); + // 转换为Base64编码 + result.data = data.toString('base64'); + } catch (err) { + result.err = err.toString(); + } + return result; +} + +export function checkFfmpeg(newPath: string = null): Promise { + return new Promise((resolve, reject) => { + if (newPath) { + ffmpeg.setFfmpegPath(newPath); + 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); + } + }) + } + }); +} + +export async function encodeSilk(filePath: string) { + const fsp = require("fs").promises + + function getFileHeader(filePath: string) { + // 定义要读取的字节数 + const bytesToRead = 7; + try { + const buffer = fs.readFileSync(filePath, { + encoding: null, + flag: "r", + }); + + const fileHeader = buffer.toString("hex", 0, bytesToRead); + return fileHeader; + } catch (err) { + console.error("读取文件错误:", err); + return; + } + } + + async function isWavFile(filePath: string) { + return isWav(fs.readFileSync(filePath)); + } + + // async function getAudioSampleRate(filePath: string) { + // try { + // const mm = await import('music-metadata'); + // const metadata = await mm.parseFile(filePath); + // log(`${filePath}采样率`, metadata.format.sampleRate); + // return metadata.format.sampleRate; + // } catch (error) { + // log(`${filePath}采样率获取失败`, error.stack); + // // console.error(error); + // } + // } + + try { + const fileName = path.basename(filePath); + const pttPath = path.join(DATA_DIR, uuidv4()); + if (getFileHeader(filePath) !== "02232153494c4b") { + log(`语音文件${filePath}需要转换成silk`) + const _isWav = await isWavFile(filePath); + const wavPath = pttPath + ".wav" + if (!_isWav) { + log(`语音文件${filePath}正在转换成wav`) + // let voiceData = await fsp.readFile(filePath) + await new Promise((resolve, reject) => { + const ffmpegPath = getConfigUtil().getConfig().ffmpeg; + if (ffmpegPath) { + ffmpeg.setFfmpegPath(ffmpegPath); + } + ffmpeg(filePath).toFormat("wav").audioChannels(2).on('end', function () { + log('wav转换完成'); + }) + .on('error', function (err) { + log(`wav转换出错: `, err.message,); + reject(err); + }) + .save(wavPath) + .on("end", () => { + filePath = wavPath + resolve(wavPath); + }); + }) + } + // const sampleRate = await getAudioSampleRate(filePath) || 0; + // log("音频采样率", sampleRate) + const pcm = fs.readFileSync(filePath); + const silk = await encode(pcm, 0); + fs.writeFileSync(pttPath, silk.data); + fs.unlink(wavPath, (err) => { + }); + log(`语音文件${filePath}转换成功!`, pttPath) + return { + converted: true, + path: pttPath, + duration: silk.duration, + }; + } else { + const pcm = fs.readFileSync(filePath); + let duration = 0; + try { + duration = getDuration(pcm); + } catch (e) { + log("获取语音文件时长失败", filePath, e.stack) + duration = fs.statSync(filePath).size / 1024 / 3 // 每3kb大约1s + duration = Math.floor(duration) + duration = Math.max(1, duration) + log("使用文件大小估算时长", duration) + } + + return { + converted: false, + path: filePath, + duration: duration, + }; + } + } catch (error) { + log("convert silk failed", error.stack); + return {}; + } +} + +export async function getVideoInfo(filePath: string) { + const size = fs.statSync(filePath).size; + return new Promise<{ + width: number, + height: number, + time: number, + format: string, + size: number, + filePath: string + }>((resolve, reject) => { + ffmpeg(filePath).ffprobe((err, metadata) => { + if (err) { + reject(err); + } else { + const videoStream = metadata.streams.find(s => s.codec_type === 'video'); + if (videoStream) { + console.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); + } else { + console.log('未找到视频流信息。'); + } + resolve({ + width: videoStream.width, height: videoStream.height, + time: parseInt(videoStream.duration), + format: metadata.format.format_name, + size, + filePath + }); + } + }); + }) +} + +export async function encodeMp4(filePath: string) { + let videoInfo = await getVideoInfo(filePath); + log("视频信息", videoInfo) + if (videoInfo.format.indexOf("mp4") === -1) { + log("视频需要转换为MP4格式", filePath) + // 转成mp4 + const newPath: string = await new Promise((resolve, reject) => { + const newPath = filePath + ".mp4" + ffmpeg(filePath) + .toFormat('mp4') + .on('error', (err) => { + reject(`转换视频格式失败: ${err.message}`); + }) + .on('end', () => { + log('视频转换为MP4格式完成'); + resolve(newPath); // 返回转换后的文件路径 + }) + .save(newPath); + }); + return await getVideoInfo(newPath) + } + return videoInfo +} + +export function calculateFileMD5(filePath: string): Promise { + return new Promise((resolve, reject) => { + // 创建一个流式读取器 + const stream = fs.createReadStream(filePath); + const hash = crypto.createHash('md5'); + + stream.on('data', (data: Buffer) => { + // 当读取到数据时,更新哈希对象的状态 + hash.update(data); + }); + + stream.on('end', () => { + // 文件读取完成,计算哈希 + const md5 = hash.digest('hex'); + resolve(md5); + }); + + stream.on('error', (err: Error) => { + // 处理可能的读取错误 + reject(err); + }); + }); +} \ No newline at end of file diff --git a/src/common/utils/helper.ts b/src/common/utils/helper.ts new file mode 100644 index 0000000..2ff735e --- /dev/null +++ b/src/common/utils/helper.ts @@ -0,0 +1,46 @@ +function truncateString(obj: any, maxLength = 500) { + if (obj !== null && typeof obj === 'object') { + Object.keys(obj).forEach(key => { + if (typeof obj[key] === 'string') { + // 如果是字符串且超过指定长度,则截断 + if (obj[key].length > maxLength) { + obj[key] = obj[key].substring(0, maxLength) + '...'; + } + } else if (typeof obj[key] === 'object') { + // 如果是对象或数组,则递归调用 + truncateString(obj[key], maxLength); + } + }); + } + return obj; +} + +export function isNumeric(str: string) { + return /^\d+$/.test(str); +} + +export function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +// 在保证老对象已有的属性不变化的情况下将新对象的属性复制到老对象 +export function mergeNewProperties(newObj: any, oldObj: any) { + Object.keys(newObj).forEach(key => { + // 如果老对象不存在当前属性,则直接复制 + if (!oldObj.hasOwnProperty(key)) { + oldObj[key] = newObj[key]; + } else { + // 如果老对象和新对象的当前属性都是对象,则递归合并 + if (typeof oldObj[key] === 'object' && typeof newObj[key] === 'object') { + mergeNewProperties(newObj[key], oldObj[key]); + } else if (typeof oldObj[key] === 'object' || typeof newObj[key] === 'object') { + // 属性冲突,有一方不是对象,直接覆盖 + oldObj[key] = newObj[key]; + } + } + }); +} + +export function isNull(value: any) { + return value === undefined || value === null; +} \ No newline at end of file diff --git a/src/common/utils/index.ts b/src/common/utils/index.ts index b9153ed..af279cf 100644 --- a/src/common/utils/index.ts +++ b/src/common/utils/index.ts @@ -1,342 +1,10 @@ -import * as path from "node:path"; -import {selfInfo} from "../data"; -import {ConfigUtil} from "../config"; -import util from "util"; -import {encode, getDuration, isWav} from "silk-wasm"; -import fs from 'fs'; -import * as crypto from 'crypto'; -import {v4 as uuidv4} from "uuid"; -import ffmpeg from "fluent-ffmpeg" - +export * from './file' +export * from './helper' +export * from './log' +export * from './qqlevel' +export * from './qqpkg' +export * from './update' export const DATA_DIR = global.LiteLoader.plugins["LLOneBot"].path.data; -export function getConfigUtil() { - const configFilePath = path.join(DATA_DIR, `config_${selfInfo.uin}.json`) - return new ConfigUtil(configFilePath) -} - -function truncateString(obj: any, maxLength = 500) { - if (obj !== null && typeof obj === 'object') { - Object.keys(obj).forEach(key => { - if (typeof obj[key] === 'string') { - // 如果是字符串且超过指定长度,则截断 - if (obj[key].length > maxLength) { - obj[key] = obj[key].substring(0, maxLength) + '...'; - } - } else if (typeof obj[key] === 'object') { - // 如果是对象或数组,则递归调用 - truncateString(obj[key], maxLength); - } - }); - } - return obj; -} - -export function isNumeric(str: string) { - return /^\d+$/.test(str); -} -export function log(...msg: any[]) { - if (!getConfigUtil().getConfig().log) { - return //console.log(...msg); - } - let currentDateTime = new Date().toLocaleString(); - const date = new Date(); - const year = date.getFullYear(); - const month = date.getMonth() + 1; - const day = date.getDate(); - const currentDate = `${year}-${month}-${day}`; - const userInfo = selfInfo.uin ? `${selfInfo.nick}(${selfInfo.uin})` : "" - let logMsg = ""; - for (let msgItem of msg) { - // 判断是否是对象 - if (typeof msgItem === "object") { - let obj = JSON.parse(JSON.stringify(msgItem)); - logMsg += JSON.stringify(truncateString(obj)) + " "; - continue; - } - logMsg += msgItem + " "; - } - logMsg = `${currentDateTime} ${userInfo}: ${logMsg}\n\n` - // sendLog(...msg); - // console.log(msg) - fs.appendFile(path.join(DATA_DIR, `llonebot-${currentDate}.log`), logMsg, (err: any) => { - - }) -} - -export function isGIF(path: string) { - const buffer = Buffer.alloc(4); - const fd = fs.openSync(path, 'r'); - fs.readSync(fd, buffer, 0, 4, 0); - fs.closeSync(fd); - return buffer.toString() === 'GIF8' -} - -export function sleep(ms: number): Promise { - return new Promise(resolve => setTimeout(resolve, ms)); -} - - -// 定义一个异步函数来检查文件是否存在 -export function checkFileReceived(path: string, timeout: number = 3000): Promise { - return new Promise((resolve, reject) => { - const startTime = Date.now(); - - function check() { - if (fs.existsSync(path)) { - resolve(); - } else if (Date.now() - startTime > timeout) { - reject(new Error(`文件不存在: ${path}`)); - } else { - setTimeout(check, 100); - } - } - - check(); - }); -} - -export async function file2base64(path: string) { - const readFile = util.promisify(fs.readFile); - let result = { - err: "", - data: "" - } - try { - // 读取文件内容 - // if (!fs.existsSync(path)){ - // path = path.replace("\\Ori\\", "\\Thumb\\"); - // } - try { - await checkFileReceived(path, 5000); - } catch (e: any) { - result.err = e.toString(); - return result; - } - const data = await readFile(path); - // 转换为Base64编码 - result.data = data.toString('base64'); - } catch (err) { - result.err = err.toString(); - } - return result; -} - - -// 在保证老对象已有的属性不变化的情况下将新对象的属性复制到老对象 -export function mergeNewProperties(newObj: any, oldObj: any) { - Object.keys(newObj).forEach(key => { - // 如果老对象不存在当前属性,则直接复制 - if (!oldObj.hasOwnProperty(key)) { - oldObj[key] = newObj[key]; - } else { - // 如果老对象和新对象的当前属性都是对象,则递归合并 - if (typeof oldObj[key] === 'object' && typeof newObj[key] === 'object') { - mergeNewProperties(newObj[key], oldObj[key]); - } else if (typeof oldObj[key] === 'object' || typeof newObj[key] === 'object') { - // 属性冲突,有一方不是对象,直接覆盖 - oldObj[key] = newObj[key]; - } - } - }); -} - -export function checkFfmpeg(newPath: string = null): Promise { - return new Promise((resolve, reject) => { - if (newPath) { - ffmpeg.setFfmpegPath(newPath); - 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); - } - }) - } - }); -} - -export async function encodeSilk(filePath: string) { - const fsp = require("fs").promises - - function getFileHeader(filePath: string) { - // 定义要读取的字节数 - const bytesToRead = 7; - try { - const buffer = fs.readFileSync(filePath, { - encoding: null, - flag: "r", - }); - - const fileHeader = buffer.toString("hex", 0, bytesToRead); - return fileHeader; - } catch (err) { - console.error("读取文件错误:", err); - return; - } - } - - async function isWavFile(filePath: string) { - return isWav(fs.readFileSync(filePath)); - } - - // async function getAudioSampleRate(filePath: string) { - // try { - // const mm = await import('music-metadata'); - // const metadata = await mm.parseFile(filePath); - // log(`${filePath}采样率`, metadata.format.sampleRate); - // return metadata.format.sampleRate; - // } catch (error) { - // log(`${filePath}采样率获取失败`, error.stack); - // // console.error(error); - // } - // } - - try { - const fileName = path.basename(filePath); - const pttPath = path.join(DATA_DIR, uuidv4()); - if (getFileHeader(filePath) !== "02232153494c4b") { - log(`语音文件${filePath}需要转换成silk`) - const _isWav = await isWavFile(filePath); - const wavPath = pttPath + ".wav" - if (!_isWav) { - log(`语音文件${filePath}正在转换成wav`) - // let voiceData = await fsp.readFile(filePath) - await new Promise((resolve, reject) => { - const ffmpegPath = getConfigUtil().getConfig().ffmpeg; - if (ffmpegPath) { - ffmpeg.setFfmpegPath(ffmpegPath); - } - ffmpeg(filePath).toFormat("wav").audioChannels(2).on('end', function () { - log('wav转换完成'); - }) - .on('error', function (err) { - log(`wav转换出错: `, err.message,); - reject(err); - }) - .save(wavPath) - .on("end", () => { - filePath = wavPath - resolve(wavPath); - }); - }) - } - // const sampleRate = await getAudioSampleRate(filePath) || 0; - // log("音频采样率", sampleRate) - const pcm = fs.readFileSync(filePath); - const silk = await encode(pcm, 0); - fs.writeFileSync(pttPath, silk.data); - fs.unlink(wavPath, (err) => { }); - log(`语音文件${filePath}转换成功!`, pttPath) - return { - converted: true, - path: pttPath, - duration: silk.duration, - }; - } else { - const pcm = fs.readFileSync(filePath); - let duration = 0; - try { - duration = getDuration(pcm); - } catch (e) { - log("获取语音文件时长失败", filePath, e.stack) - duration = fs.statSync(filePath).size / 1024 / 3 // 每3kb大约1s - duration = Math.floor(duration) - duration = Math.max(1, duration) - log("使用文件大小估算时长", duration) - } - - return { - converted: false, - path: filePath, - duration: duration, - }; - } - } catch (error) { - log("convert silk failed", error.stack); - return {}; - } -} - -export async function getVideoInfo(filePath: string) { - const size = fs.statSync(filePath).size; - return new Promise<{ width: number, height: number, time: number, format: string, size: number, filePath: string }>((resolve, reject) => { - ffmpeg(filePath).ffprobe( (err, metadata) => { - if (err) { - reject(err); - } else { - const videoStream = metadata.streams.find(s => s.codec_type === 'video'); - if (videoStream) { - console.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); - } else { - console.log('未找到视频流信息。'); - } - resolve({ - width: videoStream.width, height: videoStream.height, - time: parseInt(videoStream.duration), - format: metadata.format.format_name, - size, - filePath - }); - } - }); - }) -} - - -export async function encodeMp4(filePath: string) { - let videoInfo = await getVideoInfo(filePath); - log("视频信息", videoInfo) - if (videoInfo.format.indexOf("mp4") === -1) { - log("视频需要转换为MP4格式", filePath) - // 转成mp4 - const newPath: string = await new Promise((resolve, reject) => { - const newPath = filePath + ".mp4" - ffmpeg(filePath) - .toFormat('mp4') - .on('error', (err) => { - reject(`转换视频格式失败: ${err.message}`); - }) - .on('end', () => { - log('视频转换为MP4格式完成'); - resolve(newPath); // 返回转换后的文件路径 - }) - .save(newPath); - }); - return await getVideoInfo(newPath) - } - return videoInfo -} - -export function isNull(value: any) { - return value === undefined || value === null; -} - - -export function calculateFileMD5(filePath: string): Promise { - return new Promise((resolve, reject) => { - // 创建一个流式读取器 - const stream = fs.createReadStream(filePath); - const hash = crypto.createHash('md5'); - - stream.on('data', (data: Buffer) => { - // 当读取到数据时,更新哈希对象的状态 - hash.update(data); - }); - - stream.on('end', () => { - // 文件读取完成,计算哈希 - const md5 = hash.digest('hex'); - resolve(md5); - }); - - stream.on('error', (err: Error) => { - // 处理可能的读取错误 - reject(err); - }); - }); -} diff --git a/src/common/utils/log.ts b/src/common/utils/log.ts new file mode 100644 index 0000000..f6887bb --- /dev/null +++ b/src/common/utils/log.ts @@ -0,0 +1,34 @@ +import {selfInfo} from "../data"; +import fs from "fs"; +import path from "node:path"; +import {DATA_DIR} from "./index"; +import {getConfigUtil} from "../config"; + +export function log(...msg: any[]) { + if (!getConfigUtil().getConfig().log) { + return //console.log(...msg); + } + let currentDateTime = new Date().toLocaleString(); + const date = new Date(); + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const day = date.getDate(); + const currentDate = `${year}-${month}-${day}`; + const userInfo = selfInfo.uin ? `${selfInfo.nick}(${selfInfo.uin})` : "" + let logMsg = ""; + for (let msgItem of msg) { + // 判断是否是对象 + if (typeof msgItem === "object") { + let obj = JSON.parse(JSON.stringify(msgItem)); + logMsg += JSON.stringify(truncateString(obj)) + " "; + continue; + } + logMsg += msgItem + " "; + } + logMsg = `${currentDateTime} ${userInfo}: ${logMsg}\n\n` + // sendLog(...msg); + // console.log(msg) + fs.appendFile(path.join(DATA_DIR, `llonebot-${currentDate}.log`), logMsg, (err: any) => { + + }) +} \ No newline at end of file diff --git a/src/main/main.ts b/src/main/main.ts index dddd8ee..15da2d2 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -13,7 +13,7 @@ import { CHANNEL_UPDATE, } from "../common/channels"; import {ob11WebsocketServer} from "../onebot11/server/ws/WebsocketServer"; -import {checkFfmpeg, DATA_DIR, getConfigUtil, log} from "../common/utils"; +import {DATA_DIR} from "../common/utils"; import { friendRequests, getFriend, @@ -42,6 +42,9 @@ import {NTQQGroupApi} from "../ntqqapi/api/group"; import {registerPokeHandler} from "../ntqqapi/external/ccpoke"; import {OB11FriendPokeEvent, OB11GroupPokeEvent} from "../onebot11/event/notice/OB11PokeEvent"; import {checkVersion, updateLLOneBot} from "../common/utils/update"; +import {checkFfmpeg} from "../common/utils/file"; +import {log} from "../common/utils/log"; +import {getConfigUtil} from "../common/config"; let running = false; diff --git a/src/main/setConfig.ts b/src/main/setConfig.ts index 45f0006..eb72ede 100644 --- a/src/main/setConfig.ts +++ b/src/main/setConfig.ts @@ -1,9 +1,10 @@ import {Config} from "../common/types"; -import {checkFfmpeg, getConfigUtil} from "../common/utils"; import {ob11HTTPServer} from "../onebot11/server/http"; import {ob11WebsocketServer} from "../onebot11/server/ws/WebsocketServer"; import {ob11ReverseWebsockets} from "../onebot11/server/ws/ReverseWebsocket"; import {llonebotError} from "../common/data"; +import {checkFfmpeg} from "../common/utils/file"; +import {getConfigUtil} from "../common/config"; export async function setConfig(config: Config) { let oldConfig = getConfigUtil().getConfig(); diff --git a/src/ntqqapi/api/file.ts b/src/ntqqapi/api/file.ts index 1f1e811..cdd6335 100644 --- a/src/ntqqapi/api/file.ts +++ b/src/ntqqapi/api/file.ts @@ -9,9 +9,9 @@ import { ElementType } from "../types"; import path from "path"; -import {log} from "../../common/utils"; import fs from "fs"; import {ReceiveCmdS} from "../hook"; +import {log} from "../../common/utils/log"; export class NTQQFileApi{ static async getFileType(filePath: string) { diff --git a/src/ntqqapi/api/group.ts b/src/ntqqapi/api/group.ts index c7a63f6..aa30069 100644 --- a/src/ntqqapi/api/group.ts +++ b/src/ntqqapi/api/group.ts @@ -2,9 +2,9 @@ import {ReceiveCmdS} from "../hook"; import {Group, GroupMember, GroupMemberRole, GroupNotifies, GroupNotify, GroupRequestOperateTypes} from "../types"; import {callNTQQApi, GeneralCallResult, NTQQApiClass, NTQQApiMethod} from "../ntcall"; import {uidMaps} from "../../common/data"; -import {log} from "../../common/utils"; import {BrowserWindow} from "electron"; import {dbUtil} from "../../common/db"; +import {log} from "../../common/utils/log"; export class NTQQGroupApi{ static async getGroups(forced = false) { diff --git a/src/ntqqapi/api/msg.ts b/src/ntqqapi/api/msg.ts index ad5e0e1..bfca2be 100644 --- a/src/ntqqapi/api/msg.ts +++ b/src/ntqqapi/api/msg.ts @@ -1,9 +1,10 @@ import {callNTQQApi, GeneralCallResult, NTQQApiMethod} from "../ntcall"; import {ChatType, RawMessage, SendMessageElement} from "../types"; -import {log, sleep} from "../../common/utils"; import {dbUtil} from "../../common/db"; import {selfInfo} from "../../common/data"; import {ReceiveCmdS, registerReceiveHook} from "../hook"; +import {log} from "../../common/utils/log"; +import {sleep} from "../../common/utils/helper"; export let sendMessagePool: Record void) | null> = {}// peerUid: callbackFunnc diff --git a/src/ntqqapi/constructor.ts b/src/ntqqapi/constructor.ts index af6fea1..679f173 100644 --- a/src/ntqqapi/constructor.ts +++ b/src/ntqqapi/constructor.ts @@ -11,10 +11,12 @@ import { SendTextElement, SendVideoElement } from "./types"; -import {calculateFileMD5, encodeSilk, getVideoInfo, isGIF, log, sleep} from "../common/utils"; import {promises as fs} from "node:fs"; import ffmpeg from "fluent-ffmpeg" import {NTQQFileApi} from "./api/file"; +import {calculateFileMD5, encodeSilk, getVideoInfo, isGIF} from "../common/utils/file"; +import {log} from "../common/utils/log"; +import {sleep} from "../common/utils/helper"; export class SendMsgElementConstructor { diff --git a/src/ntqqapi/external/ccpoke/index.ts b/src/ntqqapi/external/ccpoke/index.ts index 22f82d1..011b17c 100644 --- a/src/ntqqapi/external/ccpoke/index.ts +++ b/src/ntqqapi/external/ccpoke/index.ts @@ -1,4 +1,4 @@ -import {log} from "../../../common/utils"; +import {log} from "../../../common/utils/log"; let pokeEngine: any = null diff --git a/src/ntqqapi/hook.ts b/src/ntqqapi/hook.ts index 574adea..8d403b5 100644 --- a/src/ntqqapi/hook.ts +++ b/src/ntqqapi/hook.ts @@ -1,16 +1,17 @@ import {BrowserWindow} from 'electron'; -import {getConfigUtil, log, sleep} from "../common/utils"; import {NTQQApiClass} from "./ntcall"; import {NTQQMsgApi, sendMessagePool} from "./api/msg" import {ChatType, Group, RawMessage, User} from "./types"; -import {friends, groups, receivedTempUinMap, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data"; +import {friends, groups, selfInfo, tempGroupCodeMap, uidMaps} from "../common/data"; import {OB11GroupDecreaseEvent} from "../onebot11/event/notice/OB11GroupDecreaseEvent"; import {v4 as uuidv4} from "uuid" import {postOB11Event} from "../onebot11/server/postOB11Event"; -import {HOOK_LOG} from "../common/config"; +import {getConfigUtil, HOOK_LOG} from "../common/config"; import fs from "fs"; import {dbUtil} from "../common/db"; import {NTQQGroupApi} from "./api/group"; +import {log} from "../common/utils/log"; +import {sleep} from "../common/utils/helper"; export let hookApiCallbacks: Record void> = {} diff --git a/src/ntqqapi/ntcall.ts b/src/ntqqapi/ntcall.ts index 98bc0c3..20c35c6 100644 --- a/src/ntqqapi/ntcall.ts +++ b/src/ntqqapi/ntcall.ts @@ -1,8 +1,8 @@ import {ipcMain} from "electron"; import {hookApiCallbacks, ReceiveCmd, registerReceiveHook, removeReceiveHook} from "./hook"; -import {log} from "../common/utils"; import {v4 as uuidv4} from "uuid" +import {log} from "../common/utils/log"; export enum NTQQApiClass { NT_API = "ns-ntApi", diff --git a/src/onebot11/action/BaseAction.ts b/src/onebot11/action/BaseAction.ts index 05ab409..b33124e 100644 --- a/src/onebot11/action/BaseAction.ts +++ b/src/onebot11/action/BaseAction.ts @@ -1,7 +1,8 @@ import {ActionName, BaseCheckResult} from "./types" import {OB11Response} from "./utils" import {OB11Return} from "../types"; -import {log} from "../../common/utils"; + +import {log} from "../../common/utils/log"; class BaseAction { actionName: ActionName diff --git a/src/onebot11/action/Debug.ts b/src/onebot11/action/Debug.ts index bc82d76..e3064d6 100644 --- a/src/onebot11/action/Debug.ts +++ b/src/onebot11/action/Debug.ts @@ -1,7 +1,8 @@ import BaseAction from "./BaseAction"; import {NTQQApi} from "../../ntqqapi/ntcall"; import {ActionName} from "./types"; -import {log} from "../../common/utils"; + +import {log} from "../../common/utils/log"; interface Payload { method: string, diff --git a/src/onebot11/action/GetFile.ts b/src/onebot11/action/GetFile.ts index e0a5410..ace5163 100644 --- a/src/onebot11/action/GetFile.ts +++ b/src/onebot11/action/GetFile.ts @@ -1,7 +1,7 @@ import BaseAction from "./BaseAction"; -import {getConfigUtil} from "../../common/utils"; import fs from "fs/promises"; import {dbUtil} from "../../common/db"; +import {getConfigUtil} from "../../common/config"; export interface GetFilePayload { file: string // 文件名 diff --git a/src/onebot11/action/GetGroupMemberInfo.ts b/src/onebot11/action/GetGroupMemberInfo.ts index a4bcfda..85cc99c 100644 --- a/src/onebot11/action/GetGroupMemberInfo.ts +++ b/src/onebot11/action/GetGroupMemberInfo.ts @@ -4,7 +4,8 @@ import {OB11Constructor} from "../constructor"; import BaseAction from "./BaseAction"; import {ActionName} from "./types"; import {NTQQUserApi} from "../../ntqqapi/api/user"; -import {isNull, log} from "../../common/utils"; +import {log} from "../../common/utils/log"; +import {isNull} from "../../common/utils/helper"; export interface PayloadType { diff --git a/src/onebot11/action/SendGroupMsg.ts b/src/onebot11/action/SendGroupMsg.ts index 9f6e274..7c73191 100644 --- a/src/onebot11/action/SendGroupMsg.ts +++ b/src/onebot11/action/SendGroupMsg.ts @@ -1,7 +1,8 @@ import SendMsg from "./SendMsg"; import {ActionName, BaseCheckResult} from "./types"; import {OB11PostSendMsg} from "../types"; -import {log} from "../../common/utils"; + +import {log} from "../../common/utils/log"; class SendGroupMsg extends SendMsg { diff --git a/src/onebot11/action/SendLike.ts b/src/onebot11/action/SendLike.ts index 66e1bcb..d1b4bbd 100644 --- a/src/onebot11/action/SendLike.ts +++ b/src/onebot11/action/SendLike.ts @@ -1,8 +1,8 @@ import BaseAction from "./BaseAction"; import {getFriend, getUidByUin, uidMaps} from "../../common/data"; import {ActionName} from "./types"; -import {log} from "../../common/utils"; import {NTQQFriendApi} from "../../ntqqapi/api/friend"; +import {log} from "../../common/utils/log"; interface Payload { user_id: number, diff --git a/src/onebot11/action/SendMsg.ts b/src/onebot11/action/SendMsg.ts index 52145f3..b7eb2fa 100644 --- a/src/onebot11/action/SendMsg.ts +++ b/src/onebot11/action/SendMsg.ts @@ -29,11 +29,12 @@ import {uri2local} from "../utils"; import BaseAction from "./BaseAction"; import {ActionName, BaseCheckResult} from "./types"; import * as fs from "node:fs"; -import {log, sleep} from "../../common/utils"; import {decodeCQCode} from "../cqcode"; import {dbUtil} from "../../common/db"; import {ALLOW_SEND_TEMP_MSG} from "../../common/config"; import {NTQQMsgApi} from "../../ntqqapi/api/msg"; +import {log} from "../../common/utils/log"; +import {sleep} from "../../common/utils/helper"; function checkSendMessage(sendMsgList: OB11MessageData[]) { function checkUri(uri: string): boolean { diff --git a/src/onebot11/action/SetGroupLeave.ts b/src/onebot11/action/SetGroupLeave.ts index b623d35..27bcde1 100644 --- a/src/onebot11/action/SetGroupLeave.ts +++ b/src/onebot11/action/SetGroupLeave.ts @@ -1,7 +1,7 @@ import BaseAction from "./BaseAction"; -import {log} from "../../common/utils"; import {ActionName} from "./types"; import {NTQQGroupApi} from "../../ntqqapi/api/group"; +import {log} from "../../common/utils/log"; interface Payload { group_id: number, diff --git a/src/onebot11/action/llonebot/Config.ts b/src/onebot11/action/llonebot/Config.ts index 60fea1c..64bd7f9 100644 --- a/src/onebot11/action/llonebot/Config.ts +++ b/src/onebot11/action/llonebot/Config.ts @@ -1,8 +1,8 @@ import BaseAction from "../BaseAction"; import {Config} from "../../../common/types"; -import {getConfigUtil} from "../../../common/utils"; import {ActionName} from "../types"; import {setConfig} from "../../../main/setConfig"; +import {getConfigUtil} from "../../../common/config"; export class GetConfigAction extends BaseAction { diff --git a/src/onebot11/action/llonebot/GetGroupAddRequest.ts b/src/onebot11/action/llonebot/GetGroupAddRequest.ts index 40d534c..219e5c5 100644 --- a/src/onebot11/action/llonebot/GetGroupAddRequest.ts +++ b/src/onebot11/action/llonebot/GetGroupAddRequest.ts @@ -2,9 +2,9 @@ import {GroupNotify, GroupNotifyStatus} from "../../../ntqqapi/types"; import BaseAction from "../BaseAction"; import {ActionName} from "../types"; import {uidMaps} from "../../../common/data"; -import {log} from "../../../common/utils"; import {NTQQUserApi} from "../../../ntqqapi/api/user"; import {NTQQGroupApi} from "../../../ntqqapi/api/group"; +import {log} from "../../../common/utils/log"; interface OB11GroupRequestNotify { group_id: number, diff --git a/src/onebot11/action/llonebot/SetQQAvatar.ts b/src/onebot11/action/llonebot/SetQQAvatar.ts index fd02df6..7ea4785 100644 --- a/src/onebot11/action/llonebot/SetQQAvatar.ts +++ b/src/onebot11/action/llonebot/SetQQAvatar.ts @@ -2,8 +2,8 @@ import BaseAction from "../BaseAction"; import {ActionName} from "../types"; import { uri2local } from "../../utils"; import * as fs from "node:fs"; -import { checkFileReceived } from "../../../common/utils"; import {NTQQUserApi} from "../../../ntqqapi/api/user"; +import {checkFileReceived} from "../../../common/utils/file"; // import { log } from "../../../common/utils"; interface Payload { diff --git a/src/onebot11/action/utils.ts b/src/onebot11/action/utils.ts index 3f4e590..0611829 100644 --- a/src/onebot11/action/utils.ts +++ b/src/onebot11/action/utils.ts @@ -1,5 +1,6 @@ import {OB11Return} from '../types'; -import {isNull} from '../../common/utils'; + +import {isNull} from "../../common/utils/helper"; export class OB11Response { static res(data: T, status: string, retcode: number, message: string = ""): OB11Return { diff --git a/src/onebot11/constructor.ts b/src/onebot11/constructor.ts index 760381f..a9e258f 100644 --- a/src/onebot11/constructor.ts +++ b/src/onebot11/constructor.ts @@ -21,7 +21,6 @@ import { User } from '../ntqqapi/types'; import {getFriend, getGroupMember, selfInfo, tempGroupCodeMap} from '../common/data'; -import {getConfigUtil, log, sleep} from "../common/utils"; import {EventType} from "./event/OB11BaseEvent"; import {encodeCQCode} from "./cqcode"; import {dbUtil} from "../common/db"; @@ -32,6 +31,9 @@ import {OB11GroupNoticeEvent} from "./event/notice/OB11GroupNoticeEvent"; import {NTQQUserApi} from "../ntqqapi/api/user"; import {NTQQFileApi} from "../ntqqapi/api/file"; import {calcQQLevel} from "../common/utils/qqlevel"; +import {log} from "../common/utils/log"; +import {sleep} from "../common/utils/helper"; +import {getConfigUtil} from "../common/config"; export class OB11Constructor { diff --git a/src/onebot11/server/http.ts b/src/onebot11/server/http.ts index 31cfff8..e1a9bdc 100644 --- a/src/onebot11/server/http.ts +++ b/src/onebot11/server/http.ts @@ -1,8 +1,8 @@ import {Response} from "express"; -import {getConfigUtil} from "../../common/utils"; import {OB11Response} from "../action/utils"; import {HttpServerBase} from "../../common/server/http"; import {actionHandlers} from "../action"; +import {getConfigUtil} from "../../common/config"; class OB11HTTPServer extends HttpServerBase { name = "OneBot V11 server" diff --git a/src/onebot11/server/postOB11Event.ts b/src/onebot11/server/postOB11Event.ts index 5473279..62ce555 100644 --- a/src/onebot11/server/postOB11Event.ts +++ b/src/onebot11/server/postOB11Event.ts @@ -1,10 +1,11 @@ -import {getConfigUtil, log} from "../../common/utils"; import {OB11Message} from "../types"; import {selfInfo} from "../../common/data"; import {OB11BaseMetaEvent} from "../event/meta/OB11BaseMetaEvent"; import {OB11BaseNoticeEvent} from "../event/notice/OB11BaseNoticeEvent"; import {WebSocket as WebSocketClass} from "ws"; import {wsReply} from "./ws/reply"; +import {log} from "../../common/utils/log"; +import {getConfigUtil} from "../../common/config"; export type PostEventType = OB11Message | OB11BaseMetaEvent | OB11BaseNoticeEvent diff --git a/src/onebot11/server/ws/ReverseWebsocket.ts b/src/onebot11/server/ws/ReverseWebsocket.ts index 0f5da84..c158c08 100644 --- a/src/onebot11/server/ws/ReverseWebsocket.ts +++ b/src/onebot11/server/ws/ReverseWebsocket.ts @@ -1,6 +1,3 @@ -import {getConfigUtil, log} from "../../../common/utils"; - - import {selfInfo} from "../../../common/data"; import {LifeCycleSubType, OB11LifeCycleEvent} from "../../event/meta/OB11LifeCycleEvent"; import {ActionName} from "../../action/types"; @@ -11,6 +8,8 @@ import {postWsEvent, registerWsEventSender, unregisterWsEventSender} from "../po import {wsReply} from "./reply"; import {WebSocket as WebSocketClass} from "ws"; import {OB11HeartbeatEvent} from "../../event/meta/OB11HeartbeatEvent"; +import {log} from "../../../common/utils/log"; +import {getConfigUtil} from "../../../common/config"; export let rwsList: ReverseWebsocket[] = []; diff --git a/src/onebot11/server/ws/WebsocketServer.ts b/src/onebot11/server/ws/WebsocketServer.ts index dc85fed..fc414f0 100644 --- a/src/onebot11/server/ws/WebsocketServer.ts +++ b/src/onebot11/server/ws/WebsocketServer.ts @@ -1,5 +1,4 @@ import {WebSocket} from "ws"; -import {getConfigUtil, log} from "../../../common/utils"; import {actionMap} from "../../action"; import {OB11Response} from "../../action/utils"; import {postWsEvent, registerWsEventSender, unregisterWsEventSender} from "../postOB11Event"; @@ -11,6 +10,8 @@ import {WebsocketServerBase} from "../../../common/server/websocket"; import {IncomingMessage} from "node:http"; import {wsReply} from "./reply"; import {selfInfo} from "../../../common/data"; +import {log} from "../../../common/utils/log"; +import {getConfigUtil} from "../../../common/config"; let heartbeatRunning = false; diff --git a/src/onebot11/server/ws/reply.ts b/src/onebot11/server/ws/reply.ts index 9373156..d0b910d 100644 --- a/src/onebot11/server/ws/reply.ts +++ b/src/onebot11/server/ws/reply.ts @@ -1,7 +1,8 @@ import {WebSocket as WebSocketClass} from "ws"; import {OB11Response} from "../../action/utils"; import {PostEventType} from "../postOB11Event"; -import {isNull, log} from "../../../common/utils"; +import {log} from "../../../common/utils/log"; +import {isNull} from "../../../common/utils/helper"; export function wsReply(wsClient: WebSocketClass, data: OB11Response | PostEventType) { try { diff --git a/src/onebot11/utils.ts b/src/onebot11/utils.ts index 040565d..d60b258 100644 --- a/src/onebot11/utils.ts +++ b/src/onebot11/utils.ts @@ -1,8 +1,10 @@ -import {DATA_DIR, isGIF, log} from "../common/utils"; +import {DATA_DIR} from "../common/utils"; import {v4 as uuidv4} from "uuid"; import * as path from 'node:path'; import * as fileType from 'file-type'; import {dbUtil} from "../common/db"; +import {isGIF} from "../common/utils/file"; +import {log} from "../common/utils/log"; const fs = require("fs").promises;