node-karin 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/config/defSet/group.yaml +40 -2
  2. package/lib/adapter/onebot/11/index.js +1 -1
  3. package/lib/cli/init.js +1 -1
  4. package/lib/cli/karin.js +1 -1
  5. package/lib/core/index.d.ts +9 -9
  6. package/lib/core/index.js +9 -9
  7. package/lib/core/init/dir.js +7 -0
  8. package/lib/core/init/init.js +46 -0
  9. package/lib/core/{karin.d.ts → karin/karin.d.ts} +1 -1
  10. package/lib/core/karin/karin.js +194 -0
  11. package/lib/core/{listener.d.ts → listener/listener.d.ts} +1 -1
  12. package/lib/core/listener/listener.js +213 -0
  13. package/lib/core/{plugin.app.d.ts → plugin/app.d.ts} +1 -1
  14. package/lib/core/plugin/app.js +19 -0
  15. package/lib/core/{plugin.d.ts → plugin/base.d.ts} +1 -1
  16. package/lib/core/plugin/base.js +140 -0
  17. package/lib/core/{plugin.loader.d.ts → plugin/loader.d.ts} +3 -3
  18. package/lib/core/plugin/loader.js +579 -0
  19. package/lib/core/process/process.js +100 -0
  20. package/lib/core/server/server.js +283 -0
  21. package/lib/db/index.d.ts +2 -2
  22. package/lib/db/index.js +2 -2
  23. package/lib/db/level/level.js +36 -0
  24. package/lib/db/redis/redis.js +135 -0
  25. package/lib/db/redis/redis_level.js +287 -0
  26. package/lib/event/{event.handler.d.ts → handler/base.d.ts} +2 -2
  27. package/lib/event/handler/base.js +173 -0
  28. package/lib/event/{message.handler.d.ts → handler/message.d.ts} +3 -3
  29. package/lib/event/handler/message.js +270 -0
  30. package/lib/event/{notice.handler.d.ts → handler/notice.d.ts} +3 -3
  31. package/lib/event/handler/notice.js +212 -0
  32. package/lib/event/{request.handler.d.ts → handler/request.d.ts} +3 -3
  33. package/lib/event/handler/request.js +118 -0
  34. package/lib/event/{review.handler.d.ts → handler/review.d.ts} +3 -3
  35. package/lib/event/handler/review.js +391 -0
  36. package/lib/event/index.d.ts +5 -5
  37. package/lib/event/index.js +5 -5
  38. package/lib/render/base.d.ts +1 -1
  39. package/lib/render/client.d.ts +1 -1
  40. package/lib/render/client.js +2 -12
  41. package/lib/render/client_even.d.ts +1 -1
  42. package/lib/render/client_even.js +2 -12
  43. package/lib/render/http.d.ts +1 -1
  44. package/lib/render/http.js +1 -1
  45. package/lib/render/server.js +1 -1
  46. package/lib/types/adapter/{adapter.d.ts → base.d.ts} +2 -2
  47. package/lib/types/config/config.js +1 -0
  48. package/lib/types/element/element.js +1 -0
  49. package/lib/types/event/message.d.ts +1 -1
  50. package/lib/types/event/reply.d.ts +1 -1
  51. package/lib/types/index.d.ts +6 -6
  52. package/lib/types/index.js +6 -6
  53. package/lib/types/logger/logger.js +1 -0
  54. package/lib/types/{plugin.d.ts → plugin/plugin.d.ts} +3 -3
  55. package/lib/types/plugin/plugin.js +1 -0
  56. package/lib/types/render/render.js +1 -0
  57. package/lib/utils/{common.d.ts → common/common.d.ts} +1 -1
  58. package/lib/utils/common/common.js +591 -0
  59. package/lib/utils/{config.d.ts → config/config.d.ts} +37 -19
  60. package/lib/utils/config/config.js +328 -0
  61. package/lib/utils/config/updateVersion.js +145 -0
  62. package/lib/utils/config/yamlEditor.js +292 -0
  63. package/lib/utils/{handler.d.ts → core/handler.d.ts} +1 -1
  64. package/lib/utils/core/handler.js +115 -0
  65. package/lib/utils/core/init.js +213 -0
  66. package/lib/utils/core/logger.js +105 -0
  67. package/lib/utils/{segment.d.ts → core/segment.d.ts} +1 -1
  68. package/lib/utils/core/segment.js +441 -0
  69. package/lib/utils/index.d.ts +11 -11
  70. package/lib/utils/index.js +11 -11
  71. package/lib/utils/{button.d.ts → tools/button.d.ts} +1 -1
  72. package/lib/utils/tools/button.js +38 -0
  73. package/lib/utils/tools/exec.js +37 -0
  74. package/lib/utils/tools/ffmpeg.js +25 -0
  75. package/lib/utils/tools/update.js +139 -0
  76. package/package.json +1 -1
  77. package/lib/core/dir.js +0 -7
  78. package/lib/core/init.js +0 -42
  79. package/lib/core/karin.js +0 -194
  80. package/lib/core/listener.js +0 -217
  81. package/lib/core/plugin.app.js +0 -19
  82. package/lib/core/plugin.js +0 -145
  83. package/lib/core/plugin.loader.js +0 -561
  84. package/lib/core/process.js +0 -98
  85. package/lib/core/server.js +0 -269
  86. package/lib/db/level.js +0 -37
  87. package/lib/db/redis.js +0 -134
  88. package/lib/db/redis_level.js +0 -293
  89. package/lib/event/event.handler.js +0 -167
  90. package/lib/event/message.handler.js +0 -254
  91. package/lib/event/notice.handler.js +0 -204
  92. package/lib/event/request.handler.js +0 -110
  93. package/lib/event/review.handler.js +0 -387
  94. package/lib/types/config.js +0 -1
  95. package/lib/types/element.js +0 -1
  96. package/lib/types/logger.js +0 -1
  97. package/lib/types/plugin.js +0 -1
  98. package/lib/types/render.js +0 -1
  99. package/lib/utils/button.js +0 -34
  100. package/lib/utils/common.js +0 -572
  101. package/lib/utils/config.js +0 -318
  102. package/lib/utils/exec.js +0 -36
  103. package/lib/utils/ffmpeg.js +0 -25
  104. package/lib/utils/handler.js +0 -109
  105. package/lib/utils/init.js +0 -208
  106. package/lib/utils/logger.js +0 -104
  107. package/lib/utils/segment.js +0 -470
  108. package/lib/utils/update.js +0 -135
  109. package/lib/utils/updateVersion.js +0 -145
  110. package/lib/utils/yamlEditor.js +0 -279
  111. /package/lib/core/{dir.d.ts → init/dir.d.ts} +0 -0
  112. /package/lib/core/{init.d.ts → init/init.d.ts} +0 -0
  113. /package/lib/core/{process.d.ts → process/process.d.ts} +0 -0
  114. /package/lib/core/{server.d.ts → server/server.d.ts} +0 -0
  115. /package/lib/db/{level.d.ts → level/level.d.ts} +0 -0
  116. /package/lib/db/{redis.d.ts → redis/redis.d.ts} +0 -0
  117. /package/lib/db/{redis_level.d.ts → redis/redis_level.d.ts} +0 -0
  118. /package/lib/types/adapter/{adapter.js → base.js} +0 -0
  119. /package/lib/types/{config.d.ts → config/config.d.ts} +0 -0
  120. /package/lib/types/{element.d.ts → element/element.d.ts} +0 -0
  121. /package/lib/types/{logger.d.ts → logger/logger.d.ts} +0 -0
  122. /package/lib/types/{render.d.ts → render/render.d.ts} +0 -0
  123. /package/lib/utils/{updateVersion.d.ts → config/updateVersion.d.ts} +0 -0
  124. /package/lib/utils/{yamlEditor.d.ts → config/yamlEditor.d.ts} +0 -0
  125. /package/lib/utils/{init.d.ts → core/init.d.ts} +0 -0
  126. /package/lib/utils/{logger.d.ts → core/logger.d.ts} +0 -0
  127. /package/lib/utils/{exec.d.ts → tools/exec.d.ts} +0 -0
  128. /package/lib/utils/{ffmpeg.d.ts → tools/ffmpeg.d.ts} +0 -0
  129. /package/lib/utils/{update.d.ts → tools/update.d.ts} +0 -0
