Skip to content

Commit

Permalink
feat: 新增karin.task karin.handler
Browse files Browse the repository at this point in the history
  • Loading branch information
CakmLexi committed Jun 30, 2024
1 parent 609ef99 commit 63a0576
Show file tree
Hide file tree
Showing 25 changed files with 1,044 additions and 365 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@
],
"scripts": {
"app": "node .",
"build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json && npm run fix && npm run cp",
"cp": "cp ./lib/modules.d.ts ./modules.d.ts && cp ./lib/modules.js ./modules.js && cp ./src/utils/kritor-proto.d.ts ./lib/utils/kritor-proto.d.ts",
"build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json && npm run fix:all && npm run cp",
"cp": "cp ./lib/modules.d.ts ./modules.d.ts && cp ./lib/modules.js ./modules.js",
"delete": "pm2 delete ./config/config/pm2.yaml",
"dev": "tsx ./lib/index.js --dev",
"fix": "eslint lib/**/*.js --fix",
"fix:all": "eslint lib/**/*.js --fix && eslint src/**/*.ts --fix",
"fix:all": "eslint lib/**/*.js --fix && eslint lib/**/*.ts --fix",
"init": "node lib/tools/install.js",
"init:dev": "node lib/tools/install.js",
"init:pack": "node lib/tools/install.js",
Expand Down
6 changes: 5 additions & 1 deletion src/adapter/onebot/onebot11.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { listener } from 'karin/core/listener'
import { KarinAdapter } from 'karin/types/adapter'
import { common, config, logger, segment } from 'karin/utils'
import { KarinMessage, KarinNotice, KarinRequest } from 'karin/event'

import {
Role,
Scene,
Expand Down Expand Up @@ -175,7 +176,10 @@ export class OneBot11 implements KarinAdapter {
})
}

