Skip to content

Commit

Permalink
fix: close #153 #156 #152
Browse files Browse the repository at this point in the history
  • Loading branch information
sj817 committed Sep 12, 2024
1 parent 6f7bda3 commit 8447b93
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 58 deletions.
4 changes: 2 additions & 2 deletions config/defSet/group.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ default:
disable: []

# 单个Bot默认配置
Bot.self_id:
Bot:self_id:
# 群聊中所有消息冷却时间,单位秒,0则无限制
GroupCD: 0
# 群聊中 每个人的消息冷却时间,单位秒,0则无限制。注意,开启后所有消息都会进CD,无论是否触发插件。
Expand All @@ -37,7 +37,7 @@ Bot.self_id:
disable: []

# 单个Bot单个群配置
Bot.self_id.group_id:
Bot:self_id:group_id:
# 群聊中所有消息冷却时间,单位秒,0则无限制
GroupCD: 0
# 群聊中 每个人的消息冷却时间,单位秒,0则无限制。注意,开启后所有消息都会进CD,无论是否触发插件。
Expand Down
9 changes: 5 additions & 4 deletions src/core/init/dir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import path from 'path'
import { fileURLToPath } from 'url'

const filename = fileURLToPath(import.meta.url)
/**
* - 获取当前npm包的根目录
*/
export const karinDir = path.resolve(filename, '../../../../').replace(/\\/g, '/').replace(/\/$/, '')
/** 获取当前npm包的根目录 */
export const karinDir = path.resolve(filename, '../../../..').replace(/\/$/, '')

/** 当前是否处于npm包环境 否则代表处于开发环境 */
export const isPkg = karinDir.includes('node_modules')
2 changes: 1 addition & 1 deletion src/core/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { logger } from 'karin/utils'
import { logger } from 'karin/utils/core/logger'

/**
* 启动日志
Expand Down
31 changes: 31 additions & 0 deletions src/core/listener/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
KarinNoticeType,
KarinRequestType,
KarinMessageType,
NodeElement,
} from 'karin/types'

type AdapterType = KarinAdapter['adapter']['type']
Expand Down Expand Up @@ -115,6 +116,36 @@ export class Listeners extends EventEmitter {
this.list.push({ index, type: data.type, bot: data.bot })
logger.info(`[机器人][注册][${data.type}] ` + logger.green(`[account:${data.bot.account.uid || data.bot.account.uin}(${data.bot.account.name})]`))
this.#online(data.bot.account.uid || data.bot.account.uin)

/** 对sendForwardMessage方法进行修改 添加中间键 */
const sendForwardMessage = data.bot.sendForwardMessage
data.bot.sendForwardMessage = async (contact: Contact, elements: Array<NodeElement>) => {
for (const info of pluginLoader.use.forwardMsg) {
try {
let next = false
let exit = false
const nextFn = () => { next = true }
const exitFn = () => { exit = true }

await info.fn(contact, elements, nextFn, exitFn)

if (exit) {
const plugin = pluginLoader.plugin.get(info.key)!
logger.debug(`[消息中间件][${plugin.plugin}][${plugin.file}] 主动操作退出`)
return { message_id: '' }
}

if (!next) break
} catch (e) {
logger.error('[消息中间件] 调用失败,已跳过')
logger.error(e)
}
}

const result = await sendForwardMessage(contact, elements)
return result
}

logger.debug('注册', this.list)
return index
}
Expand Down
16 changes: 16 additions & 0 deletions src/core/plugin/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ class PluginLoader {
recvMsg: [],
replyMsg: [],
sendMsg: [],
forwardMsg: [],
notFound: [],
}

