update: 简化写法+标注类型

This commit is contained in:
ningmengchongshui 2024-06-14 10:35:58 +08:00
parent 47ba0fee14
commit 503942cc0d
15 changed files with 247 additions and 141 deletions

View File

@ -4,6 +4,9 @@ import { join } from 'node:path'
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync } from 'node:fs' import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync } from 'node:fs'
import { CONFIG_DEFAULT_PATH, CONFIG_INIT_PATH } from './system.js' import { CONFIG_DEFAULT_PATH, CONFIG_INIT_PATH } from './system.js'
/**
*
*/
export function configInit() { export function configInit() {
const path = CONFIG_INIT_PATH const path = CONFIG_INIT_PATH
const pathDef = CONFIG_DEFAULT_PATH const pathDef = CONFIG_DEFAULT_PATH
@ -11,7 +14,7 @@ export function configInit() {
mkdirSync(join(process.cwd(), path), { mkdirSync(join(process.cwd(), path), {
'recursive': true 'recursive': true
}) })
for (let file of files) { for (const file of files) {
if (!existsSync(`${path}${file}`)) { if (!existsSync(`${path}${file}`)) {
copyFileSync(`${pathDef}${file}`, `${path}${file}`) copyFileSync(`${pathDef}${file}`, `${path}${file}`)
} }
@ -26,7 +29,6 @@ export function configInit() {
* ******** * ********
*/ */
class ConfigController { class ConfigController {
/** /**
* *
*/ */
@ -55,8 +57,8 @@ class ConfigController {
* icqq配置 * icqq配置
*/ */
get bot() { get bot() {
let bot = this.getConfig('bot') const bot = this.getConfig('bot')
let defbot = this.getdefSet('bot') const defbot = this.getdefSet('bot')
const Config = { ...defbot, ...bot } const Config = { ...defbot, ...bot }
Config.platform = this.getConfig('qq').platform Config.platform = this.getConfig('qq').platform
/** /**
@ -182,16 +184,13 @@ class ConfigController {
* @param name * @param name
*/ */
getYaml(type, name) { getYaml(type, name) {
let file = `config/${type}/${name}.yaml` const file = `config/${type}/${name}.yaml`
let key = `${type}.${name}` const key = `${type}.${name}`
if (this.config[key]) return this.config[key] if (this.config[key]) return this.config[key]
this.config[key] = YAML.parse( this.config[key] = YAML.parse(
readFileSync(file, 'utf8') readFileSync(file, 'utf8')
) )
this.watch(file, name, type) this.watch(file, name, type)
return this.config[key] return this.config[key]
} }
@ -228,6 +227,7 @@ class ConfigController {
/** /**
* *
* @deprecated
*/ */
async change_bot() { async change_bot() {
// //

View File

@ -1,10 +1,3 @@
export * from './system.js'
import config from './config.js' import ConfigController from './config.js'
/** export { ConfigController }
*
*/
export const ConfigController = config
/**
*
*/
export * from './system.js'

View File

@ -10,6 +10,10 @@ import cfg from '../config/config.js'
* ********** * **********
*/ */
import ListenerLoader from './events.loader.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() { static async run() {
const bot = new Client(cfg.bot) const bot = new Client(cfg.bot)
/** 加载监听事件 */
/**
*
*/
await ListenerLoader.load(bot) await ListenerLoader.load(bot)
/** 跳过登录 */ /**
*
*/
if (cfg.bot.skip_login) return await this.skip_login(bot) if (cfg.bot.skip_login) return await this.skip_login(bot)
/** 正常的登录 */ /**
*
*/
await bot.login(cfg.qq, cfg.pwd) await bot.login(cfg.qq, cfg.pwd)
bot[bot.uin] = bot bot[bot.uin] = bot
/** 全局变量 bot */ /**
* bot
*/
global.Bot = bot global.Bot = bot
return bot return bot
} }
@ -58,10 +71,18 @@ export class Client extends IcqqClient {
static async skip_login(bot) { static async skip_login(bot) {
bot.uin = 88888 bot.uin = 88888
bot[bot.uin] = bot bot[bot.uin] = bot
/** 全局变量 bot */ /**
* bot
*/
global.Bot = bot global.Bot = bot
/** 加载插件 */ /**
return await (await import('./plugins.loader.js')).default.load() *
*/
await PluginsLoader.load()
/**
*
*/
return
} }
} }

View File

@ -1,36 +1,36 @@
import { type Client } from 'icqq'
import lodash from 'lodash' import lodash from 'lodash'
import * as Events from './events.js'
/** /**
* *
*/ */
class ListenerLoader { class ListenerLoader {
client = null /**
*
*/
client: Client = null
/** /**
* *
* @param listener * @param listener
* @param File * @param name
* @returns * @returns
*/ */
init = (listener, File: string) => { init = (Listener, name: string) => {
try { try {
if (!listener.default) return
/** /**
* *
*/ */
listener = new listener.default() const listener = new Listener()
/** /**
* *
*/ */
listener.client = this.client listener.client = this.client
/** /**
* *
*/ */
const on = listener.once ? 'once' : 'on' const on = listener.once ? 'once' : 'on'
if (lodash.isArray(listener.event)) { if (lodash.isArray(listener.event)) {
listener.event.forEach(type => { listener.event.forEach(type => {
const e = listener[type] ? type : 'execute' const e = listener[type] ? type : 'execute'
@ -42,9 +42,9 @@ class ListenerLoader {
listener[e](event) listener[e](event)
) )
} }
} catch (e) { } catch (err) {
logger.mark(`监听事件错误:${File}`) logger.mark(`监听事件错误:${name}`)
logger.error(e) logger.error(err)
} }
} }
@ -52,22 +52,11 @@ class ListenerLoader {
* *
* @param client Bot示例 * @param client Bot示例
*/ */
async load(client) { async load(client: Client) {
this.client = client this.client = client
for (const key in Events) {
/** this.init(Events[key], key)
* **************** }
*
* *****************
*
*/
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')
} }
} }

View File

@ -1,10 +1,6 @@
import EventLogin from './events/login' export { EventLogin } from './events/login'
import EventMessage from './events/message' export { EventMessage } from './events/message'
import EventNotice from './events/notice' export { EventNotice } from './events/notice'
import EventOffine from './events/offline' export { EventOffline } from './events/offline'
import EventOnline from './events/online' export { EventOnline } from './events/online'
export { EventLogin } export { EventRequest } from './events/request'
export { EventMessage }
export { EventNotice }
export { EventOffine }
export { EventOnline }

View File

@ -3,7 +3,6 @@ import { sleep } from '../../utils/common.js'
import inquirer from 'inquirer' import inquirer from 'inquirer'
import lodash from 'lodash' import lodash from 'lodash'
import fetch from 'node-fetch' 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 client = null
/** /**

View File

@ -3,7 +3,7 @@ import EventListener from '../listener.js'
/** /**
* *
*/ */
export default class messageEvent extends EventListener { export class EventMessage extends EventListener {
/** /**
* *
*/ */

View File

@ -3,7 +3,7 @@ import EventListener from '../listener.js'
/** /**
* *
*/ */
export default class noticeEvent extends EventListener { export class EventNotice extends EventListener {
/** /**
* *
*/ */

View File

@ -6,7 +6,7 @@ import { BOT_NAME } from '../../config/system.js'
/** /**
* 线 * 线
*/ */
export default class offlineEvent extends EventListener { export class EventOffline extends EventListener {
/** /**
* *
*/ */

View File

@ -6,7 +6,7 @@ import { BOT_NAME } from '../../config/system.js'
/** /**
* 线 * 线
*/ */
export default class onlineEvent extends EventListener { export class EventOnline extends EventListener {
/** /**
* *
*/ */

View File

@ -1,9 +1,8 @@
import EventListener from '../listener.js' import EventListener from '../listener.js'
/** /**
* *
*/ */
export default class requestEvent extends EventListener { export class EventRequest extends EventListener {
/** /**
* *
*/ */

View File

@ -1,3 +1,2 @@
export { segment } from 'icqq' export { segment } from 'icqq'
import { segment } from 'icqq' export { segment as Segment } from 'icqq'
export const Segment = segment

View File

@ -3,5 +3,4 @@ export * from './plugins/functional.js'
export * from './plugins/types.js' export * from './plugins/types.js'
export * from './plugins/common.js' export * from './plugins/common.js'
export * from './icqq.js' export * from './icqq.js'
export * from './events.js'
export * from './bot.js' export * from './bot.js'

View File

@ -44,6 +44,21 @@ class PluginsLoader {
*/ */
watcher = {} watcher = {}
/**
*
*/
msgThrottle = {}
/**
*
*/
pluginCount = null
/**
*
*/
srReg = /^#?(\*|星铁|星轨|穹轨|星穹|崩铁|星穹铁道|崩坏星穹铁道|铁道)+/
/** /**
* *
*/ */
@ -62,13 +77,6 @@ class PluginsLoader {
request: ['post_type', 'request_type', 'sub_type'] request: ['post_type', 'request_type', 'sub_type']
} }
msgThrottle = {}
/**
*
*/
srReg = /^#?(\*|星铁|星轨|穹轨|星穹|崩铁|星穹铁道|崩坏星穹铁道|铁道)+/
/** /**
* *
* @returns * @returns
@ -112,11 +120,6 @@ class PluginsLoader {
return ret return ret
} }
/**
*
*/
pluginCount = null
/** /**
* *
* @param isRefresh * @param isRefresh
@ -149,7 +152,7 @@ class PluginsLoader {
} }
/** /**
* *
* @param file * @param file
* @param packageErr * @param packageErr
*/ */
@ -175,33 +178,65 @@ class PluginsLoader {
} }
/** /**
* *
* @param file * @param file
* @param p * @param p
* @returns * @returns
*/ */
async loadPlugin(file, p) { async loadPlugin(file, p) {
if (!p?.prototype) return if (!p?.prototype) return
/**
*
*/
this.pluginCount++ this.pluginCount++
/**
*
*/
const plugin = new p() const plugin = new p()
/**
*
*/
logger.debug(`加载插件 [${file.name}][${plugin.name}]`) logger.debug(`加载插件 [${file.name}][${plugin.name}]`)
/** 执行初始化,返回 return 则跳过加载 */
/**
* return
*/
if (plugin.init && (await plugin.init()) == 'return') return if (plugin.init && (await plugin.init()) == 'return') return
/** 初始化定时任务 */
/**
*
*/
this.collectTask(plugin.task) this.collectTask(plugin.task)
/**
*
*/
this.priority.push({ this.priority.push({
class: p, class: p,
key: file.name, key: file.name,
name: plugin.name, name: plugin.name,
priority: plugin.priority priority: plugin.priority
}) })
/**
*
*/
if (plugin.handler) { if (plugin.handler) {
/**
*
*/
lodash.forEach(plugin.handler, ({ fn, key, priority }) => { lodash.forEach(plugin.handler, ({ fn, key, priority }) => {
/**
*
*/
Handler.add({ Handler.add({
ns: plugin.namespace || file.name, ns: plugin.namespace || file.name,
key, key,
self: plugin, self: plugin,
property: priority || plugin.priority || 500, property: priority || plugin.priority || 9999,
fn: plugin[fn] fn: plugin[fn]
}) })
}) })
@ -224,44 +259,73 @@ class PluginsLoader {
`如安装后仍未解决可联系插件作者将 ${logger.red(pack)} 依赖添加至插件的package.json dependencies中或手工安装依赖` `如安装后仍未解决可联系插件作者将 ${logger.red(pack)} 依赖添加至插件的package.json dependencies中或手工安装依赖`
) )
}) })
// logger.error('或者使用其他包管理工具安装依赖')
logger.mark('---------------------') logger.mark('---------------------')
} }
/** /**
* *
*
* https://oicqjs.github.io/oicq/interfaces/GroupMessageEvent.html * https://oicqjs.github.io/oicq/interfaces/GroupMessageEvent.html
* @param e icqq Events * @param e icqq Events
*/ */
async deal(e) { async deal(e) {
/**
*
*/
Object.defineProperty(e, 'bot', { Object.defineProperty(e, 'bot', {
value: Bot[e?.self_id || Bot.uin] value: Bot[e?.self_id || Bot.uin]
}) })
/** 检查频道消息 */
/**
*
*/
if (this.checkGuildMsg(e)) return if (this.checkGuildMsg(e)) return
/** 冷却 */ /**
*
*/
if (!this.checkLimit(e)) return if (!this.checkLimit(e)) return
/** 处理消息 */
/**
*
*/
this.dealMsg(e) this.dealMsg(e)
/** 检查黑白名单 */
/**
*
*/
if (!this.checkBlack(e)) return if (!this.checkBlack(e)) return
/** 处理回复 */
/**
*
*/
this.reply(e) this.reply(e)
/** 注册runtime */
/**
* runtime
*/
await Runtime.init(e) await Runtime.init(e)
const priority = [] const priority = []
/**
*
*/
for (const i of this.priority) { for (const i of this.priority) {
const p = new i.class(e) const p = new i.class(e)
p.e = e p.e = e
/** 判断是否启用功能,过滤事件 */ /**
*
*/
if (this.checkDisable(p) && this.filtEvent(e, p)) priority.push(p) if (this.checkDisable(p) && this.filtEvent(e, p)) priority.push(p)
} }
/**
*
*/
for (const plugin of priority) { for (const plugin of priority) {
/** 上下文hook */ /**
* hook
*/
if (!plugin.getContext) continue if (!plugin.getContext) continue
const context = { const context = {
...plugin.getContext(), ...plugin.getContext(),
@ -278,7 +342,9 @@ class PluginsLoader {
} }
} }
/** 是否只关注主动at */ /**
* at
*/
if (!this.onlyReplyAt(e)) return if (!this.onlyReplyAt(e)) return
// 判断是否是星铁命令,若是星铁命令则标准化处理 // 判断是否是星铁命令,若是星铁命令则标准化处理
@ -287,58 +353,102 @@ class PluginsLoader {
get: () => e.game === 'sr', get: () => e.game === 'sr',
set: v => (e.game = v ? 'sr' : 'gs') set: v => (e.game = v ? 'sr' : 'gs')
}) })
Object.defineProperty(e, 'isGs', { Object.defineProperty(e, 'isGs', {
get: () => e.game === 'gs', get: () => e.game === 'gs',
set: v => (e.game = v ? 'gs' : 'sr') set: v => (e.game = v ? 'gs' : 'sr')
}) })
/**
*
*/
if (this.srReg.test(e.msg)) { if (this.srReg.test(e.msg)) {
e.game = 'sr' e.game = 'sr'
e.msg = e.msg.replace(this.srReg, '#星铁') e.msg = e.msg.replace(this.srReg, '#星铁')
} }
/** 优先执行 accept */ /**
for (const plugin of priority) * accept
if (plugin.accept) { */
const res = await plugin.accept(e) for (const plugin of priority) {
if (res == 'return') return if (!plugin.accept) continue
if (res) break const res = await plugin.accept(e)
} // 结束所有
if (res == 'return') return
// 结束当前
if (res) break
}
a: for (const plugin of priority) { for (const plugin of priority) {
/** 正则匹配 */ if (!Array.isArray(plugin?.rule) || plugin.rule.length < 1) continue
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}]`
if (v.log !== false) for (const v of plugin.rule) {
logger.info( /**
`${e.logFnc}${e.logText} ${lodash.truncate(e.msg, { length: 100 })}` *
) */
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) { e.logFnc = `[${plugin.name}][${v.fnc}]`
/** 设置冷却cd */
this.setLimit(e) /**
if (v.log !== false) *
logger.mark( */
`${e.logFnc} ${lodash.truncate(e.msg, { length: 100 })} 处理完成 ${Date.now() - start}ms` if (v.log !== false) {
) logger.info(
break a `${e.logFnc}${e.logText} ${lodash.truncate(e.msg, { length: 100 })}`
} )
} catch (error) {
logger.error(`${e.logFnc}`)
logger.error(error.stack)
break a
}
} }
/**
*
*/
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
}
}
} }
} }

View File

@ -15,7 +15,8 @@ global.segment = segment
*/ */
global.Renderer = Renderer global.Renderer = Renderer
/** /**
* *
*
*/ */
setTimeout(async () => { setTimeout(async () => {
await createQQ() await createQQ()