/** 处理事件 */
/**
* 处理事件
* - @param data ob11相关标准数据
*/
#event (data: OneBot11Event) {
switch (data.post_type) {
case 'meta_event': {
Expand Down
95 changes: 89 additions & 6 deletions src/core/karin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-dupe-class-members */
import PluginApp from './plugin.app'
import { common } from 'karin/utils'
import { KarinMessage } from 'karin/event/message'
Expand All @@ -12,10 +11,6 @@ export interface OptionsCommand {
* - 插件名称 不传则使用 插件名称:函数名
*/
name?: string
/**
* - 插件描述
*/
desc?: string
/**
* - 插件优先级 数字越小优先级越高
* @default 10000
Expand Down Expand Up @@ -72,6 +67,7 @@ export class Karin {
* @param element - 字符串或者KarinElement、KarinElement数组
* @param options - 选项
*/
// eslint-disable-next-line no-dupe-class-members
command (reg: string | RegExp, element: FncElement, options?: OptionsElement): PluginApps
/**
* - 快速构建命令
Expand All @@ -80,6 +76,7 @@ export class Karin {
* @param options - 选项
* @returns - 返回插件对象
*/
// eslint-disable-next-line no-dupe-class-members
command (reg: string | RegExp, second: FncFunction | FncElement, options: OptionsCommand | OptionsElement = {}): PluginApps {
const Reg = typeof reg === 'string' ? new RegExp(reg) : reg

Expand All @@ -103,7 +100,7 @@ export class Karin {
case 'string':
case 'number':
case 'object': {
const element = common.makeMessage(typeof second === 'function' ? second : String(second))
const element = common.makeMessage(typeof second === 'number' ? String(second) : second)
const fnc = async (e: KarinMessage) => {
if ('delay' in options && options.delay) await common.sleep(options.delay)

Expand All @@ -123,4 +120,90 @@ export class Karin {
}
}
}

/**
* - 构建定时任务
* @param name - 任务名称
* @param cron - cron表达式
* @param fnc - 执行函数
* @param options - 选项
*/
task (name: string, cron: string, fnc: Function, options?: {
/**
* - 任务插件名称
*/
name?: string
/**
* - 任务优先级
*/
priority?: number
/**
* - 是否打印日志 传递布尔值
*/
log?: boolean | Function
}) {
if (!name) throw new Error('[task]: 缺少参数[name]')
if (!cron) throw new Error('[task]: 缺少参数[cron]')
if (!fnc) throw new Error('[task]: 缺少参数[fnc]')

const data = {
name: options?.name || 'task',
priority: options?.priority,
task: [
{
name,
cron,
fnc,
log: options?.log ?? true,
},
],
}

return PluginApp(data)
}

/**
* - 构建handler
* @param key - 事件key
* @param fnc - 函数实现
* @param options - 选项
*/
handler (key: string, fnc: (
/**
* - 自定义参数 由调用方传递
*/
args: any,
/**
* - 拒绝处理器 调用后则不再继续执行下一个处理器
*/
reject: (msg?: string) => void
) => Promise<any>, options?: {
/**
* - 插件名称
*/
name?: string
/**
* - handler优先级
*/
priority?: number
}) {
if (!key) throw new Error('[handler]: 缺少参数[key]')
if (!fnc) throw new Error('[handler]: 缺少参数[fnc]')

const priority = options?.priority || 10000

const data = {
name: options?.name || 'handler',
priority,
handler: [
{
key,
fnc,
priority,
},
],
}

return PluginApp(data)
}
}
11 changes: 7 additions & 4 deletions src/core/plugin.app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ export interface PluginAppType {
name?: string
event?: PluginApps['event']
priority?: number
accept?: boolean
accept?: boolean | Function
rule?: PluginApps['rule']
task?: PluginApps['task']
handler?: PluginApps['handler']
button?: PluginApps['button']
}

export default function PluginApp (options: PluginAppType): PluginApps {
Expand All @@ -27,8 +30,8 @@ export default function PluginApp (options: PluginAppType): PluginApps {
priority: options.priority || 10000,
accept: options.accept ?? false,
rule: options.rule || [],
task: [],
handler: [],
button: [],
task: options.task || [],
handler: options.handler || [],
button: options.button || [],
}
}
71 changes: 56 additions & 15 deletions src/core/plugin.loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,14 @@ export const pluginLoader = new (class PluginLoader {
* - 命令插件索引列表
*/
ruleIds: Array<number>
/**
* - 按钮插件索引列表
*/
buttonIds: Array<number>
/**
* - accept插件索引列表
*/
acceptIds: Array<number>
/**
* - handler
*/
Expand Down Expand Up @@ -66,6 +73,7 @@ export const pluginLoader = new (class PluginLoader {
this.PluginList = {}
this.task = []
this.ruleIds = []
this.acceptIds = []
this.buttonIds = []
this.handlerIds = {}
}
Expand Down Expand Up @@ -199,16 +207,19 @@ export const pluginLoader = new (class PluginLoader {

const rule: { key: string, val: number }[] = []
const button: { key: string, val: number }[] = []
const accept: { key: string, val: number }[] = []
Object.keys(this.PluginList).forEach(key => {
taskCount += this.PluginList[key].task.length
if (this.PluginList[key].rule.length) rule.push({ key, val: this.PluginList[key].priority })
if (this.PluginList[key].button.length) button.push({ key, val: this.PluginList[key].priority })
if (this.PluginList[key].accept) accept.push({ key, val: this.PluginList[key].priority })
})

this.ruleIds = lodash.orderBy(rule, ['val'], ['asc']).map((v) => Number(v.key))
logger.debug('rule排序完成...')
this.buttonIds = lodash.orderBy(button, ['val'], ['asc']).map((v) => Number(v.key))
logger.debug('button排序完成...')
this.acceptIds = lodash.orderBy(accept, ['val'], ['asc']).map((v) => Number(v.key))

if (!isPrint) return
const PluginListKeys = Object.keys(this.PluginList)
Expand All @@ -222,6 +233,7 @@ export const pluginLoader = new (class PluginLoader {
logger.info(`[渲染器][${render.Apps.length}个] 加载完成`)
logger.info(`[rule][${this.ruleIds.length}个] 加载完成`)
logger.info(`[button][${this.buttonIds.length}个] 加载完成`)
logger.info(`[accept][${this.acceptIds.length}个] 加载完成`)
logger.info(`[定时任务][${taskCount}个] 加载完成`)
logger.info(`[Handler][Key:${handlerKeys.length}个][fnc:${handlerCount}个] 加载完成`)
logger.info(logger.green('-----------'))
Expand All @@ -242,12 +254,40 @@ export const pluginLoader = new (class PluginLoader {
lodash.forEach(tmp, (App) => {
const index = this.index
this.index++
if (typeof App === 'object') {
if (App?.file?.type !== 'function') return
if (typeof App === 'object' && App?.file?.type === 'function') {
if (!App?.name) return logger.error(`[${dir}][${name}] 插件名称错误`)
App.file.dir = dir
App.file.name = name

/** handler */
handler.add(index + '', App)

const task: PluginTask[] = []

/** 定时任务 */
lodash.forEach(App.task, val => {
task.push({
name: val.name,
cron: val.cron,
fnc: val.fnc,
log: val.log === false ? (log: string) => logger.debug(log) : (log: string) => logger.mark(log),
schedule: schedule.scheduleJob(val.cron, async () => {
try {
typeof val.log === 'function' && val.log(`[定时任务][${dir}][${val.name}] 开始执行`)
if (typeof val.fnc === 'function') await val.fnc()
typeof val.log === 'function' && val.log(`[定时任务][${dir}][${val.name}] 执行完毕`)
} catch (error) {
logger.error(`[定时任务][${dir}][${val.name}] 执行报错`)
logger.error(error)
}
}),
})
})

App.task = task
this.PluginList[index] = App
if (App.accept) this.acceptIds.push(index)
return true
}

if (typeof App !== 'function' || !App?.prototype?.constructor) return
Expand Down Expand Up @@ -317,20 +357,15 @@ export const pluginLoader = new (class PluginLoader {
})
})

/** accept */
if (Class.accept && typeof Class.accept === 'function') this.acceptIds.push(index)

/** handler */
handler.add(index + '', Class)

/** 执行初始化 */
Class.init && Class.init()
this.PluginList[index] = info

// const Class = new App()

/** 注册Handler */
// if (!lodash.isEmpty(Class.handler)) handler.add({ name, dir, App, Class })

/** 注册按钮 */
// if (!lodash.isEmpty(Class.button)) button.add({ name, dir, App, Class })
return true
})

Expand Down Expand Up @@ -359,16 +394,22 @@ export const pluginLoader = new (class PluginLoader {
* 卸载插件
*/
uninstallApp (dir: dirName, name: fileName) {
// this.Apps = this.Apps.filter((v) => !(v.file.dir === dir && v.file.name === name))
// this.uninstallTask(dir, name)
// button.del(dir, name)
// handler.del({ dir, name, key: '' })
const index: string[] = []
Object.keys(this.PluginList).forEach(key => {
const info = this.PluginList[key]
/** 停止定时任务 */
info.task.forEach(val => val.schedule?.cancel())
info.file.dir === dir && info.file.name === name && delete this.PluginList[key]
if (info.file.dir === dir && info.file.name === name) {
index.push(key)
delete this.PluginList[key]
}
})

/** 删除handler */
index.forEach(key => handler.del(key))

/** 重新排序 */
this.orderBy()
}

/**
Expand Down
11 changes: 9 additions & 2 deletions src/core/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PluginType, KarinElement, KarinNodeElement, EventType } from 'karin/types'
import { PluginType, KarinElement, KarinNodeElement, EventType, KarinNoticeEvent, KarinRequestEvent } from 'karin/types'

/**
* 插件基类
Expand All @@ -7,7 +7,7 @@ export class Plugin implements PluginType {
// 类型 需要根据e中的event类型来确定
e!: EventType<this>
init?: () => void
accept?: (e: EventType<this>) => Promise<void>
accept?: (e: any) => Promise<void>
replyCallback!: PluginType['replyCallback']

/**
Expand Down Expand Up @@ -235,3 +235,10 @@ export const stateArr: {
fnc: string
}
} = {}

/**
* 通知事件 插件类型
*/
export interface ExtendedPlugin extends Plugin {
accept: (e: KarinNoticeEvent | KarinRequestEvent) => Promise<void>
}
8 changes: 2 additions & 6 deletions src/db/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
import Redis from './redis'
import LevelDB from './level'
import { RedisClientType } from 'redis'

export const level = new LevelDB()
export const redis: RedisClientType = await new Redis().start() as RedisClientType
export * from './level'
export * from './redis'
2 changes: 2 additions & 0 deletions src/db/level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,5 @@ export default class LevelDB extends Level {
return await super.put(key, value as string)
}
}

export const level = new LevelDB()
Loading

0 comments on commit 63a0576

Please sign in to comment.