update: 简化写法+标注类型
This commit is contained in:
parent
47ba0fee14
commit
503942cc0d
|
@ -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() {
|
||||
//
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
|
||||
import config from './config.js'
|
||||
/**
|
||||
* 配置控制器
|
||||
*/
|
||||
export const ConfigController = config
|
||||
/**
|
||||
* 系统性配置
|
||||
*/
|
||||
export * from './system.js'
|
||||
export * from './system.js'
|
||||
import ConfigController from './config.js'
|
||||
export { ConfigController }
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,7 +3,7 @@ import EventListener from '../listener.js'
|
|||
/**
|
||||
* 监听群聊消息
|
||||
*/
|
||||
export default class messageEvent extends EventListener {
|
||||
export class EventMessage extends EventListener {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -3,7 +3,7 @@ import EventListener from '../listener.js'
|
|||
/**
|
||||
* 监听群聊消息
|
||||
*/
|
||||
export default class noticeEvent extends EventListener {
|
||||
export class EventNotice extends EventListener {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@ import { BOT_NAME } from '../../config/system.js'
|
|||
/**
|
||||
* 监听下线事件
|
||||
*/
|
||||
export default class offlineEvent extends EventListener {
|
||||
export class EventOffline extends EventListener {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@ import { BOT_NAME } from '../../config/system.js'
|
|||
/**
|
||||
* 监听上线事件
|
||||
*/
|
||||
export default class onlineEvent extends EventListener {
|
||||
export class EventOnline extends EventListener {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import EventListener from '../listener.js'
|
||||
|
||||
/**
|
||||
* 监听群聊消息
|
||||
*/
|
||||
export default class requestEvent extends EventListener {
|
||||
export class EventRequest extends EventListener {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
export { segment } from 'icqq'
|
||||
import { segment } from 'icqq'
|
||||
export const Segment = segment
|
||||
export { segment as Segment } from 'icqq'
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ global.segment = segment
|
|||
*/
|
||||
global.Renderer = Renderer
|
||||
/**
|
||||
*
|
||||
* 确保所有微任务做好准备后
|
||||
* 再进行宏任务
|
||||
*/
|
||||
setTimeout(async () => {
|
||||
await createQQ()
|
||||
|
|
Loading…
Reference in New Issue