this.ext = process.env.karin_app_lang === 'ts' ? ['.js', '.ts'] : ['.js']
Expand Down Expand Up @@ -367,6 +369,8 @@ class PluginLoader {
this.use.recvMsg = lodash.orderBy(this.use.recvMsg, ['rank'], ['asc'])
this.use.replyMsg = lodash.orderBy(this.use.replyMsg, ['rank'], ['asc'])
this.use.sendMsg = lodash.orderBy(this.use.sendMsg, ['rank'], ['asc'])
this.use.forwardMsg = lodash.orderBy(this.use.forwardMsg, ['rank'], ['asc'])
this.use.notFound = lodash.orderBy(this.use.notFound, ['rank'], ['asc'])

const handler = Object.keys(this.handler)
handler.forEach(key => {
Expand Down Expand Up @@ -513,6 +517,10 @@ class PluginLoader {
/**
* 缓存插件
* @param index - 插件索引
* @param plugin - 插件名称
* @param file - 插件文件
* @param info - 插件信息
* @param App - 插件类
*/
async cachePlugin (index: number, plugin: string, file: string, info: AppType, App?: any) {
if (!info?.name) {
Expand Down Expand Up @@ -632,6 +640,9 @@ class PluginLoader {

/**
* 卸载插件
* @param plugin - 插件名称
* @param _path - 插件apps相对路径
* @param file - 插件文件名称
*/
uninstallApp (plugin: string, _path: string, file: string) {
this.plugin.forEach((info, key) => {
Expand All @@ -644,6 +655,8 @@ class PluginLoader {
this.use.recvMsg = this.use.recvMsg.filter(val => val.key !== key)
this.use.replyMsg = this.use.replyMsg.filter(val => val.key !== key)
this.use.sendMsg = this.use.sendMsg.filter(val => val.key !== key)
this.use.forwardMsg = this.use.forwardMsg.filter(val => val.key !== key)
this.use.notFound = this.use.notFound.filter(val => val.key !== key)

/** 定时任务需要先停止 */
this.task = this.task.filter(val => {
Expand Down Expand Up @@ -673,6 +686,9 @@ class PluginLoader {

/**
* 监听文件夹更新
* @param plugin - 插件名称
* @param _path - 插件apps相对路径
* @returns 是否成功
*/
async watchDir (plugin: string, _path: string) {
const root = path.join(this.dir, plugin, _path)
Expand Down
81 changes: 66 additions & 15 deletions src/event/handler/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,39 @@ import { review } from './review'
import { EventBaseHandler } from './base'
import { logger, config } from 'karin/utils'
import { karin, stateArr, pluginLoader } from 'karin/core'
import { KarinMessageType, PluginCommandInfoType } from 'karin/types'
import { KarinMessageType, MessageSubType, PluginCommandInfoType } from 'karin/types'

/**
* 消息事件
*/
export class MessageHandler extends EventBaseHandler {
e: KarinMessageType
/** 当前事件是否是上下文事件 */
isContext: boolean
constructor (e: KarinMessageType) {
super(e)
this.e = e
this.start()
this.isContext = !!this.getContext()
}

async start () {
this.init()
await this.startUse()

if (this.e.group_id) {
if (this.e.sub_event === MessageSubType.GroupMessage) {
if (!this.getCd()) return
if (!this.getMode()) return
/** 下文不走响应模式 */
if (!this.isContext && !this.getMode()) return
if (!this.getGroupEnable()) return
if (!this.getUserEnable()) return
} else {
if (!this.private()) return
}

/** 上下文 */
if (await this.context()) return

/** 处理消息 */
this.deal()
}
Expand All @@ -32,7 +44,7 @@ export class MessageHandler extends EventBaseHandler {
* 先对消息事件进行初始化
*/
init () {
karin.emit('karin:count:recv', 1)
karin.emit('karin:count:recv', this.e)
const logs = []
for (const val of this.e.elements) {
switch (val.type) {
Expand Down Expand Up @@ -176,20 +188,37 @@ export class MessageHandler extends EventBaseHandler {
}

/**
* 响应模式检查 返回false表示未通过
* 开始中间件
*/
getMode () {
if (review.mode(this.e, this.config)) return true
logger.debug(`[消息拦截][${this.e.group_id}][${this.e.user_id}] 响应模式不匹配`)
return false
async startUse () {
for (const info of pluginLoader.use.recvMsg) {
try {
let next = false
let exit = false
const nextFn = () => { next = true }
const exitFn = () => { exit = true }

await info.fn(this.e, nextFn, exitFn)

if (exit) {
const plugin = pluginLoader.plugin.get(info.key)!
logger.debug(`[消息中间件][${plugin.plugin}][${plugin.file}] 主动操作退出`)
return
}

if (!next) break
} catch (e) {
logger.error('[消息中间件] 调用失败,已跳过')
logger.error(e)
}
}
}

/**
* 处理消息
* 结束中间件
*/
async deal () {
/** 先调用中间件 */
for (const info of pluginLoader.use.recvMsg) {
async endUse () {
for (const info of pluginLoader.use.notFound) {
try {
let next = false
let exit = false
Expand All @@ -210,10 +239,21 @@ export class MessageHandler extends EventBaseHandler {
logger.error(e)
}
}
}

/** 上下文 */
if (await this.context()) return
/**
* 响应模式检查 返回false表示未通过
*/
getMode () {
if (review.mode(this.e, this.config)) return true
logger.debug(`[消息拦截][${this.e.group_id}][${this.e.user_id}] 响应模式不匹配`)
return false
}

/**
* 处理消息
*/
async deal () {
const app = this.e.group_id
? (info: PluginCommandInfoType) => review.PluginEnable(info, this.config)
: () => true
Expand Down Expand Up @@ -262,6 +302,17 @@ export class MessageHandler extends EventBaseHandler {
}
}
}

logger.debug(`[事件处理][${this.e.self_id}][${this.e.user_id}][${this.e.event_id}] 未匹配到任何插件`)
await this.endUse()
}

/**
* 获取下文
*/
getContext () {
const key = this.e.isGroup ? `${this.e.group_id}.${this.e.user_id}` : this.e.user_id
return stateArr[key]
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/event/handler/notice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export class NoticeHandler extends EventBaseHandler {
break
}
}
logger.debug(`[事件处理][${this.e.self_id}][${this.e.user_id}][${this.e.event_id}] 未匹配到任何插件`)
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/event/handler/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export class RequestHandler extends EventBaseHandler {
break
}
}
logger.debug(`[事件处理][${this.e.self_id}][${this.e.user_id}][${this.e.event_id}] 未匹配到任何插件`)
}

/**
Expand Down
44 changes: 41 additions & 3 deletions src/types/plugin/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import schedule from 'node-schedule'
import { Plugin } from 'karin/core'
import { Reply, replyCallback, replyForward } from '../event/reply'
import { KarinNoticeType, KarinRequestType, AllListenEvent, KarinMessageType, PermissionType, AllMessageSubType, Contact, AllNoticeSubType, AllRequestSubType } from '../event'
import { KarinElement } from '../element/element'
import { KarinElement, NodeElement } from '../element/element'

/**
* - 插件根目录名称
Expand All @@ -27,7 +27,7 @@ export const enum AppsType {
/** npm插件 */
Npm = 'npm',
/** 单个app插件 */
Js = 'js'
Js = 'js',
}

/**
Expand All @@ -37,7 +37,7 @@ export const enum MethodType {
/** 函数 */
Function = 'function',
/** 类 */
Class = 'class'
Class = 'class',
}

/**
Expand Down Expand Up @@ -216,6 +216,44 @@ export interface PluginMiddlewareInfoType {
/** 优先级 */
rank: number
}>
/** 发送合并转发前 */
forwardMsg: Array<{
/** 插件基本信息的映射key */
key: number,
/** 插件包名称 */
name: string,
/** 插件执行方法 */
fn: (
/** 发送的目标信息 */
contact: Contact,
/** 发送的消息体 */
elements: Array<NodeElement>,
/** 是否继续执行下一个中间件 */
next: Function,
/** 是否不发送此条消息 */
exit: Function
) => Promise<boolean>,
/** 优先级 */
rank: number
}>
/** 消息事件没有找到任何匹配的插件触发 */
notFound: Array<{
/** 插件基本信息的映射key */
key: number,
/** 插件包名称 */
name: string,
/** 插件执行方法 */
fn: (
/** 消息事件方法 */
e: KarinMessageType,
/** 是否继续执行下一个中间件 */
next: Function,
/** 是否退出此条消息 不再执行匹配插件 */
exit: Function
) => Promise<boolean>,
/** 优先级 */
rank: number
}>
}

/**
Expand Down
Loading

0 comments on commit 8447b93

Please sign in to comment.