diff --git a/plugins/system b/plugins/system new file mode 160000 index 0000000..c052a84 --- /dev/null +++ b/plugins/system @@ -0,0 +1 @@ +Subproject commit c052a84f274b4ed9fd924afd682a359ec4fde2f2 diff --git a/renderers/puppeteer/index.ts b/renderers/puppeteer/index.ts index d392524..8c8b1b8 100644 --- a/renderers/puppeteer/index.ts +++ b/renderers/puppeteer/index.ts @@ -1,13 +1,18 @@ +import { PuppeteerLaunchOptions } from 'puppeteer'; import Puppeteer from './lib/puppeteer.js' /** * - * @param config 本地config.yaml的配置内容 + * @param config * @returns renderer 渲染器对象 * @returns renderer.id 渲染器ID,对应renderer中选择的id * @returns renderer.type 渲染类型,保留字段,暂时支持image * @returns renderer.render 渲染入口 */ -export default function (config) { +export default function (config?: PuppeteerLaunchOptions & { + chromiumPath: string; + puppeteerWS: any; + puppeteerTimeout: any; +}) { // TODO Puppeteer待简化重构 return new Puppeteer(config) } \ No newline at end of file diff --git a/src/config/config.ts b/src/config/config.ts index 63cc151..3fd623f 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -4,6 +4,22 @@ import { join } from 'node:path' import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync } from 'node:fs' import { CONFIG_DEFAULT_PATH, CONFIG_INIT_PATH } from './system.js' +export function configInit() { + const path = CONFIG_INIT_PATH + const pathDef = CONFIG_DEFAULT_PATH + const files = readdirSync(pathDef).filter(file => file.endsWith('.yaml')) + mkdirSync(join(process.cwd(), path), { + 'recursive': true + }) + for (let file of files) { + if (!existsSync(`${path}${file}`)) { + copyFileSync(`${pathDef}${file}`, `${path}${file}`) + } + } + if (!existsSync("data")) mkdirSync("data") + if (!existsSync("resources")) mkdirSync("resources") +} + /** * ******** * 配置文件 @@ -21,30 +37,6 @@ class ConfigController { */ watcher = { config: {}, defSet: {} } - /** - * - */ - constructor() { - this.initCfg() - } - - - /** - * 初始化配置 - */ - initCfg() { - const path = CONFIG_INIT_PATH - const pathDef = CONFIG_DEFAULT_PATH - const files = readdirSync(pathDef).filter(file => file.endsWith('.yaml')) - for (let file of files) { - if (!existsSync(`${path}${file}`)) { - copyFileSync(`${pathDef}${file}`, `${path}${file}`) - } - } - if (!existsSync("data")) mkdirSync("data") - if (!existsSync("resources")) mkdirSync("resources") - } - /** * 机器人qq号 */ @@ -238,8 +230,7 @@ class ConfigController { * 修改日志等级 */ async change_bot() { - const { setLogger } = await import('./log.js') - setLogger && setLogger() + // } } diff --git a/src/config/log.ts b/src/config/log.ts index 68ace94..ce66d96 100644 --- a/src/config/log.ts +++ b/src/config/log.ts @@ -1,8 +1,7 @@ import log4js from 'log4js' import chalk from 'chalk' import cfg from './config.js' -import fs from 'node:fs' - +import { mkdirSync } from 'node:fs' /** * 创建日志 @@ -86,27 +85,18 @@ function createLog() { /** * 设置日志样式 */ -export function setLogger() { - +export function loggerInit() { /** * */ - let file = './logs' - - /** - * - */ - if (!fs.existsSync(file)) { - fs.mkdirSync(file, { - 'recursive': true - }) - } + mkdirSync('./logs', { + 'recursive': true + }) /** * 全局变量 logger */ global.logger = createLog() as any - logger.chalk = chalk logger.red = chalk.red logger.green = chalk.green diff --git a/src/core/events/message.ts b/src/core/events/message.ts index 6687d2b..dea260d 100644 --- a/src/core/events/message.ts +++ b/src/core/events/message.ts @@ -11,7 +11,7 @@ export default class messageEvent extends EventListener { /** * */ - super({ event: 'message', prefix: undefined, once: undefined }) + super({ event: 'message' }) } /** diff --git a/src/core/events/notice.ts b/src/core/events/notice.ts index a2076b7..1cd2b3f 100644 --- a/src/core/events/notice.ts +++ b/src/core/events/notice.ts @@ -11,7 +11,7 @@ export default class noticeEvent extends EventListener { /** * */ - super({ event: 'notice', prefix: undefined, once: undefined }) + super({ event: 'notice' }) } /** diff --git a/src/core/events/offline.ts b/src/core/events/offline.ts index 219bfe9..9609ad1 100644 --- a/src/core/events/offline.ts +++ b/src/core/events/offline.ts @@ -14,7 +14,7 @@ export default class offlineEvent extends EventListener { /** * */ - super({ event: 'system.offline', prefix: undefined, once: undefined }) + super({ event: 'system.offline' }) } /** diff --git a/src/core/events/online.ts b/src/core/events/online.ts index a86bd8d..0698ee7 100644 --- a/src/core/events/online.ts +++ b/src/core/events/online.ts @@ -16,8 +16,7 @@ export default class onlineEvent extends EventListener { */ super({ event: 'system.online', - once: true, - prefix: undefined + once: true }) } diff --git a/src/core/events/request.ts b/src/core/events/request.ts index bb9c286..99d7792 100644 --- a/src/core/events/request.ts +++ b/src/core/events/request.ts @@ -11,7 +11,7 @@ export default class requestEvent extends EventListener { /** * */ - super({ event: 'request', prefix: undefined, once: undefined }) + super({ event: 'request' }) } /** diff --git a/src/core/listener.ts b/src/core/listener.ts index 2875368..430736c 100644 --- a/src/core/listener.ts +++ b/src/core/listener.ts @@ -29,7 +29,15 @@ export default class EventListener { * @param data.event 监听的事件 * @param data.once 是否只监听一次 */ - constructor({ prefix, event, once }) { + constructor({ + prefix, + event, + once + }: { + prefix?: string + event?: any + once?: any + }) { prefix && (this.prefix = prefix) once && (this.once = once) this.event = event diff --git a/src/core/plugins/common.ts b/src/core/plugins/common.ts index 49ea2d7..94697e9 100644 --- a/src/core/plugins/common.ts +++ b/src/core/plugins/common.ts @@ -10,9 +10,9 @@ * @param msg 消息 * @param uin 指定bot发送,默认为Bot */ -export async function relpyPrivate(userId, msg, uin = Bot.uin) { +export async function relpyPrivate(userId: number | string, msg, uin = Bot.uin) { userId = Number(userId) - let friend = Bot.fl.get(userId) + const friend = Bot.fl.get(userId) if (friend) { logger.mark(`发送好友消息[${friend.nickname}](${userId})`) return await Bot[uin] @@ -58,13 +58,13 @@ export async function makeForwardMsg( let forwardMsg: | { - user_id: number - nickname: string - message: any - }[] + user_id: number + nickname: string + message: any + }[] | { - data: any - } = [] + data: any + } = [] /** * diff --git a/src/core/plugins/types.ts b/src/core/plugins/types.ts index 8e93a61..01bbe84 100644 --- a/src/core/plugins/types.ts +++ b/src/core/plugins/types.ts @@ -6,6 +6,10 @@ interface EventTypeBase { * 是否是主人 */ isMaster: boolean; + /** + * 是否是管理员 + */ + // isAdmin: boolean; /** * 是否是群里 */ @@ -21,11 +25,9 @@ interface EventTypeBase { */ reply: (...arg: any[]) => Promise; /** - * @deprecated 已废弃 */ file: any; /** - * @deprecated 已废弃 */ bot: typeof Client.prototype; /** @@ -49,7 +51,11 @@ interface EventTypeGroup extends EventTypeBase, GroupMessage { */ group_id: number; /** - * @deprecated 已废弃 + * 群名 + */ + group_name:string + /** + * */ group: { is_owner: any; diff --git a/src/init.ts b/src/init.ts index 62eade9..f555f1a 100644 --- a/src/init.ts +++ b/src/init.ts @@ -1,124 +1,42 @@ -import fs, { promises } from 'node:fs' +import { existsSync } from 'fs' +import { join } from 'path' +import { configInit } from './config/config' +import { loggerInit } from './config/log' +import { BOT_NAME } from './config' +import { redisInit } from './config/redis' +import { promises } from 'node:fs' import yaml from 'yaml' -import { join } from 'node:path' -/** - * - */ -import { BOT_NAME, CONFIG_INIT_PATH } from './config/system.js' -import { createQQ } from './config/qq.js' -import { setLogger } from './config/log.js' -import { redisInit } from './config/redis.js' +import { CONFIG_INIT_PATH } from './config/system.js' import { checkRun } from './config/check.js' /** - * + * 检查node_modules */ -async function UpdateTitle() { - /** - * 添加一些多余的标题内容 - */ - let title = BOT_NAME - - // - const qq = await promises - .readFile(`./${CONFIG_INIT_PATH}qq.yaml`, 'utf-8') - .then(yaml.parse) - .catch(() => null) - - /** - * - */ - if (qq) { - title += `@${qq.qq || ''}` - switch (qq.platform) { - case 1: { - title += ' 安卓手机' - break - } - case 2: { - title += ' aPad' - break - } - case 3: { - title += ' 安卓手表' - break - } - case 4: { - title += ' MacOS' - break - } - case 5: { - title += ' iPad' - break - } - case 6: { - title += ' Tim' - break - } - default: { - break - } - } - } - - /** - * 设置标题 - */ - process.title = title +if (!existsSync(join(process.cwd(), './node_modules'))) { + console.log('未安装依赖。。。。') + console.log('请先运行命令:pnpm install -P 安装依赖') + process.exit() } /** - * 初始化事件 + * 初始化配置 */ -export async function checkInit() { - /** - * 检查node_modules - */ - if (!fs.existsSync(join(process.cwd(), './node_modules'))) { - console.log('未安装依赖。。。。') - console.log('请先运行命令:pnpm install -P 安装依赖') - process.exit() - } +configInit() - /** - * 检查node_modules/icqq - */ - if (!fs.existsSync(join(process.cwd(), './node_modules/icqq'))) { - console.log('未安装icqq。。。。') - console.log('请先运行命令:pnpm install -P 安装依赖') - process.exit() - } +/** + * 日志初始化 + */ +loggerInit() - /** - * 检查qq.yaml - */ - await createQQ() +/** + * + */ +logger.mark(`${BOT_NAME} 启动中...`) - /** - * 日志设置 - */ - setLogger() - - /** - * - */ - logger.mark(`${BOT_NAME} 启动中...`) - - /** - * 初始化客户端 - */ - await redisInit() - - /** - * 检查程序 - */ - await checkRun() - - /** - * 更新标题 - */ - await UpdateTitle() -} +/** + * 初始化客户端 + */ +await redisInit() /** * 设置标题 @@ -166,6 +84,58 @@ process.on('exit', async () => { }) /** - * 初始化 + * 添加一些多余的标题内容 */ -await checkInit() +let title = BOT_NAME + +// +const qq = await promises + .readFile(`./${CONFIG_INIT_PATH}qq.yaml`, 'utf-8') + .then(yaml.parse) + .catch(() => null) + +/** + * + */ +if (qq) { + title += `@${qq.qq || ''}` + switch (qq.platform) { + case 1: { + title += ' 安卓手机' + break + } + case 2: { + title += ' aPad' + break + } + case 3: { + title += ' 安卓手表' + break + } + case 4: { + title += ' MacOS' + break + } + case 5: { + title += ' iPad' + break + } + case 6: { + title += ' Tim' + break + } + default: { + break + } + } +} + +/** + * 设置标题 + */ +process.title = title + +/** + * 检查程序 + */ +await checkRun() diff --git a/src/main.ts b/src/main.ts index f18d4c4..c618de3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,14 +1,7 @@ -/** - * ********** - * 配置初始化 - * ********** - */ import './init.js' -/** - * 引入模块 - */ import { plugin, segment, Client } from './core/index.js' import { Renderer } from './utils/index.js' +import { createQQ } from './config/qq.js' /** * global.plugin */ @@ -22,6 +15,12 @@ global.segment = segment */ global.Renderer = Renderer /** - * run + * */ -await Client.run() +setTimeout(async () => { + await createQQ() + /** + * run + */ + await Client.run() +}, 0) diff --git a/src/utils/index.ts b/src/utils/index.ts index d86cfde..f30aeec 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -3,24 +3,16 @@ export * from './puppeteer.js' export * from './types.js' export * from './common.js' export * from './component.js' - /** - * 旧版本 + * 旧版本兼容性方法 */ import puppeteer from './puppeteer/puppeteer.js' export { puppeteer } - -/** - * ******** - * - * ********** - */ import renderer from './renderer/loader.js' import Renderer from './renderer/Renderer.js' import renderers from './renderers/index.js' import Renderers from './renderers/puppeteer.js' export { Renderers, renderers, Renderer, renderer } - /** * puppeteer/ * renderer/ diff --git a/src/utils/puppeteer/puppeteer.ts b/src/utils/puppeteer/puppeteer.ts index f57aa14..98add21 100644 --- a/src/utils/puppeteer/puppeteer.ts +++ b/src/utils/puppeteer/puppeteer.ts @@ -1,13 +1,16 @@ import Renderer from '../renderer/loader.js' +/** + * @deprecated 已废弃 + */ const renderer = Renderer.getRenderer() renderer.screenshot = async (name, data) => { - let img = await renderer.render(name, data) + const img = await renderer.render(name, data) return img ? segment.image(img) : img } renderer.screenshots = async (name, data) => { data.multiPage = true - let imgs = (await renderer.render(name, data)) || [] - let ret = [] + const imgs = (await renderer.render(name, data)) || [] + const ret = [] for (let img of imgs) { ret.push(img ? segment.image(img) : img) } diff --git a/src/utils/renderer/Renderer.ts b/src/utils/renderer/Renderer.ts index 2203bda..5f68d77 100644 --- a/src/utils/renderer/Renderer.ts +++ b/src/utils/renderer/Renderer.ts @@ -1,8 +1,12 @@ import template from 'art-template' import chokidar from 'chokidar' import path from 'node:path' -import fs from 'node:fs' +import fs, { writeFileSync } from 'node:fs' +/** + * + * @deprecated 已废弃 + */ export default class Renderer { id = null type = null @@ -10,14 +14,13 @@ export default class Renderer { dir = './temp/html' html = {} watcher = {} - /** * 渲染器 * @param data.id 渲染器ID * @param data.type 渲染器类型 * @param data.render 渲染器入口 */ - constructor(data) { + constructor(data?: { id?: any; type?: any; render?: any }) { /** 渲染器ID */ this.id = data.id || 'renderer' /** 渲染器类型 */ @@ -26,13 +29,12 @@ export default class Renderer { this.render = this[data.render || 'render'] this.createDir(this.dir) } - /** * 创建文件夹 * @param dirname * @returns */ - createDir(dirname) { + createDir(dirname: string) { if (fs.existsSync(dirname)) { return true } else { @@ -42,7 +44,6 @@ export default class Renderer { } } } - /** * 模板 * @param name @@ -50,8 +51,8 @@ export default class Renderer { * @returns */ dealTpl(name, data) { - let { tplFile, saveId = name } = data - let savePath = `./temp/html/${name}/${saveId}.html` + const { tplFile, saveId = name } = data + const savePath = `./temp/html/${name}/${saveId}.html` /** 读取html模板 */ if (!this.html[tplFile]) { this.createDir(`./temp/html/${name}`) @@ -63,18 +64,14 @@ export default class Renderer { } this.watch(tplFile) } - data.resPath = `./resources/` - /** 替换模板 */ - let tmpHtml = template.render(this.html[tplFile], data) - + const tmpHtml = template.render(this.html[tplFile], data) /** 保存模板 */ - fs.writeFileSync(savePath, tmpHtml) + writeFileSync(savePath, tmpHtml) logger.debug(`[图片生成][使用模板] ${savePath}`) return savePath } - /** * 监听配置文件 * @param tplFile diff --git a/src/utils/renderer/config.yaml b/src/utils/renderer/config.yaml deleted file mode 100644 index 8e27302..0000000 --- a/src/utils/renderer/config.yaml +++ /dev/null @@ -1,23 +0,0 @@ -# 如需自定义,复制此文件为 config.yaml 进行配置 -# 更新配置后需要重启 - -# chromium 地址,可填写系统的edge/chromium路径,例如(根据实际情况调整): -# chromiumPath: C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe -chromiumPath: - -# puppeteer websocket 地址。连接单独存在的 chromium。 -# puppeteerWS: 'ws://browserless:3000' -puppeteerWS: - -# headless -headless: 'new' - -# puppeteer启动args,注意args的--前缀 -args: - - --disable-gpu - - --disable-setuid-sandbox - - --no-sandbox - - --no-zygote - -# puppeteer截图超时时间 -puppeteerTimeout: diff --git a/src/utils/renderer/loader.ts b/src/utils/renderer/loader.ts index 30d3013..3ed012b 100644 --- a/src/utils/renderer/loader.ts +++ b/src/utils/renderer/loader.ts @@ -2,26 +2,25 @@ import fs from 'node:fs' import yaml from 'yaml' import lodash from 'lodash' import { ConfigController as cfg } from '../../config/index.js' +import { join } from 'node:path' /** * 加载渲染器 + * @deprecated 已废弃 */ class RendererLoader { /** * */ renderers = new Map() - /** * */ dir = './renderers' - /** * */ watcher = {} - /** * * @returns @@ -31,7 +30,6 @@ class RendererLoader { await render.load() return render } - /** * */ @@ -39,15 +37,20 @@ class RendererLoader { const subFolders = fs .readdirSync(this.dir, { withFileTypes: true }) .filter(dirent => dirent.isDirectory()) - for (let subFolder of subFolders) { - let name = subFolder.name + for (const subFolder of subFolders) { + const name = subFolder.name try { const rendererFn = await import('../renderers/index.js') - let configFile = `./config.yaml` - let rendererCfg = fs.existsSync(configFile) + const configFile = join( + process.cwd(), + 'config', + 'config', + 'puppeteer.yaml' + ) + const rendererCfg = fs.existsSync(configFile) ? yaml.parse(fs.readFileSync(configFile, 'utf8')) : {} - let renderer = rendererFn.default(rendererCfg) + const renderer = rendererFn.default(rendererCfg) if ( !renderer.id || !renderer.type || @@ -64,7 +67,6 @@ class RendererLoader { } } } - /** * * @param name @@ -74,10 +76,12 @@ class RendererLoader { // TODO 渲染器降级 return this.renderers.get(name) } - /** * */ } - +/** + * + * @deprecated 已废弃 + */ export default await RendererLoader.init() diff --git a/src/utils/renderers/index.ts b/src/utils/renderers/index.ts index dc10049..21e04ff 100644 --- a/src/utils/renderers/index.ts +++ b/src/utils/renderers/index.ts @@ -1,13 +1,19 @@ +import { PuppeteerLaunchOptions } from 'puppeteer'; import Puppeteer from './puppeteer.js' /** * - * @param config 本地config.yaml的配置内容 + * @deprecated 已废弃 + * @param config * @returns renderer 渲染器对象 * @returns renderer.id 渲染器ID,对应renderer中选择的id * @returns renderer.type 渲染类型,保留字段,暂时支持image * @returns renderer.render 渲染入口 */ -export default function (config) { +export default function (config?: PuppeteerLaunchOptions & { + chromiumPath: string; + puppeteerWS: any; + puppeteerTimeout: any; +}) { // TODO Puppeteer待简化重构 return new Puppeteer(config) } \ No newline at end of file diff --git a/src/utils/renderers/puppeteer.ts b/src/utils/renderers/puppeteer.ts index 4fc7d46..5c85a2e 100644 --- a/src/utils/renderers/puppeteer.ts +++ b/src/utils/renderers/puppeteer.ts @@ -1,15 +1,30 @@ -import Renderer from "../renderer/Renderer.js" import os from "node:os" import lodash from "lodash" -import puppeteer, { Browser } from "puppeteer" -// 暂时保留对原config的兼容 +import puppeteer, { Browser, PuppeteerLaunchOptions } from "puppeteer" +/** + * + */ +import Renderer from "../renderer/Renderer.js" +/** + * 暂时保留对原config的兼容 + */ import { ConfigController as cfg } from "../../config/index.js" +/** + * + */ const _path = process.cwd() -// mac地址 + +/** + * mac地址 + */ let mac = "" +/** + * + * @deprecated 已废弃 + */ export default class Puppeteer extends Renderer { browser: false | Browser = false lock = false @@ -27,7 +42,11 @@ export default class Puppeteer extends Renderer { * * @param config */ - constructor(config) { + constructor(config?: PuppeteerLaunchOptions & { + chromiumPath: string + puppeteerWS: any + puppeteerTimeout: any + }) { /** * */ @@ -182,16 +201,16 @@ export default class Puppeteer extends Renderer { * @param data.pageGotoParams 页面goto时的参数 * @return img 不做segment包裹 */ - async screenshot(name, data: any = {}) { + async screenshot(name:string, data: any = {}) { if (!await this.browserInit()) return false const pageHeight = data.multiPageHeight || 4000 - let savePath = this.dealTpl(name, data) + const savePath = this.dealTpl(name, data) if (!savePath) return false let buff: any = "" - let start = Date.now() + const start = Date.now() let ret = [] this.shoting.push(name) @@ -213,16 +232,16 @@ export default class Puppeteer extends Renderer { try { const page = await this.browser.newPage() - let pageGotoParams = lodash.extend({ timeout: 120000 }, data.pageGotoParams || {}) + const pageGotoParams = lodash.extend({ timeout: 120000 }, data.pageGotoParams || {}) await page.goto(`file://${_path}${lodash.trim(savePath, ".")}`, pageGotoParams) - let body = await page.$("#container") || await page.$("body") + const body = await page.$("#container") || await page.$("body") // 计算页面高度 const boundingBox = await body.boundingBox() // 分页数 let num = 1 - let randData = { + const randData = { type: data.imgType || "jpeg", omitBackground: data.omitBackground || false, quality: data.quality || 90, @@ -322,10 +341,10 @@ export default class Puppeteer extends Renderer { } /** - * + * 停止 * @param browser */ - async stop(browser) { + async stop(browser: Browser) { try { await browser.close() } catch (err) {