@@ -1,293 +0,0 @@
1
- import { Level } from 'level'
2
- export default class RedisLevel {
3
- #level
4
- #expireMap
5
- id
6
- constructor () {
7
- const path = process.cwd() + '/data/db/RedisLevel'
8
- this.#level = new Level(path, { valueEncoding: 'json' })
9
- /**
10
- * @type {'RedisLevel'} 唯一标识符 用于区分不同的数据库
11
- */
12
- this.id = 'RedisLevel'
13
- /**
14
- * 过期时间映射表
15
- * @type {Map<string, number>} 键: 值 (过期时间)
16
- */
17
- this.#expireMap = new Map()
18
- /**
19
- * 开启过期时间处理
20
- */
21
- this.#expireHandle()
22
- }
23
-
24
- /**
25
- * 过期时间处理 每分钟检查一次
26
- */
27
- async #expireHandle () {
28
- setInterval(async () => {
29
- const now = Date.now()
30
- // 获取代理对象的键值对数组
31
- const entries = Array.from(this.#expireMap.entries())
32
- for (const [key, expire] of entries) {
33
- if (expire < now) {
34
- await this.#level.del(key)
35
- this.#expireMap.delete(key) // 通过代理的方式删除键值对
36
- }
37
- }
38
- }, 60000)
39
- /**
40
- * 对expireMap进行代理 实现持久化 每次触发都保存到数据库
41
- */
42
- const handler = {
43
- get: function (target, prop, receiver) {
44
- if (prop === 'get' || prop === 'entries') {
45
- return function (...args) {
46
- const reflect = Reflect.get(target, prop).apply(target, args)
47
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
48
- }
49
- }
50
- const reflect = Reflect.get(target, prop, receiver)
51
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
52
- },
53
- set: function (target, key, value) {
54
- target.set(key, value)
55
- // 修改后持久化到数据库
56
- const reflect = Reflect.set(target, key, value)
57
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
58
- },
59
- deleteProperty: function (target, key) {
60
- Reflect.deleteProperty(target, key)
61
- // 删除后持久化到数据库
62
- const reflect = Reflect.deleteProperty(target, key)
63
- return typeof reflect === 'function' ? reflect.bind(target) : reflect
64
- },
65
- }
66
- this.#expireMap = new Proxy(this.#expireMap, handler)
67
- }
68
-
69
- /**
70
- * get 获取数据
71
- * @param {string} key 键
72
- * @returns {Promise<string>|Error} 数据
73
- */
74
- async get (key) {
75
- try {
76
- /** 先查过期时间 */
77
- const expire = this.#expireMap.get(key)
78
- if (expire && expire < Date.now()) {
79
- await this.#level.del(key)
80
- this.#expireMap.delete(key)
81
- return null
82
- }
83
- return await this.#level.get(key)
84
- } catch (error) {
85
- if (error.notFound) { return null }
86
- throw error
87
- }
88
- }
89
-
90
- /**
91
- * set 设置数据
92
- * @param key 键
93
- * @param value 值
94
- * @param options 选项
95
- */
96
- async set (key, value, options) {
97
- if (options && options.EX) {
98
- this.#expireMap.set(key, Date.now() + options.EX * 1000)
99
- }
100
- return await this.#level.put(key, value)
101
- }
102
-
103
- /**
104
- * del 删除数据
105
- * @param key 键
106
- */
107
- async del (key) {
108
- this.#expireMap.delete(key)
109
- return await this.#level.del(key)
110
- }
111
-
112
- /**
113
- * keys 获取所有键
114
- * @param prefix 前缀
115
- */
116
- async keys (prefix = '') {
117
- /** 去掉末尾的* */
118
- prefix = prefix.replace(/\*$/, '')
119
- const list = await this.#level.keys({ gte: prefix, lt: `${prefix}\xFF` }).all()
120
- this.#checkKeys(list)
121
- return list
122
- }
123
-
124
- /**
125
- * 给一个kyes 检查是否过期
126
- * @param keys 键数组
127
- */
128
- async #checkKeys (keys) {
129
- for (const key of keys) {
130
- const expire = this.#expireMap.get(key)
131
- if (expire && expire < Date.now()) {
132
- await this.#level.del(key)
133
- this.#expireMap.delete(key)
134
- }
135
- }
136
- }
137
-
138
- /**
139
- * incr 递增数据
140
- * @param {string} key 键
141
- * @returns {Promise<number>|Error}
142
- */
143
- async incr (key) {
144
- let value = Number(await this.get(key))
145
- if (value === null) {
146
- value = 0
147
- } else {
148
- value = Number(value)
149
- if (isNaN(value)) { throw new Error('Value is not a number') }
150
- }
151
- value += 1
152
- await this.set(key, value.toString())
153
- return value
154
- }
155
-
156
- /**
157
- * decr 递减数据
158
- * @param {string} key 键
159
- * @returns {Promise<number>|Error}
160
- */
161
- async decr (key) {
162
- let value = Number(await this.get(key))
163
- if (value === null) {
164
- value = 0
165
- } else {
166
- value = Number(value)
167
- if (isNaN(value)) { throw new Error('Value is not a number') }
168
- }
169
- value -= 1
170
- await this.set(key, value.toString())
171
- return value
172
- }
173
-
174
- /**
175
- * expire 设置过期时间
176
- * @param {string} key 键
177
- * @param seconds 过期时间 单位秒
178
- * @returns {Promise<number>|Error}
179
- */
180
- async expire (key, seconds) {
181
- this.#expireMap.set(key, Date.now() + seconds * 1000)
182
- return seconds
183
- }
184
-
185
- /**
186
- * ttl 获取过期时间
187
- * @param {string} key 键
188
- * @returns {Promise<number>|Error}
189
- */
190
- async ttl (key) {
191
- const expire = this.#expireMap.get(key)
192
- if (expire) {
193
- return Math.ceil((expire - Date.now()) / 1000)
194
- }
195
- return -2
196
- }
197
-
198
- /**
199
- * setEx 设置数据并设置过期时间
200
- * @param {string} key 键
201
- * @param seconds 过期时间 单位秒
202
- * @param {string} value 值
203
- * @returns {Promise<void>|Error}
204
- */
205
- async setEx (key, seconds, value) {
206
- this.#expireMap.set(key, Date.now() + seconds * 1000)
207
- return await this.#level.put(key, value)
208
- }
209
-
210
- /**
211
- * exists 判断键是否存在
212
- * @param {string} key 键
213
- * @returns {Promise<number>|Error}
214
- */
215
- async exists (key) {
216
- const value = await this.get(key)
217
- return value === null ? 0 : 1
218
- }
219
-
220
- /**
221
- * zAdd 有序集合添加元素
222
- * @param {string} key 键
223
- * @param {object} data 数据
224
- * @param data.score 分数
225
- * @param {string} data.value 值
226
- */
227
- async zAdd (key, { score, value }) {
228
- const set = await this.get(key)
229
- const arr = (set ? JSON.parse(set) : [])
230
- arr.push({ score, value })
231
- arr.sort((a, b) => a.score - b.score)
232
- await this.set(key, JSON.stringify(arr))
233
- }
234
-
235
- /**
236
- * zRem 有序集合删除元素
237
- * @param {string} key 键
238
- * @param {string} value 值
239
- */
240
- async zRem (key, value) {
241
- const set = await this.get(key)
242
- if (set === null) { return }
243
- let arr = JSON.parse(set)
244
- arr = arr.filter((item) => item.value !== value)
245
- await this.set(key, JSON.stringify(arr))
246
- }
247
-
248
- /**
249
- * zIncrBy 有序集合分数递增
250
- * @param {string} key 键
251
- * @param increment 递增值
252
- * @param {string} value 值
253
- * @returns {Promise<number>|Error}
254
- */
255
- async zIncrBy (key, increment, value) {
256
- const set = await this.get(key)
257
- if (set === null) { throw new Error('Set does not exist') }
258
- const arr = JSON.parse(set)
259
- const item = arr.find((item) => item.value === value)
260
- if (item) { item.score += increment }
261
- arr.sort((a, b) => a.score - b.score)
262
- await this.set(key, JSON.stringify(arr))
263
- return item.score
264
- }
265
-
266
- /**
267
- * zRangeByScore 有序集合根据分数范围获取元素
268
- * @param {string} key 键
269
- * @param min 最小分数
270
- * @param max 最大分数
271
- * @returns {Promise<string[]>|Error}
272
- */
273
- async zRangeByScore (key, min, max) {
274
- const set = await this.get(key)
275
- if (set === null) { return [] }
276
- const arr = JSON.parse(set)
277
- return arr.filter((item) => item.score >= min && item.score <= max).map((item) => item.value)
278
- }
279
-
280
- /**
281
- * zScore 有序集合获取元素分数
282
- * @param {string} key 键
283
- * @param {string} value 值
284
- * @returns {Promise<number>|Error}
285
- */
286
- async zScore (key, value) {
287
- const set = await this.get(key)
288
- if (set === null) { return null }
289
- const arr = JSON.parse(set)
290
- const item = arr.find((item) => item.value === value)
291
- return item ? item.score : null
292
- }
293
- }
@@ -1,167 +0,0 @@
1
- import { listener } from '../core/index.js'
2
- import { review } from './review.handler.js'
3
- import { segment, common, logger, config } from '../utils/index.js'
4
- export default class EventHandler {
5
- e
6
- config
7
- /**
8
- * - 是否打印群消息日志
9
- */
10
- GroupMsgPrint
11
- /**
12
- * 处理事件,加入自定义字段
13
- */
14
- constructor (e) {
15
- this.e = e
16
- this.config = {}
17
- this.GroupMsgPrint = false
18
- /** 加入e.bot */
19
- !this.e.bot && Object.defineProperty(this.e, 'bot', { value: listener.getBot(this.e.self_id) })
20
- if (this.e.group_id) { this.config = config.group(this.e.group_id) }
21
- }
22
-
23
- /**
24
- * 事件处理
25
- */
26
- review () {
27
- /** 检查CD */
28
- if (!review.CD(this.e, this.config)) {
29
- logger.debug('[消息拦截] 正在冷却中')
30
- return true
31
- }
32
- /** 检查群聊黑白名单 */
33
- if (!review.GroupEnable(this.e)) {
34
- logger.debug('[消息拦截] 未通过群聊黑白名单检查')
35
- return true
36
- }
37
- /** 检查用户黑白名单 */
38
- if (!review.UserEnable(this.e)) {
39
- logger.debug('[消息拦截] 未通过用户黑白名单检查')
40
- return true
41
- }
42
- /** 都通过了 */
43
- return false
44
- }
45
-
46
- /**
47
- * 处理私聊功能 功能开启返回true
48
- */
49
- private () {
50
- /** 检查私聊是否开启 */
51
- if (this.e.user_id !== 'input' && this.e.isPrivate && !review.Private()) {
52
- /** 用户处于白名单 */
53
- if (config.Config?.private?.white_list?.includes(String(this.e.user_id))) { return true }
54
- /** 不处于白名单 检查是否存在提示词 */
55
- if (config.Config?.private?.tips) { this.e.reply(config.Config.private.tips) }
56
- logger.debug('[消息拦截] 私聊功能未开启')
57
- return false
58
- }
59
- return true
60
- }
61
-
62
- /**
63
- * 根据事件类型过滤事件
64
- */
65
- filtEvent (event) {
66
- /** 事件映射表 */
67
- const eventMap = {
68
- message: () => `message.${this.e.sub_event}`,
69
- message_sent: () => `message_sent.${this.e.sub_event}`,
70
- meta_event: () => `message.${this.e.sub_event}`,
71
- notice: () => `notice.${this.e.sub_event}`,
72
- request: () => `request.${this.e.sub_event}`,
73
- }
74
- const eventType = eventMap[this.e.event]()
75
- return eventType.includes(event)
76
- }
77
-
78
- /**
79
- * 判断权限
80
- */
81
- filterPermission (permission) {
82
- if (!permission || permission === 'all') { return true }
83
- if (permission === 'master') {
84
- if (!this.e.isMaster) {
85
- this.e.reply('暂无权限,只有主人才能操作')
86
- return false
87
- }
88
- return true
89
- }
90
- if (permission === 'admin') {
91
- if (!this.e.isMaster && !this.e.isAdmin) {
92
- this.e.reply('暂无权限,只有管理员才能操作')
93
- return false
94
- }
95
- return true
96
- }
97
- if (this.e.isGroup) {
98
- const list = {
99
- 'group.owner': {
100
- role: 'owner',
101
- name: '群主',
102
- },
103
- 'group.admin': {
104
- role: 'admin',
105
- name: '群管理员',
106
- },
107
- }
108
- const role = list[permission]
109
- if (!role) { return true }
110
- if (role.role === 'owner' && this.e.sender?.role === 'owner') { return true }
111
- if (role.role === 'admin' && (this.e.sender?.role === 'owner' || this.e.sender?.role === 'admin')) { return true }
112
- this.e.reply(`暂无权限,只有${role.name}才能操作`)
113
- return false
114
- }
115
- return true
116
- }
117
-
118
- /**
119
- * 快速回复
120
- */
121
- reply () {
122
- /**
123
- * 快速回复
124
- * @param elements 回复内容
125
- * @param options 回复选项
126
- */
127
- this.e.reply = async (elements = '', options = { reply: false, recallMsg: 0, at: false, retry_count: 1 }) => {
128
- const message = common.makeMessage(elements)
129
- const { reply = false, recallMsg = 0, at, retry_count = 1 } = options
130
- /** 加入at */
131
- if (at && this.e.isGroup) { message.unshift(segment.at(this.e.user_id)) }
132
- /** 加入引用回复 */
133
- if (reply && 'message_id' in this.e) { message.unshift(segment.reply(this.e.message_id)) }
134
- /** 先发 提升速度 */
135
- const result = this.e.replyCallback(message, retry_count)
136
- const ReplyLog = common.makeMessageLog(message)
137
- if (this.e.isGroup) {
138
- review.GroupMsgPrint(this.e) && logger.bot('info', this.e.self_id, `${logger.green(`Send Group ${this.e.group_id}: `)}${ReplyLog}`)
139
- } else {
140
- this.e.self_id !== 'input' && logger.bot('info', this.e.self_id, `${logger.green(`Send private ${this.e.user_id}: `)}${ReplyLog}`)
141
- }
142
- const request = {
143
- message_id: '',
144
- message_time: 0,
145
- raw_data: undefined,
146
- }
147
- try {
148
- listener.emit('karin:count:send', 1)
149
- /** 取结果 */
150
- const Res = await result
151
- request.message_id = Res.message_id || ''
152
- request.message_time = Res.message_time || Date.now()
153
- request.raw_data = Res.raw_data || undefined
154
- logger.bot('debug', this.e.self_id, `回复消息结果:${JSON.stringify(result)}`)
155
- } catch (error) {
156
- logger.bot('error', this.e.self_id, `回复消息失败:${ReplyLog}`)
157
- logger.bot('error', this.e.self_id, error.stack || error.message || JSON.stringify(error))
158
- }
159
- /** 快速撤回 */
160
- if (recallMsg > 0 && request.message_id) {
161
- setTimeout(() => this.e.bot.RecallMessage(this.e.contact, request.message_id), recallMsg * 1000)
162
- }
163
- return request
164
- }
165
- Object.freeze(this.e.reply)
166
- }
167
- }
@@ -1,254 +0,0 @@
1
- import lodash from 'lodash'
2
- import { review } from './review.handler.js'
3
- import EventHandler from './event.handler.js'
4
- import { logger, config } from '../utils/index.js'
5
- import { listener, stateArr, pluginLoader } from '../core/index.js'
6
- /**
7
- * 消息事件
8
- */
9
- export class MessageHandler extends EventHandler {
10
- e
11
- /**
12
- * - 是否打印群消息日志
13
- */
14
- GroupMsgPrint = true
15
- constructor (e) {
16
- super(e)
17
- this.e = e
18
- listener.emit('karin:count:recv', 1)
19
- /** 处理消息 保证日志的打印 */
20
- this.dealMsg()
21
- /** 事件处理 */
22
- if (this.review()) { return }
23
- /** 响应模式 */
24
- if (this.e.group_id && 'mode' in this.config && this.config.mode && !review.mode(this.e, this.config)) {
25
- logger.debug('[消息拦截] 响应模式不匹配')
26
- return
27
- }
28
- /** 处理回复 */
29
- this.reply()
30
- /** 处理私聊 */
31
- if (!this.private()) { return }
32
- /** 处理消息 */
33
- this.deal()
34
- }
35
-
36
- /**
37
- * 处理消息
38
- */
39
- async deal () {
40
- /** 上下文 */
41
- if (await this.context()) { return }
42
- /* eslint-disable no-labels */
43
- a: for (const index of pluginLoader.ruleIds) {
44
- const app = pluginLoader.PluginList[index]
45
- /** 判断事件 */
46
- if (app.event && !this.filtEvent(app.event)) { continue }
47
- /** 正则匹配 */
48
- for (const v of app.rule) {
49
- const reg = v.reg
50
- if (reg.test(this.e.msg)) {
51
- /** 检查黑白名单插件 */
52
- if ('GroupCD' in this.config && !review.PluginEnable(app, this.config)) { continue }
53
- /** 判断子事件 */
54
- if (v.event && !this.filtEvent(v.event)) { continue }
55
- const fncName = app.file.type === 'function' ? 'default' : v.fnc
56
- this.e.logFnc = `[${app.file.dir}][${app.name}][${fncName}]`
57
- const logFnc = logger.fnc(`[${app.name}][${fncName}]`)
58
- this.GroupMsgPrint && typeof v.log === 'function' && v.log(this.e.self_id, `${logFnc}${this.e.logText} ${lodash.truncate(this.e.msg, { length: 80 })}`)
59
- /** 判断权限 */
60
- if (!this.filterPermission(v.permission)) { break a }
61
- /** 计算插件处理时间 */
62
- const start = Date.now()
63
- listener.emit('karin:count:fnc', this.e.logFnc)
64
- try {
65
- let res
66
- if (app.file.type === 'function' && typeof v.fnc === 'function') {
67
- res = await v.fnc(this.e)
68
- } else {
69
- const cla = new app.file.Fnc(this.e)
70
- cla.e = this.e
71
- res = await cla[v.fnc](this.e)
72
- }
73
- this.GroupMsgPrint && typeof v.log === 'function' && v.log(this.e.self_id, `${logFnc} ${lodash.truncate(this.e.msg, { length: 80 })} 处理完成 ${logger.green(Date.now() - start + 'ms')}`)
74
- if (res !== false) { break a }
75
- } catch (error) {
76
- logger.error(`${this.e.logFnc}`)
77
- logger.error(error.stack || error.message || JSON.stringify(error))
78
- break a
79
- }
80
- }
81
- }
82
- }
83
- }
84
-
85
- /**
86
- * 处理消息体
87
- */
88
- dealMsg () {
89
- const logs = []
90
- for (const val of this.e.elements) {
91
- switch (val.type) {
92
- case 'text': {
93
- const msg = (val.text || '').replace(/^\s*[#井#]+\s*/, '#').replace(/^\s*[\\*※*]+\s*/, '*').trim()
94
- this.e.msg += msg
95
- /** 美观一点... */
96
- logs.push(msg)
97
- break
98
- }
99
- case 'face':
100
- logs.push(`[face:${val.id}]`)
101
- break
102
- case 'video':
103
- case 'record':
104
- logs.push(`[${val.type}:${val.file}]`)
105
- break
106
- case 'image':
107
- this.e.image.push(val.file)
108
- logs.push(`[image:${val.file}]`)
109
- break
110
- case 'file':
111
- this.e.file = val
112
- logs.push(`[file:${val.file}]`)
113
- break
114
- case 'at':
115
- /** atBot不计入e.at */
116
- if (val.uid && val.uid === this.e.bot.account.uid) {
117
- this.e.atBot = true
118
- } else if (val.uin === this.e.bot.account.uin) {
119
- this.e.atBot = true
120
- } else if (val.uid && val.uid === 'all') {
121
- this.e.atAll = true
122
- } else {
123
- const id = (val.uid || val.uin)
124
- this.e.at.push(id)
125
- }
126
- logs.push(`[at:${val.uid || val.uin}]`)
127
- break
128
- case 'rps':
129
- logs.push(`[rps:${val.id}]`)
130
- break
131
- case 'dice':
132
- logs.push(`[dice:${val.id}]`)
133
- break
134
- case 'poke':
135
- logs.push(`[poke:${val.id}]`)
136
- break
137
- case 'share':
138
- logs.push(`[share:${val.url}]`)
139
- break
140
- case 'contact':
141
- logs.push(`[contact:${val.peer}]`)
142
- break
143
- case 'location':
144
- logs.push(`[location:${val.lat}-${val.lon}]`)
145
- break
146
- case 'music':
147
- logs.push(`[music:${JSON.stringify(val)}]`)
148
- break
149
- case 'reply':
150
- this.e.reply_id = val.message_id
151
- logs.push(`[reply:${val.message_id}]`)
152
- break
153
- case 'forward':
154
- logs.push(`[forward:${val.res_id}]`)
155
- break
156
- case 'xml':
157
- this.e.msg += val.data
158
- logs.push(`[xml:${val.data}]`)
159
- break
160
- case 'json':
161
- this.e.msg += val.data
162
- logs.push(`[json:${JSON.stringify(val.data)}]`)
163
- break
164
- case 'markdown': {
165
- logs.push(`[markdown:${val.content}]`)
166
- break
167
- }
168
- case 'markdown_tpl': {
169
- const params = val.params
170
- if (!params) { break }
171
- const content = { id: val.custom_template_id }
172
- for (const v of params) { content[v.key] = v.values[0] }
173
- logs.push(`[markdown_tpl:${JSON.stringify(content)}]`)
174
- break
175
- }
176
- case 'rows': {
177
- const rows = []
178
- for (const v of val.rows) { rows.push(JSON.stringify(v.data)) }
179
- logs.push(`[rows:${JSON.stringify(rows)}]`)
180
- break
181
- }
182
- case 'button':
183
- logs.push(`[button:${JSON.stringify(val.data)}]`)
184
- break
185
- case 'long_msg':
186
- logs.push(`[long_msg:${val.id}]`)
187
- break
188
- default:
189
- logs.push(`[未知:${JSON.stringify(val)}]`)
190
- }
191
- }
192
- this.e.raw_message = logs.join('')
193
- /** 前缀处理 */
194
- this.e.group_id && 'GroupCD' in this.config && review.alias(this.e, this.config)
195
- /** 主人 */
196
- if (config.master.includes(String(this.e.user_id))) {
197
- this.e.isMaster = true
198
- this.e.isAdmin = true
199
- } else if (config.admin.includes(String(this.e.user_id))) {
200
- /** 管理员 */
201
- this.e.isAdmin = true
202
- }
203
- if (this.e.contact.scene === 'friend') {
204
- this.e.isPrivate = true
205
- this.e.logText = `[Private:${this.e.sender.nick || ''}(${this.e.user_id})]`
206
- logger.bot('info', this.e.self_id, `私聊:[${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
207
- } else if (this.e.contact.scene === 'group') {
208
- this.e.isGroup = true
209
- this.e.logText = `[Group:${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})]`
210
- this.GroupMsgPrint = review.GroupMsgPrint(this.e)
211
- this.GroupMsgPrint && logger.bot('info', this.e.self_id, `群消息:[${this.e.group_id}-${this.e.user_id}(${this.e.sender.nick || ''})] ${this.e.raw_message}`)
212
- } else {
213
- logger.bot('info', this.e.self_id, `未知消息:${JSON.stringify(this.e)}`)
214
- }
215
- }
216
-
217
- /**
218
- * 处理上下文
219
- */
220
- async context () {
221
- const key = this.e.isGroup ? `${this.e.group_id}.${this.e.user_id}` : this.e.user_id
222
- const App = stateArr[key]
223
- if (App) {
224
- switch (App.type) {
225
- case 'ctx': {
226
- listener.emit(`ctx:${key}`, this.e)
227
- delete stateArr[key]
228
- return true
229
- }
230
- case 'class': {
231
- const { fnc, name } = App
232
- this.e.logFnc = `[${fnc.name}][${name}]`
233
- /** 计算插件处理时间 */
234
- const start = Date.now()
235
- fnc.e = this.e
236
- await fnc[name]()
237
- logger.bot('mark', this.e.self_id, `${this.e.logFnc} 上下文处理完成 ${Date.now() - start}ms`)
238
- return true
239
- }
240
- case 'fnc': {
241
- const { fnc } = App
242
- this.e.logFnc = `[${fnc.name}]`
243
- /** 计算插件处理时间 */
244
- const start = Date.now()
245
- await fnc(this.e)
246
- logger.bot('mark', this.e.self_id, `${this.e.logFnc} 上下文处理完成 ${Date.now() - start}ms`)
247
- delete stateArr[key]
248
- return true
249
- }
250
- }
251
- }
252
- return false
253
- }
254
- }