From 503942cc0d51b0d3910d867a4f65a939a399f024 Mon Sep 17 00:00:00 2001 From: ningmengchongshui <916415899@qq.com> Date: Fri, 14 Jun 2024 10:35:58 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E7=AE=80=E5=8C=96=E5=86=99=E6=B3=95+?= =?UTF-8?q?=E6=A0=87=E6=B3=A8=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/config.ts | 18 +-- src/config/index.ts | 13 +- src/core/bot.ts | 35 ++++-- src/core/events.loader.ts | 43 +++---- src/core/events.ts | 16 +-- src/core/events/login.ts | 3 +- src/core/events/message.ts | 2 +- src/core/events/notice.ts | 2 +- src/core/events/offline.ts | 2 +- src/core/events/online.ts | 2 +- src/core/events/request.ts | 3 +- src/core/icqq.ts | 3 +- src/core/index.ts | 1 - src/core/plugins.loader.ts | 242 +++++++++++++++++++++++++++---------- src/main.ts | 3 +- 15 files changed, 247 insertions(+), 141 deletions(-) diff --git a/src/config/config.ts b/src/config/config.ts index 3fd623f..25f4333 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -4,6 +4,9 @@ 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 @@ -11,7 +14,7 @@ export function configInit() { mkdirSync(join(process.cwd(), path), { 'recursive': true }) - for (let file of files) { + for (const file of files) { if (!existsSync(`${path}${file}`)) { copyFileSync(`${pathDef}${file}`, `${path}${file}`) } @@ -26,7 +29,6 @@ export function configInit() { * ******** */ class ConfigController { - /** * */ @@ -55,8 +57,8 @@ class ConfigController { * icqq配置 */ get bot() { - let bot = this.getConfig('bot') - let defbot = this.getdefSet('bot') + const bot = this.getConfig('bot') + const defbot = this.getdefSet('bot') const Config = { ...defbot, ...bot } Config.platform = this.getConfig('qq').platform /** @@ -182,16 +184,13 @@ class ConfigController { * @param name 名称 */ getYaml(type, name) { - let file = `config/${type}/${name}.yaml` - let key = `${type}.${name}` + const file = `config/${type}/${name}.yaml` + const key = `${type}.${name}` if (this.config[key]) return this.config[key] - this.config[key] = YAML.parse( readFileSync(file, 'utf8') ) - this.watch(file, name, type) - return this.config[key] } @@ -228,6 +227,7 @@ class ConfigController { /** * 修改日志等级 + * @deprecated 已废弃 */ async change_bot() { // diff --git a/src/config/index.ts b/src/config/index.ts index 4a8dae5..3a79adb 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,10 +1,3 @@ - -import config from './config.js' -/** - * 配置控制器 - */ -export const ConfigController = config -/** - * 系统性配置 - */ -export * from './system.js' \ No newline at end of file +export * from './system.js' +import ConfigController from './config.js' +export { ConfigController } \ No newline at end of file diff --git a/src/core/bot.ts b/src/core/bot.ts index 04cc095..f7f09b0 100644 --- a/src/core/bot.ts +++ b/src/core/bot.ts @@ -10,6 +10,10 @@ import cfg from '../config/config.js' * ********** */ import ListenerLoader from './events.loader.js' +/** + * + */ +import PluginsLoader from './plugins.loader.js' /** * 扩展 */ @@ -35,17 +39,26 @@ export class Client extends IcqqClient { */ static async run() { const bot = new Client(cfg.bot) - /** 加载监听事件 */ + + /** + * 加载监听事件 + */ await ListenerLoader.load(bot) - /** 跳过登录 */ + /** + * 跳过登录 + */ if (cfg.bot.skip_login) return await this.skip_login(bot) - /** 正常的登录 */ + /** + * 正常的登录 + */ await bot.login(cfg.qq, cfg.pwd) bot[bot.uin] = bot - /** 全局变量 bot */ + /** + * 全局变量 bot + */ global.Bot = bot return bot } @@ -58,10 +71,18 @@ export class Client extends IcqqClient { static async skip_login(bot) { bot.uin = 88888 bot[bot.uin] = bot - /** 全局变量 bot */ + /** + * 全局变量 bot + */ global.Bot = bot - /** 加载插件 */ - return await (await import('./plugins.loader.js')).default.load() + /** + * 加载插件 + */ + await PluginsLoader.load() + /** + * + */ + return } } diff --git a/src/core/events.loader.ts b/src/core/events.loader.ts index 0ac1933..ff7cd1b 100644 --- a/src/core/events.loader.ts +++ b/src/core/events.loader.ts @@ -1,36 +1,36 @@ +import { type Client } from 'icqq' import lodash from 'lodash' +import * as Events from './events.js' /** * 加载监听事件 */ class ListenerLoader { - client = null + /** + * + */ + client: Client = null /** * * @param listener - * @param File + * @param name * @returns */ - init = (listener, File: string) => { + init = (Listener, name: string) => { try { - if (!listener.default) return - /** * */ - listener = new listener.default() - + const listener = new Listener() /** * */ listener.client = this.client - /** * */ const on = listener.once ? 'once' : 'on' - if (lodash.isArray(listener.event)) { listener.event.forEach(type => { const e = listener[type] ? type : 'execute' @@ -42,9 +42,9 @@ class ListenerLoader { listener[e](event) ) } - } catch (e) { - logger.mark(`监听事件错误:${File}`) - logger.error(e) + } catch (err) { + logger.mark(`监听事件错误:${name}`) + logger.error(err) } } @@ -52,22 +52,11 @@ class ListenerLoader { * 监听事件加载 * @param client Bot示例 */ - async load(client) { + async load(client: Client) { this.client = client - - /** - * **************** - * 不可以加载未知代码 - * ***************** - * 防止被代码植入 - */ - - this.init(await import('./events/login.js'), './events/login.js') - this.init(await import('./events/message.js'), './events/message.js') - this.init(await import('./events/notice.js'), './events/notice.js') - this.init(await import('./events/offline.js'), './events/offline.js') - this.init(await import('./events/online.js'), './events/online.js') - this.init(await import('./events/request.js'), './events/request.js') + for (const key in Events) { + this.init(Events[key], key) + } } } diff --git a/src/core/events.ts b/src/core/events.ts index 1b8ffff..1eef745 100644 --- a/src/core/events.ts +++ b/src/core/events.ts @@ -1,10 +1,6 @@ -import EventLogin from './events/login' -import EventMessage from './events/message' -import EventNotice from './events/notice' -import EventOffine from './events/offline' -import EventOnline from './events/online' -export { EventLogin } -export { EventMessage } -export { EventNotice } -export { EventOffine } -export { EventOnline } +export { EventLogin } from './events/login' +export { EventMessage } from './events/message' +export { EventNotice } from './events/notice' +export { EventOffline } from './events/offline' +export { EventOnline } from './events/online' +export { EventRequest } from './events/request' diff --git a/src/core/events/login.ts b/src/core/events/login.ts index 9a782e5..bd5c5c7 100644 --- a/src/core/events/login.ts +++ b/src/core/events/login.ts @@ -3,7 +3,6 @@ import { sleep } from '../../utils/common.js' import inquirer from 'inquirer' import lodash from 'lodash' import fetch from 'node-fetch' - /** * 监听上线事件 */ @@ -12,7 +11,7 @@ let inSlider = false /** * */ -export default class loginEvent extends EventListener { +export class EventLogin extends EventListener { client = null /** diff --git a/src/core/events/message.ts b/src/core/events/message.ts index dea260d..1837e92 100644 --- a/src/core/events/message.ts +++ b/src/core/events/message.ts @@ -3,7 +3,7 @@ import EventListener from '../listener.js' /** * 监听群聊消息 */ -export default class messageEvent extends EventListener { +export class EventMessage extends EventListener { /** * */ diff --git a/src/core/events/notice.ts b/src/core/events/notice.ts index 1cd2b3f..2534fb7 100644 --- a/src/core/events/notice.ts +++ b/src/core/events/notice.ts @@ -3,7 +3,7 @@ import EventListener from '../listener.js' /** * 监听群聊消息 */ -export default class noticeEvent extends EventListener { +export class EventNotice extends EventListener { /** * */ diff --git a/src/core/events/offline.ts b/src/core/events/offline.ts index 9609ad1..fcf2ecd 100644 --- a/src/core/events/offline.ts +++ b/src/core/events/offline.ts @@ -6,7 +6,7 @@ import { BOT_NAME } from '../../config/system.js' /** * 监听下线事件 */ -export default class offlineEvent extends EventListener { +export class EventOffline extends EventListener { /** * */ diff --git a/src/core/events/online.ts b/src/core/events/online.ts index 0698ee7..3deabd9 100644 --- a/src/core/events/online.ts +++ b/src/core/events/online.ts @@ -6,7 +6,7 @@ import { BOT_NAME } from '../../config/system.js' /** * 监听上线事件 */ -export default class onlineEvent extends EventListener { +export class EventOnline extends EventListener { /** * */ diff --git a/src/core/events/request.ts b/src/core/events/request.ts index 99d7792..c229a6f 100644 --- a/src/core/events/request.ts +++ b/src/core/events/request.ts @@ -1,9 +1,8 @@ import EventListener from '../listener.js' - /** * 监听群聊消息 */ -export default class requestEvent extends EventListener { +export class EventRequest extends EventListener { /** * */ diff --git a/src/core/icqq.ts b/src/core/icqq.ts index 9136785..78e8edf 100644 --- a/src/core/icqq.ts +++ b/src/core/icqq.ts @@ -1,3 +1,2 @@ export { segment } from 'icqq' -import { segment } from 'icqq' -export const Segment = segment +export { segment as Segment } from 'icqq' diff --git a/src/core/index.ts b/src/core/index.ts index 5e79063..db5de50 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -3,5 +3,4 @@ export * from './plugins/functional.js' export * from './plugins/types.js' export * from './plugins/common.js' export * from './icqq.js' -export * from './events.js' export * from './bot.js' diff --git a/src/core/plugins.loader.ts b/src/core/plugins.loader.ts index 428d422..f7f230e 100644 --- a/src/core/plugins.loader.ts +++ b/src/core/plugins.loader.ts @@ -44,6 +44,21 @@ class PluginsLoader { */ watcher = {} + /** + * + */ + msgThrottle = {} + + /** + * + */ + pluginCount = null + + /** + * 星铁命令前缀 + */ + srReg = /^#?(\*|星铁|星轨|穹轨|星穹|崩铁|星穹铁道|崩坏星穹铁道|铁道)+/ + /** * */ @@ -62,13 +77,6 @@ class PluginsLoader { request: ['post_type', 'request_type', 'sub_type'] } - msgThrottle = {} - - /** - * 星铁命令前缀 - */ - srReg = /^#?(\*|星铁|星轨|穹轨|星穹|崩铁|星穹铁道|崩坏星穹铁道|铁道)+/ - /** * * @returns @@ -112,11 +120,6 @@ class PluginsLoader { return ret } - /** - * - */ - pluginCount = null - /** * 监听事件加载 * @param isRefresh 是否刷新 @@ -149,7 +152,7 @@ class PluginsLoader { } /** - * + * 引入插件 * @param file * @param packageErr */ @@ -175,33 +178,65 @@ class PluginsLoader { } /** - * + * 解析插件 * @param file * @param p * @returns */ async loadPlugin(file, p) { if (!p?.prototype) return + + /** + * + */ this.pluginCount++ + + /** + * + */ const plugin = new p() + + /** + * + */ logger.debug(`加载插件 [${file.name}][${plugin.name}]`) - /** 执行初始化,返回 return 则跳过加载 */ + + /** + * 执行初始化,返回 return 则跳过加载 + */ if (plugin.init && (await plugin.init()) == 'return') return - /** 初始化定时任务 */ + + /** + * 初始化定时任务 + */ this.collectTask(plugin.task) + + /** + * + */ this.priority.push({ class: p, key: file.name, name: plugin.name, priority: plugin.priority }) + + /** + * + */ if (plugin.handler) { + /** + * + */ lodash.forEach(plugin.handler, ({ fn, key, priority }) => { + /** + * + */ Handler.add({ ns: plugin.namespace || file.name, key, self: plugin, - property: priority || plugin.priority || 500, + property: priority || plugin.priority || 9999, fn: plugin[fn] }) }) @@ -224,44 +259,73 @@ class PluginsLoader { `如安装后仍未解决可联系插件作者将 ${logger.red(pack)} 依赖添加至插件的package.json dependencies中,或手工安装依赖` ) }) - // logger.error('或者使用其他包管理工具安装依赖') logger.mark('---------------------') } /** * 处理事件 - * * 参数文档 https://oicqjs.github.io/oicq/interfaces/GroupMessageEvent.html * @param e icqq Events */ async deal(e) { + /** + * + */ Object.defineProperty(e, 'bot', { value: Bot[e?.self_id || Bot.uin] }) - /** 检查频道消息 */ + + /** + * 检查频道消息 + */ if (this.checkGuildMsg(e)) return - /** 冷却 */ + /** + * 冷却 + */ if (!this.checkLimit(e)) return - /** 处理消息 */ + + /** + * 处理消息 + */ this.dealMsg(e) - /** 检查黑白名单 */ + + /** + * 检查黑白名单 + */ if (!this.checkBlack(e)) return - /** 处理回复 */ + + /** + * 处理回复 + */ this.reply(e) - /** 注册runtime */ + + /** + * 注册runtime + */ await Runtime.init(e) const priority = [] + + /** + * + */ for (const i of this.priority) { const p = new i.class(e) p.e = e - /** 判断是否启用功能,过滤事件 */ + /** + * 判断是否启用功能,过滤事件 + */ if (this.checkDisable(p) && this.filtEvent(e, p)) priority.push(p) } + /** + * + */ for (const plugin of priority) { - /** 上下文hook */ + /** + * 上下文hook + */ if (!plugin.getContext) continue const context = { ...plugin.getContext(), @@ -278,7 +342,9 @@ class PluginsLoader { } } - /** 是否只关注主动at */ + /** + * 是否只关注主动at + */ if (!this.onlyReplyAt(e)) return // 判断是否是星铁命令,若是星铁命令则标准化处理 @@ -287,58 +353,102 @@ class PluginsLoader { get: () => e.game === 'sr', set: v => (e.game = v ? 'sr' : 'gs') }) + Object.defineProperty(e, 'isGs', { get: () => e.game === 'gs', set: v => (e.game = v ? 'gs' : 'sr') }) + + /** + * + */ if (this.srReg.test(e.msg)) { e.game = 'sr' e.msg = e.msg.replace(this.srReg, '#星铁') } - /** 优先执行 accept */ - for (const plugin of priority) - if (plugin.accept) { - const res = await plugin.accept(e) - if (res == 'return') return - if (res) break - } + /** + * 优先执行 accept + */ + for (const plugin of priority) { + if (!plugin.accept) continue + const res = await plugin.accept(e) + // 结束所有 + if (res == 'return') return + // 结束当前 + if (res) break + } - a: for (const plugin of priority) { - /** 正则匹配 */ - if (plugin.rule) - for (const v of plugin.rule) { - /** 判断事件 */ - if (v.event && !this.filtEvent(e, v)) continue - if (!new RegExp(v.reg).test(e.msg)) continue - e.logFnc = `[${plugin.name}][${v.fnc}]` + for (const plugin of priority) { + if (!Array.isArray(plugin?.rule) || plugin.rule.length < 1) continue - if (v.log !== false) - logger.info( - `${e.logFnc}${e.logText} ${lodash.truncate(e.msg, { length: 100 })}` - ) + for (const v of plugin.rule) { + /** + * 判断事件 + */ + if (v.event && !this.filtEvent(e, v)) continue - /** 判断权限 */ - if (!this.filtPermission(e, v)) break a + /** + * + */ + if (!new RegExp(v.reg).test(e.msg)) continue - try { - const start = Date.now() - const res = plugin[v.fnc] && (await plugin[v.fnc](e)) - if (res !== false) { - /** 设置冷却cd */ - this.setLimit(e) - if (v.log !== false) - logger.mark( - `${e.logFnc} ${lodash.truncate(e.msg, { length: 100 })} 处理完成 ${Date.now() - start}ms` - ) - break a - } - } catch (error) { - logger.error(`${e.logFnc}`) - logger.error(error.stack) - break a - } + /** + * + */ + e.logFnc = `[${plugin.name}][${v.fnc}]` + + /** + * + */ + if (v.log !== false) { + logger.info( + `${e.logFnc}${e.logText} ${lodash.truncate(e.msg, { length: 100 })}` + ) } + + /** + * 判断权限 + */ + if (!this.filtPermission(e, v)) break + + /** + * + */ + try { + const start = Date.now() + /** + * + */ + const res = plugin[v.fnc] && (await plugin[v.fnc](e)) + + /** + * res 不是 false , 结束匹配 + * 即 return false 的时候。继续匹配。 + * tudo + * 匹配一次之后就不要再匹配,减少循环。 + * 因此,修改为 仅有当 return true的时候 + * 才会继续匹配 + * + */ + if (res !== false) { + /** + * 设置冷却cd + */ + this.setLimit(e) + if (v.log !== false) { + logger.mark( + `${e.logFnc} ${lodash.truncate(e.msg, { length: 100 })} 处理完成 ${Date.now() - start}ms` + ) + } + break + } + } catch (error) { + logger.error(`${e.logFnc}`) + logger.error(error.stack) + break + } + } } } diff --git a/src/main.ts b/src/main.ts index c618de3..537f2d9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,7 +15,8 @@ global.segment = segment */ global.Renderer = Renderer /** - * + * 确保所有微任务做好准备后 + * 再进行宏任务 */ setTimeout(async () => { await createQQ()