node-karin 0.3.9 → 0.5.0
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.
- package/config/defSet/config.yaml +11 -0
- package/lib/adapter/input/index.d.ts +63 -0
- package/lib/adapter/input/index.js +188 -0
- package/lib/adapter/onebot/onebot11.d.ts +12 -138
- package/lib/adapter/onebot/onebot11.js +70 -50
- package/lib/core/index.d.ts +1 -0
- package/lib/core/index.js +1 -0
- package/lib/core/karin.d.ts +45 -4
- package/lib/core/karin.js +52 -1
- package/lib/core/listener.js +6 -2
- package/lib/core/plugin.app.d.ts +4 -1
- package/lib/core/plugin.app.js +3 -3
- package/lib/core/plugin.d.ts +8 -2
- package/lib/core/plugin.loader.d.ts +7 -0
- package/lib/core/plugin.loader.js +49 -12
- package/lib/core/server.js +26 -0
- package/lib/db/index.d.ts +2 -4
- package/lib/db/index.js +2 -4
- package/lib/db/level.d.ts +1 -0
- package/lib/db/level.js +1 -0
- package/lib/db/redis.d.ts +2 -41
- package/lib/db/redis.js +2 -3
- package/lib/event/event.d.ts +7 -3
- package/lib/event/event.handler.d.ts +7 -6
- package/lib/event/event.handler.js +6 -1
- package/lib/event/event.js +6 -1
- package/lib/event/index.js +2 -2
- package/lib/event/message.handler.d.ts +3 -3
- package/lib/event/message.handler.js +8 -11
- package/lib/event/notice.d.ts +4 -4
- package/lib/event/notice.handler.d.ts +17 -0
- package/lib/event/notice.handler.js +203 -0
- package/lib/event/request.d.ts +4 -4
- package/lib/event/request.handler.d.ts +17 -0
- package/lib/event/request.handler.js +109 -0
- package/lib/event/request.js +1 -0
- package/lib/event/review.handler.js +12 -24
- package/lib/index.d.ts +2 -1
- package/lib/types/adapter.d.ts +3 -2
- package/lib/types/api.d.ts +295 -0
- package/lib/types/api.js +1 -0
- package/lib/types/config.d.ts +21 -0
- package/lib/types/event.d.ts +127 -241
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/lib/types/plugin.d.ts +4 -4
- package/lib/utils/button.d.ts +2 -2
- package/lib/utils/common.d.ts +5 -6
- package/lib/utils/common.js +3 -4
- package/lib/utils/config.d.ts +5 -2
- package/lib/utils/config.js +43 -17
- package/lib/utils/handler.d.ts +5 -12
- package/lib/utils/handler.js +3 -1
- package/lib/utils/yamlEditor.d.ts +1 -1
- package/package.json +4 -3
- package/lib/utils/kritor-proto.d.ts +0 -1
|
@@ -12,10 +12,6 @@ export class OneBot11 {
|
|
|
12
12
|
* 是否初始化
|
|
13
13
|
*/
|
|
14
14
|
#init = false;
|
|
15
|
-
/**
|
|
16
|
-
* 机器人QQ号
|
|
17
|
-
*/
|
|
18
|
-
self_id;
|
|
19
15
|
/**
|
|
20
16
|
* - 重连次数 仅正向ws使用
|
|
21
17
|
*/
|
|
@@ -25,7 +21,6 @@ export class OneBot11 {
|
|
|
25
21
|
adapter;
|
|
26
22
|
version;
|
|
27
23
|
constructor() {
|
|
28
|
-
this.self_id = '';
|
|
29
24
|
this.index = 0;
|
|
30
25
|
this.account = { uid: '', uin: '', name: '' };
|
|
31
26
|
this.adapter = { id: 'QQ', name: 'OneBot11', type: 'ws', sub_type: 'internal', start_time: Date.now(), connect: '' };
|
|
@@ -108,6 +103,9 @@ export class OneBot11 {
|
|
|
108
103
|
await this.getSelf();
|
|
109
104
|
this.#init = true;
|
|
110
105
|
}
|
|
106
|
+
get self_id() {
|
|
107
|
+
return this.account.uid || this.account.uin;
|
|
108
|
+
}
|
|
111
109
|
/**
|
|
112
110
|
* 获取当前登录号信息
|
|
113
111
|
*/
|
|
@@ -146,7 +144,10 @@ export class OneBot11 {
|
|
|
146
144
|
}, 100);
|
|
147
145
|
});
|
|
148
146
|
}
|
|
149
|
-
/**
|
|
147
|
+
/**
|
|
148
|
+
* 处理事件
|
|
149
|
+
* - @param data ob11相关标准数据
|
|
150
|
+
*/
|
|
150
151
|
#event(data) {
|
|
151
152
|
switch (data.post_type) {
|
|
152
153
|
case 'meta_event': {
|
|
@@ -534,7 +535,6 @@ export class OneBot11 {
|
|
|
534
535
|
}
|
|
535
536
|
/**
|
|
536
537
|
* onebot11转karin
|
|
537
|
-
* @param {Array<{type: string, data: any}>} data onebot11格式消息
|
|
538
538
|
* @return karin格式消息
|
|
539
539
|
* */
|
|
540
540
|
AdapterConvertKarin(data) {
|
|
@@ -590,12 +590,9 @@ export class OneBot11 {
|
|
|
590
590
|
/**
|
|
591
591
|
* karin转onebot11
|
|
592
592
|
* @param data karin格式消息
|
|
593
|
-
* @return {Array<{type: string, data: any}>} onebot11格式消息
|
|
594
593
|
* */
|
|
595
594
|
KarinConvertAdapter(data) {
|
|
596
595
|
const elements = [];
|
|
597
|
-
// const selfUin = this.account.uin
|
|
598
|
-
// const selfNick = this.account.name
|
|
599
596
|
for (const i of data) {
|
|
600
597
|
switch (i.type) {
|
|
601
598
|
case 'text':
|
|
@@ -616,37 +613,35 @@ export class OneBot11 {
|
|
|
616
613
|
elements.push({ type: i.type, data: { file: i.file } });
|
|
617
614
|
break;
|
|
618
615
|
}
|
|
619
|
-
case 'xml':
|
|
616
|
+
case 'xml': {
|
|
617
|
+
elements.push({ type: 'xml', data: { data: i.data } });
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
620
620
|
case 'json': {
|
|
621
|
-
elements.push({ type:
|
|
621
|
+
elements.push({ type: 'json', data: { data: i.data } });
|
|
622
622
|
break;
|
|
623
623
|
}
|
|
624
|
-
// case 'node': {
|
|
625
|
-
// let { type, user_id = selfUin, nickname = selfNick, content } = i
|
|
626
|
-
// content = this.KarinConvertAdapter(content)
|
|
627
|
-
// elements.push({ type, data: { uin: user_id, name: nickname, content } })
|
|
628
|
-
// break
|
|
629
|
-
// }
|
|
630
624
|
case 'forward': {
|
|
631
625
|
elements.push({ type: 'forward', data: { id: i.res_id } });
|
|
632
626
|
break;
|
|
633
627
|
}
|
|
628
|
+
case 'record':
|
|
634
629
|
case 'voice': {
|
|
635
630
|
elements.push({ type: 'record', data: { file: i.file, magic: i.magic || false } });
|
|
636
631
|
break;
|
|
637
632
|
}
|
|
638
633
|
case 'music': {
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
634
|
+
if (i.id) {
|
|
635
|
+
elements.push({ type: 'music', data: { type: i.platform, id: i.id } });
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
const { url, audio, title, author, pic } = i;
|
|
639
|
+
elements.push({ type: 'music', data: { type: 'custom', url, audio, title, content: author, image: pic } });
|
|
640
|
+
}
|
|
645
641
|
break;
|
|
646
642
|
}
|
|
647
643
|
case 'button': {
|
|
648
|
-
|
|
649
|
-
// elements.push({ type: 'button', data: { buttons: i.buttons } })
|
|
644
|
+
elements.push({ type: 'button', data: i.data });
|
|
650
645
|
break;
|
|
651
646
|
}
|
|
652
647
|
case 'markdown': {
|
|
@@ -654,19 +649,51 @@ export class OneBot11 {
|
|
|
654
649
|
elements.push({ type, data: { ...data } });
|
|
655
650
|
break;
|
|
656
651
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
652
|
+
case 'rows': {
|
|
653
|
+
for (const val of i.rows) {
|
|
654
|
+
elements.push({ type: 'button', data: val.data });
|
|
655
|
+
}
|
|
656
|
+
break;
|
|
657
|
+
}
|
|
663
658
|
case 'poke': {
|
|
664
659
|
elements.push({ type: 'poke', data: { type: i.poke_type, id: i.id } });
|
|
665
660
|
break;
|
|
666
661
|
}
|
|
662
|
+
case 'bubble_face': {
|
|
663
|
+
elements.push({ type: 'bubble_face', data: { id: i.id, count: i.count } });
|
|
664
|
+
break;
|
|
665
|
+
}
|
|
666
|
+
case 'contact': {
|
|
667
|
+
elements.push({ type: 'contact', data: { type: i.scene, id: i.peer } });
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
case 'location': {
|
|
671
|
+
elements.push({ type: 'location', data: { lat: i.lat, lon: i.lon, title: i.title, content: i.address } });
|
|
672
|
+
break;
|
|
673
|
+
}
|
|
674
|
+
case 'long_msg':
|
|
675
|
+
case 'basketball':
|
|
676
|
+
case 'dice':
|
|
677
|
+
case 'market_face':
|
|
678
|
+
case 'rps': {
|
|
679
|
+
elements.push({ type: i.type, data: { id: i.id } });
|
|
680
|
+
break;
|
|
681
|
+
}
|
|
682
|
+
case 'gift': {
|
|
683
|
+
elements.push({ type: 'gift', data: { qq: i.qq, id: i.id } });
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
686
|
+
case 'share': {
|
|
687
|
+
elements.push({ type: 'share', data: { url: i.url, title: i.title, content: i.content, image: i.image } });
|
|
688
|
+
break;
|
|
689
|
+
}
|
|
690
|
+
case 'weather': {
|
|
691
|
+
elements.push({ type: 'weather', data: { city: i.city, type: i.type } });
|
|
692
|
+
break;
|
|
693
|
+
}
|
|
667
694
|
default: {
|
|
668
695
|
elements.push(i);
|
|
669
|
-
|
|
696
|
+
break;
|
|
670
697
|
}
|
|
671
698
|
}
|
|
672
699
|
}
|
|
@@ -747,7 +774,14 @@ export class OneBot11 {
|
|
|
747
774
|
}
|
|
748
775
|
const { scene, peer } = contact;
|
|
749
776
|
const message_type = scene === 'group' ? 'group_id' : 'user_id';
|
|
750
|
-
const messages =
|
|
777
|
+
const messages = [];
|
|
778
|
+
const selfUin = this.account.uin;
|
|
779
|
+
const selfNick = this.account.name;
|
|
780
|
+
for (const i of elements) {
|
|
781
|
+
const { type, user_id, nickname, content: contents } = i;
|
|
782
|
+
const content = this.KarinConvertAdapter(contents);
|
|
783
|
+
messages.push({ type, data: { uin: user_id || selfUin, name: nickname || selfNick, content } });
|
|
784
|
+
}
|
|
751
785
|
const params = { [message_type]: String(peer), messages };
|
|
752
786
|
return await this.SendApi('send_forward_msg', params);
|
|
753
787
|
}
|
|
@@ -767,7 +801,7 @@ export class OneBot11 {
|
|
|
767
801
|
}
|
|
768
802
|
/**
|
|
769
803
|
* 撤回消息
|
|
770
|
-
* @param
|
|
804
|
+
* @param _contact - ob11无需提供contact参数
|
|
771
805
|
* @param message_id - 消息ID
|
|
772
806
|
* @returns {Promise<null>}
|
|
773
807
|
*/
|
|
@@ -776,7 +810,7 @@ export class OneBot11 {
|
|
|
776
810
|
}
|
|
777
811
|
/**
|
|
778
812
|
* 获取消息
|
|
779
|
-
* @param
|
|
813
|
+
* @param _contact - ob11无需提供contact参数
|
|
780
814
|
* @param message_id - 消息ID
|
|
781
815
|
* @returns {Promise<object>} - 消息内容
|
|
782
816
|
*/
|
|
@@ -988,22 +1022,8 @@ export class OneBot11 {
|
|
|
988
1022
|
* 获取群信息
|
|
989
1023
|
* @param group_id - 群号
|
|
990
1024
|
* @param no_cache - 是否不使用缓存
|
|
991
|
-
* @returns {Promise<IGroupInfo>} - 群信息
|
|
992
1025
|
*/
|
|
993
1026
|
async GetGroupInfo(group_id, no_cache = false) {
|
|
994
|
-
/**
|
|
995
|
-
* @type {{
|
|
996
|
-
* group_id: number,
|
|
997
|
-
* group_name: string,
|
|
998
|
-
* group_memo: string,
|
|
999
|
-
* group_remark: string,
|
|
1000
|
-
* group_create_time: number,
|
|
1001
|
-
* group_level: number,
|
|
1002
|
-
* member_count: number,
|
|
1003
|
-
* max_member_count: number,
|
|
1004
|
-
* admins: number[]
|
|
1005
|
-
* }}
|
|
1006
|
-
*/
|
|
1007
1027
|
const groupInfo = await this.SendApi('get_group_info', { group_id, no_cache });
|
|
1008
1028
|
return {
|
|
1009
1029
|
group_id: groupInfo.group_id,
|
package/lib/core/index.d.ts
CHANGED
package/lib/core/index.js
CHANGED
package/lib/core/karin.d.ts
CHANGED
|
@@ -7,10 +7,6 @@ export interface OptionsCommand {
|
|
|
7
7
|
* - 插件名称 不传则使用 插件名称:函数名
|
|
8
8
|
*/
|
|
9
9
|
name?: string;
|
|
10
|
-
/**
|
|
11
|
-
* - 插件描述
|
|
12
|
-
*/
|
|
13
|
-
desc?: string;
|
|
14
10
|
/**
|
|
15
11
|
* - 插件优先级 数字越小优先级越高
|
|
16
12
|
* @default 10000
|
|
@@ -66,5 +62,50 @@ export declare class Karin {
|
|
|
66
62
|
* @param options - 选项
|
|
67
63
|
*/
|
|
68
64
|
command(reg: string | RegExp, element: FncElement, options?: OptionsElement): PluginApps;
|
|
65
|
+
/**
|
|
66
|
+
* - 构建定时任务
|
|
67
|
+
* @param name - 任务名称
|
|
68
|
+
* @param cron - cron表达式
|
|
69
|
+
* @param fnc - 执行函数
|
|
70
|
+
* @param options - 选项
|
|
71
|
+
*/
|
|
72
|
+
task(name: string, cron: string, fnc: Function, options?: {
|
|
73
|
+
/**
|
|
74
|
+
* - 任务插件名称
|
|
75
|
+
*/
|
|
76
|
+
name?: string;
|
|
77
|
+
/**
|
|
78
|
+
* - 任务优先级
|
|
79
|
+
*/
|
|
80
|
+
priority?: number;
|
|
81
|
+
/**
|
|
82
|
+
* - 是否打印日志 传递布尔值
|
|
83
|
+
*/
|
|
84
|
+
log?: boolean | Function;
|
|
85
|
+
}): PluginApps;
|
|
86
|
+
/**
|
|
87
|
+
* - 构建handler
|
|
88
|
+
* @param key - 事件key
|
|
89
|
+
* @param fnc - 函数实现
|
|
90
|
+
* @param options - 选项
|
|
91
|
+
*/
|
|
92
|
+
handler(key: string, fnc: (
|
|
93
|
+
/**
|
|
94
|
+
* - 自定义参数 由调用方传递
|
|
95
|
+
*/
|
|
96
|
+
args: any,
|
|
97
|
+
/**
|
|
98
|
+
* - 拒绝处理器 调用后则不再继续执行下一个处理器
|
|
99
|
+
*/
|
|
100
|
+
reject: (msg?: string) => void) => Promise<any>, options?: {
|
|
101
|
+
/**
|
|
102
|
+
* - 插件名称
|
|
103
|
+
*/
|
|
104
|
+
name?: string;
|
|
105
|
+
/**
|
|
106
|
+
* - handler优先级
|
|
107
|
+
*/
|
|
108
|
+
priority?: number;
|
|
109
|
+
}): PluginApps;
|
|
69
110
|
}
|
|
70
111
|
export {};
|
package/lib/core/karin.js
CHANGED
|
@@ -8,6 +8,7 @@ export class Karin {
|
|
|
8
8
|
* @param options - 选项
|
|
9
9
|
* @returns - 返回插件对象
|
|
10
10
|
*/
|
|
11
|
+
|
|
11
12
|
command (reg, second, options = {}) {
|
|
12
13
|
const Reg = typeof reg === 'string' ? new RegExp(reg) : reg
|
|
13
14
|
const data = {
|
|
@@ -29,7 +30,7 @@ export class Karin {
|
|
|
29
30
|
case 'string':
|
|
30
31
|
case 'number':
|
|
31
32
|
case 'object': {
|
|
32
|
-
const element = common.makeMessage(typeof second === '
|
|
33
|
+
const element = common.makeMessage(typeof second === 'number' ? String(second) : second)
|
|
33
34
|
const fnc = async (e) => {
|
|
34
35
|
if ('delay' in options && options.delay) { await common.sleep(options.delay) }
|
|
35
36
|
await e.reply(element, {
|
|
@@ -48,4 +49,54 @@ export class Karin {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* - 构建定时任务
|
|
55
|
+
* @param name - 任务名称
|
|
56
|
+
* @param cron - cron表达式
|
|
57
|
+
* @param fnc - 执行函数
|
|
58
|
+
* @param options - 选项
|
|
59
|
+
*/
|
|
60
|
+
task (name, cron, fnc, options) {
|
|
61
|
+
if (!name) { throw new Error('[task]: 缺少参数[name]') }
|
|
62
|
+
if (!cron) { throw new Error('[task]: 缺少参数[cron]') }
|
|
63
|
+
if (!fnc) { throw new Error('[task]: 缺少参数[fnc]') }
|
|
64
|
+
const data = {
|
|
65
|
+
name: options?.name || 'task',
|
|
66
|
+
priority: options?.priority,
|
|
67
|
+
task: [
|
|
68
|
+
{
|
|
69
|
+
name,
|
|
70
|
+
cron,
|
|
71
|
+
fnc,
|
|
72
|
+
log: options?.log ?? true,
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
}
|
|
76
|
+
return PluginApp(data)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* - 构建handler
|
|
81
|
+
* @param key - 事件key
|
|
82
|
+
* @param fnc - 函数实现
|
|
83
|
+
* @param options - 选项
|
|
84
|
+
*/
|
|
85
|
+
handler (key, fnc, options) {
|
|
86
|
+
if (!key) { throw new Error('[handler]: 缺少参数[key]') }
|
|
87
|
+
if (!fnc) { throw new Error('[handler]: 缺少参数[fnc]') }
|
|
88
|
+
const priority = options?.priority || 10000
|
|
89
|
+
const data = {
|
|
90
|
+
name: options?.name || 'handler',
|
|
91
|
+
priority,
|
|
92
|
+
handler: [
|
|
93
|
+
{
|
|
94
|
+
key,
|
|
95
|
+
fnc,
|
|
96
|
+
priority,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
}
|
|
100
|
+
return PluginApp(data)
|
|
101
|
+
}
|
|
51
102
|
}
|
package/lib/core/listener.js
CHANGED
|
@@ -2,6 +2,8 @@ import { EventEmitter } from 'events'
|
|
|
2
2
|
import { pluginLoader } from './plugin.loader.js'
|
|
3
3
|
import { common, logger, config } from '../utils/index.js'
|
|
4
4
|
import { MessageHandler } from '../event/message.handler.js'
|
|
5
|
+
import NoticeHandler from '../event/notice.handler.js'
|
|
6
|
+
import RequestHandler from '../event/request.handler.js'
|
|
5
7
|
/**
|
|
6
8
|
* 监听器管理
|
|
7
9
|
*/
|
|
@@ -33,11 +35,13 @@ class Listeners extends EventEmitter {
|
|
|
33
35
|
this.addAdapter(data)
|
|
34
36
|
})
|
|
35
37
|
this.on('bot', data => {
|
|
36
|
-
this.addBot(data)
|
|
38
|
+
if (!this.addBot(data)) { return }
|
|
37
39
|
logger.info(`[机器人][注册][${data.type}] ` + logger.green(`[account:${data.bot.account.uid || data.bot.account.uin}(${data.bot.account.name})]`))
|
|
38
40
|
this.emit('karin:online', data.bot.account.uid || data.bot.account.uin)
|
|
39
41
|
})
|
|
40
42
|
this.on('message', data => new MessageHandler(data))
|
|
43
|
+
this.on('notice', data => new NoticeHandler(data))
|
|
44
|
+
this.on('request', data => new RequestHandler(data))
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
/**
|
|
@@ -47,7 +51,7 @@ class Listeners extends EventEmitter {
|
|
|
47
51
|
this.index++
|
|
48
52
|
const index = this.index
|
|
49
53
|
if (!data.bot) {
|
|
50
|
-
logger.error('[Bot管理][注册] 注册失败: Bot实例不能为空')
|
|
54
|
+
logger.error('[Bot管理][注册] 注册失败: Bot实例不能为空', JSON.stringify(data))
|
|
51
55
|
return false
|
|
52
56
|
}
|
|
53
57
|
this.list.push({ index, type: data.type, bot: data.bot })
|
package/lib/core/plugin.app.d.ts
CHANGED
|
@@ -9,7 +9,10 @@ export interface PluginAppType {
|
|
|
9
9
|
name?: string;
|
|
10
10
|
event?: PluginApps['event'];
|
|
11
11
|
priority?: number;
|
|
12
|
-
accept?: boolean;
|
|
12
|
+
accept?: boolean | Function;
|
|
13
13
|
rule?: PluginApps['rule'];
|
|
14
|
+
task?: PluginApps['task'];
|
|
15
|
+
handler?: PluginApps['handler'];
|
|
16
|
+
button?: PluginApps['button'];
|
|
14
17
|
}
|
|
15
18
|
export default function PluginApp(options: PluginAppType): PluginApps;
|
package/lib/core/plugin.app.js
CHANGED
|
@@ -11,8 +11,8 @@ export default function PluginApp (options) {
|
|
|
11
11
|
priority: options.priority || 10000,
|
|
12
12
|
accept: options.accept ?? false,
|
|
13
13
|
rule: options.rule || [],
|
|
14
|
-
task: [],
|
|
15
|
-
handler: [],
|
|
16
|
-
button: [],
|
|
14
|
+
task: options.task || [],
|
|
15
|
+
handler: options.handler || [],
|
|
16
|
+
button: options.button || [],
|
|
17
17
|
}
|
|
18
18
|
}
|
package/lib/core/plugin.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { PluginType, KarinElement, KarinNodeElement, EventType } from '../types/index.js';
|
|
1
|
+
import { PluginType, KarinElement, KarinNodeElement, EventType, KarinNoticeEvent, KarinRequestEvent } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* 插件基类
|
|
4
4
|
*/
|
|
5
5
|
export declare class Plugin implements PluginType {
|
|
6
6
|
e: EventType<this>;
|
|
7
7
|
init?: () => void;
|
|
8
|
-
accept?: (e:
|
|
8
|
+
accept?: (e: any) => Promise<void>;
|
|
9
9
|
replyCallback: PluginType['replyCallback'];
|
|
10
10
|
/**
|
|
11
11
|
* @param name - 插件名称
|
|
@@ -178,3 +178,9 @@ export declare const stateArr: {
|
|
|
178
178
|
fnc: string;
|
|
179
179
|
};
|
|
180
180
|
};
|
|
181
|
+
/**
|
|
182
|
+
* 通知事件 插件类型
|
|
183
|
+
*/
|
|
184
|
+
export interface ExtendedPlugin extends Plugin {
|
|
185
|
+
accept: (e: KarinNoticeEvent | KarinRequestEvent) => Promise<void>;
|
|
186
|
+
}
|
|
@@ -21,7 +21,14 @@ export const pluginLoader = new (class PluginLoader {
|
|
|
21
21
|
* - 命令插件索引列表
|
|
22
22
|
*/
|
|
23
23
|
ruleIds
|
|
24
|
+
/**
|
|
25
|
+
* - 按钮插件索引列表
|
|
26
|
+
*/
|
|
24
27
|
buttonIds
|
|
28
|
+
/**
|
|
29
|
+
* - accept插件索引列表
|
|
30
|
+
*/
|
|
31
|
+
acceptIds
|
|
25
32
|
/**
|
|
26
33
|
* - handler
|
|
27
34
|
*/
|
|
@@ -61,6 +68,7 @@ export const pluginLoader = new (class PluginLoader {
|
|
|
61
68
|
this.PluginList = {}
|
|
62
69
|
this.task = []
|
|
63
70
|
this.ruleIds = []
|
|
71
|
+
this.acceptIds = []
|
|
64
72
|
this.buttonIds = []
|
|
65
73
|
this.handlerIds = {}
|
|
66
74
|
}
|
|
@@ -181,15 +189,18 @@ export const pluginLoader = new (class PluginLoader {
|
|
|
181
189
|
let handlerCount = 0
|
|
182
190
|
const rule = []
|
|
183
191
|
const button = []
|
|
192
|
+
const accept = []
|
|
184
193
|
Object.keys(this.PluginList).forEach(key => {
|
|
185
194
|
taskCount += this.PluginList[key].task.length
|
|
186
195
|
if (this.PluginList[key].rule.length) { rule.push({ key, val: this.PluginList[key].priority }) }
|
|
187
196
|
if (this.PluginList[key].button.length) { button.push({ key, val: this.PluginList[key].priority }) }
|
|
197
|
+
if (this.PluginList[key].accept) { accept.push({ key, val: this.PluginList[key].priority }) }
|
|
188
198
|
})
|
|
189
199
|
this.ruleIds = lodash.orderBy(rule, ['val'], ['asc']).map((v) => Number(v.key))
|
|
190
200
|
logger.debug('rule排序完成...')
|
|
191
201
|
this.buttonIds = lodash.orderBy(button, ['val'], ['asc']).map((v) => Number(v.key))
|
|
192
202
|
logger.debug('button排序完成...')
|
|
203
|
+
this.acceptIds = lodash.orderBy(accept, ['val'], ['asc']).map((v) => Number(v.key))
|
|
193
204
|
if (!isPrint) { return }
|
|
194
205
|
const PluginListKeys = Object.keys(this.PluginList)
|
|
195
206
|
const handlerKeys = Object.keys(this.handlerIds)
|
|
@@ -200,6 +211,7 @@ export const pluginLoader = new (class PluginLoader {
|
|
|
200
211
|
logger.info(`[渲染器][${render.Apps.length}个] 加载完成`)
|
|
201
212
|
logger.info(`[rule][${this.ruleIds.length}个] 加载完成`)
|
|
202
213
|
logger.info(`[button][${this.buttonIds.length}个] 加载完成`)
|
|
214
|
+
logger.info(`[accept][${this.acceptIds.length}个] 加载完成`)
|
|
203
215
|
logger.info(`[定时任务][${taskCount}个] 加载完成`)
|
|
204
216
|
logger.info(`[Handler][Key:${handlerKeys.length}个][fnc:${handlerCount}个] 加载完成`)
|
|
205
217
|
logger.info(logger.green('-----------'))
|
|
@@ -220,12 +232,36 @@ export const pluginLoader = new (class PluginLoader {
|
|
|
220
232
|
lodash.forEach(tmp, (App) => {
|
|
221
233
|
const index = this.index
|
|
222
234
|
this.index++
|
|
223
|
-
if (typeof App === 'object') {
|
|
224
|
-
if (App?.file?.type !== 'function') { return }
|
|
235
|
+
if (typeof App === 'object' && App?.file?.type === 'function') {
|
|
225
236
|
if (!App?.name) { return logger.error(`[${dir}][${name}] 插件名称错误`) }
|
|
226
237
|
App.file.dir = dir
|
|
227
238
|
App.file.name = name
|
|
239
|
+
/** handler */
|
|
240
|
+
handler.add(index + '', App)
|
|
241
|
+
const task = []
|
|
242
|
+
/** 定时任务 */
|
|
243
|
+
lodash.forEach(App.task, val => {
|
|
244
|
+
task.push({
|
|
245
|
+
name: val.name,
|
|
246
|
+
cron: val.cron,
|
|
247
|
+
fnc: val.fnc,
|
|
248
|
+
log: val.log === false ? (log) => logger.debug(log) : (log) => logger.mark(log),
|
|
249
|
+
schedule: schedule.scheduleJob(val.cron, async () => {
|
|
250
|
+
try {
|
|
251
|
+
typeof val.log === 'function' && val.log(`[定时任务][${dir}][${val.name}] 开始执行`)
|
|
252
|
+
if (typeof val.fnc === 'function') { await val.fnc() }
|
|
253
|
+
typeof val.log === 'function' && val.log(`[定时任务][${dir}][${val.name}] 执行完毕`)
|
|
254
|
+
} catch (error) {
|
|
255
|
+
logger.error(`[定时任务][${dir}][${val.name}] 执行报错`)
|
|
256
|
+
logger.error(error)
|
|
257
|
+
}
|
|
258
|
+
}),
|
|
259
|
+
})
|
|
260
|
+
})
|
|
261
|
+
App.task = task
|
|
228
262
|
this.PluginList[index] = App
|
|
263
|
+
if (App.accept) { this.acceptIds.push(index) }
|
|
264
|
+
return true
|
|
229
265
|
}
|
|
230
266
|
if (typeof App !== 'function' || !App?.prototype?.constructor) { return }
|
|
231
267
|
const Class = new App()
|
|
@@ -288,16 +324,13 @@ export const pluginLoader = new (class PluginLoader {
|
|
|
288
324
|
fnc: val.fnc,
|
|
289
325
|
})
|
|
290
326
|
})
|
|
327
|
+
/** accept */
|
|
328
|
+
if (Class.accept && typeof Class.accept === 'function') { this.acceptIds.push(index) }
|
|
291
329
|
/** handler */
|
|
292
330
|
handler.add(index + '', Class)
|
|
293
331
|
/** 执行初始化 */
|
|
294
332
|
Class.init && Class.init()
|
|
295
333
|
this.PluginList[index] = info
|
|
296
|
-
// const Class = new App()
|
|
297
|
-
/** 注册Handler */
|
|
298
|
-
// if (!lodash.isEmpty(Class.handler)) handler.add({ name, dir, App, Class })
|
|
299
|
-
/** 注册按钮 */
|
|
300
|
-
// if (!lodash.isEmpty(Class.button)) button.add({ name, dir, App, Class })
|
|
301
334
|
return true
|
|
302
335
|
})
|
|
303
336
|
// rule收集并排序
|
|
@@ -325,16 +358,20 @@ export const pluginLoader = new (class PluginLoader {
|
|
|
325
358
|
* 卸载插件
|
|
326
359
|
*/
|
|
327
360
|
uninstallApp (dir, name) {
|
|
328
|
-
|
|
329
|
-
// this.uninstallTask(dir, name)
|
|
330
|
-
// button.del(dir, name)
|
|
331
|
-
// handler.del({ dir, name, key: '' })
|
|
361
|
+
const index = []
|
|
332
362
|
Object.keys(this.PluginList).forEach(key => {
|
|
333
363
|
const info = this.PluginList[key]
|
|
334
364
|
/** 停止定时任务 */
|
|
335
365
|
info.task.forEach(val => val.schedule?.cancel())
|
|
336
|
-
info.file.dir === dir && info.file.name === name
|
|
366
|
+
if (info.file.dir === dir && info.file.name === name) {
|
|
367
|
+
index.push(key)
|
|
368
|
+
delete this.PluginList[key]
|
|
369
|
+
}
|
|
337
370
|
})
|
|
371
|
+
/** 删除handler */
|
|
372
|
+
index.forEach(key => handler.del(key))
|
|
373
|
+
/** 重新排序 */
|
|
374
|
+
this.orderBy()
|
|
338
375
|
}
|
|
339
376
|
|
|
340
377
|
/**
|
package/lib/core/server.js
CHANGED
|
@@ -76,6 +76,32 @@ export const server = new (class Server {
|
|
|
76
76
|
process.exit()
|
|
77
77
|
}
|
|
78
78
|
})
|
|
79
|
+
/** 控制台适配器 */
|
|
80
|
+
this.app.get('/api/input', (req, res) => {
|
|
81
|
+
const name = req.query.name
|
|
82
|
+
const token = req.query.token
|
|
83
|
+
if (!name || !token) {
|
|
84
|
+
logger.error('[HTTP][input] 缺少参数', req.query)
|
|
85
|
+
return res.status(403).json({ error: '禁止访问', message: '缺少参数' })
|
|
86
|
+
}
|
|
87
|
+
// 禁止键入向上级目录
|
|
88
|
+
if (name.includes('/')) {
|
|
89
|
+
logger.error('[HTTP][input] 无效的文件名', name)
|
|
90
|
+
return res.status(403).json({ error: '禁止访问', message: '无效的文件名' })
|
|
91
|
+
}
|
|
92
|
+
const CfgToken = config.Config.AdapterInput.token
|
|
93
|
+
if (CfgToken === 'AdapterInput' || CfgToken !== token) {
|
|
94
|
+
logger.error('[HTTP][input] 无效的令牌', token)
|
|
95
|
+
return res.status(403).json({ error: '禁止访问', message: '无效的令牌' })
|
|
96
|
+
}
|
|
97
|
+
const file = process.cwd() + `/temp/input/${name}`
|
|
98
|
+
if (!fs.existsSync(file)) {
|
|
99
|
+
logger.error('[HTTP][input] 文件不存在', file)
|
|
100
|
+
return res.status(404).json({ error: '文件不存在', message: '找不到指定文件' })
|
|
101
|
+
}
|
|
102
|
+
logger.info(`${logger.yellow('[HTTP][input]')} ${logger.green(token)} file:${file}`)
|
|
103
|
+
res.sendFile(file)
|
|
104
|
+
})
|
|
79
105
|
/** 监听端口 */
|
|
80
106
|
const { host, port } = config.Server.http
|
|
81
107
|
this.server.listen(port, host, () => {
|
package/lib/db/index.d.ts
CHANGED
package/lib/db/index.js
CHANGED
package/lib/db/level.d.ts
CHANGED
package/lib/db/level.js
CHANGED