Compare commits

...

841 Commits

Author SHA1 Message Date
手瓜一十雪
149b518f48 release: v1.5.0 2024-06-03 17:15:43 +08:00
手瓜一十雪
74621447ff fix: 提高兼容性 2024-06-03 17:12:53 +08:00
手瓜一十雪
3280952931 fix: 提高Api兼容性 2024-06-03 17:09:23 +08:00
手瓜一十雪
9e670e2736 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-06-03 16:56:28 +08:00
手瓜一十雪
9fc6347a2f fix: 进一步标准化 2024-06-03 16:56:08 +08:00
Version
ec7a15a192 chore:version change 2024-06-03 08:50:25 +00:00
手瓜一十雪
7f99982810 release: v1.4.9 2024-06-03 16:49:08 +08:00
Version
935d83aaf8 chore:version change 2024-06-02 13:01:32 +00:00
手瓜一十雪
0ff6edd546 style: lint 2024-06-02 20:49:09 +08:00
手瓜一十雪
94f629585a build: v1.4.8-beta2 2024-06-02 20:40:41 +08:00
手瓜一十雪
89c04be02f fix 2024-06-02 13:58:51 +08:00
手瓜一十雪
3151965ea8 build: 1.3.8-beta1 2024-06-02 13:45:48 +08:00
手瓜一十雪
bdf5159be1 refactor: guid 2024-06-02 13:38:33 +08:00
手瓜一十雪
0499ebbea3 release: v1.4.7 2024-06-01 15:52:06 +08:00
手瓜一十雪
d5843b7236 refactor: v1.4.6 2024-06-01 14:09:16 +08:00
手瓜一十雪
1c9c574a90 refactor: v1.4.6 2024-06-01 14:08:10 +08:00
手瓜一十雪
39acf20e48 release: v1.4.6 2024-06-01 14:05:44 +08:00
手瓜一十雪
52eb6ed5ab refactor: group call 2024-06-01 14:02:43 +08:00
手瓜一十雪
ee78d2d59d fix: type hint 2024-06-01 12:14:37 +08:00
手瓜一十雪
60dc5c4a38 refactor: re groupList 2024-06-01 12:10:50 +08:00
手瓜一十雪
50a0dc0355 refactor: GroupListGet 2024-06-01 11:38:50 +08:00
手瓜一十雪
3f681ec914 refactor:NT Event Finish 2024-05-31 23:33:23 +08:00
手瓜一十雪
0bf499f191 release: v1.4.5 2024-05-31 21:25:47 +08:00
手瓜一十雪
389695a0d6 fix: 1.4.5 2024-05-31 21:22:17 +08:00
手瓜一十雪
07f1afb312 fix 2024-05-31 21:03:00 +08:00
手瓜一十雪
ae91e61304 refactor:NTEvent 2024-05-31 21:02:39 +08:00
手瓜一十雪
6248991b01 refactor: NTEvent 2024-05-31 20:38:31 +08:00
手瓜一十雪
7f2d57ef62 refactor: event 2024-05-31 20:29:01 +08:00
手瓜一十雪
31f8f884f1 refactor: NTEvent 2024-05-31 19:09:03 +08:00
手瓜一十雪
4f4af5985a fix: type check & type output 2024-05-31 18:55:18 +08:00
手瓜一十雪
a716fdf6d4 refactor:NTEventDispatch 2024-05-31 14:07:35 +08:00
手瓜一十雪
9717f64abd refactor:NTEvent 2024-05-31 13:55:28 +08:00
手瓜一十雪
adf239183a docs: change 2024-05-31 10:12:59 +08:00
手瓜一十雪
6cf209c79c release: v1.4.4 2024-05-30 22:45:57 +08:00
手瓜一十雪
decc5fb3c0 refactor: checkDate 2024-05-30 22:41:51 +08:00
手瓜一十雪
1e0820d613 refactor: send rate 2024-05-30 22:38:02 +08:00
手瓜一十雪
70124d5177 refactor: GoCQHTTPUploadGroupFile 2024-05-30 22:32:09 +08:00
手瓜一十雪
269de65201 fix: undel 2024-05-30 20:53:58 +08:00
手瓜一十雪
1d11abbfb6 refactor: NTEvent 2024-05-30 19:40:40 +08:00
手瓜一十雪
700f308d6e feat: wrap NT-Event 2024-05-30 17:28:08 +08:00
手瓜一十雪
21b6928ca6 chore: sync core 2024-05-30 16:24:09 +08:00
手瓜一十雪
998c67a649 release: v1.4.3 2024-05-30 16:21:39 +08:00
Version
fb99e878b0 chore:version change 2024-05-30 04:36:42 +00:00
手瓜一十雪
1619adfc27 release: v1.4.2 2024-05-30 12:36:15 +08:00
手瓜一十雪
5510fb473f fix: typo 2024-05-30 12:02:47 +08:00
手瓜一十雪
be1878cb2b build: 1.4.2-fix:file list 2024-05-30 11:01:34 +08:00
手瓜一十雪
15ab121cbd fix: config 2024-05-29 14:26:45 +08:00
手瓜一十雪
aa79b0e861 fix: ocr 2024-05-29 14:18:43 +08:00
手瓜一十雪
b80e550bcd docs: 1.4.2 2024-05-29 12:14:17 +08:00
手瓜一十雪
dbc40b5814 release:1.4.1 2024-05-29 11:38:57 +08:00
Version
0d5696a644 chore:version change 2024-05-29 03:36:54 +00:00
手瓜一十雪
ceffa05802 fix 2024-05-29 11:36:04 +08:00
手瓜一十雪
d5668920b6 release: 1.4.1 2024-05-29 11:34:55 +08:00
手瓜一十雪
516f2da144 feat: en2zh 2024-05-29 10:25:13 +08:00
手瓜一十雪
33c94e1888 docs: 1.4.1 todo 2024-05-29 00:34:44 +08:00
手瓜一十雪
51ab58cd91 fix: webui 2024-05-29 00:07:05 +08:00
手瓜一十雪
aa7798d1d1 feat: wait fix 2024-05-29 00:00:48 +08:00
手瓜一十雪
9067a1fc92 refactor: info record local 2024-05-28 23:24:54 +08:00
手瓜一十雪
4024b6c564 Merge pull request #46 from po-lan/main
Update GetGroupMemberList.ts
2024-05-28 23:20:11 +08:00
po-lan
d39730928b Update GetGroupMemberList.ts
fix
2024-05-28 23:17:39 +08:00
手瓜一十雪
e1f049229c Merge pull request #45 from po-lan/main
对 get_group_member_list 增强
2024-05-28 22:49:21 +08:00
po-lan
8f2676ec19 Update main.ts 2024-05-28 22:43:41 +08:00
po-lan
32d26248dc Update main.ts 2024-05-28 22:41:40 +08:00
po-lan
16f926401b Update db.ts 2024-05-28 22:30:26 +08:00
po-lan
66d60d3599 Update main.ts 2024-05-28 22:27:12 +08:00
po-lan
5a35ab6c34 Update OB11GroupIncreaseEvent.ts 2024-05-28 22:26:02 +08:00
手瓜一十雪
ba1542bd31 Merge pull request #44 from po-lan/main
对 get_group_member_list 增强
2024-05-28 21:49:26 +08:00
po-lan
453060945a Update OB11GroupIncreaseEvent.ts 2024-05-28 21:47:05 +08:00
po-lan
c8351be461 Update config.ts 2024-05-28 21:45:36 +08:00
po-lan
9954da22a6 Update db.ts 2024-05-28 21:44:30 +08:00
手瓜一十雪
907b5611eb chore: sync core 2024-05-28 21:02:57 +08:00
手瓜一十雪
5f075de212 refactor: Info 2024-05-28 20:50:29 +08:00
手瓜一十雪
8fcf3c5079 refactor: GroupInfo 2024-05-28 20:43:16 +08:00
手瓜一十雪
07cee90c7a refactor: MemberInfo-1 2024-05-28 20:08:40 +08:00
手瓜一十雪
75ad495b98 refactor: remove some log 2024-05-28 19:32:08 +08:00
手瓜一十雪
0bb7288ad2 Merge pull request #40 from po-lan/main
对 get_group_member_list 增强
2024-05-28 19:21:25 +08:00
po-lan
ad72415532 对 get_group_member_list 增强开关 2024-05-27 17:11:26 +08:00
po-lan
0ad0353fc0 对 get_group_member_list 增强
监听每一条群聊消息准备写入数据库
2024-05-27 17:09:27 +08:00
po-lan
9fa0dcd7aa 对 get_group_member_list 增强
非管理员的Bot可以通过本地数据库获取到最近的发言时间
2024-05-27 17:07:23 +08:00
po-lan
1f2e80cd39 对 get_group_member_list 增强
一个基于LRU思想写出来的缓存结构
来降低写入数据库的次数
2024-05-27 17:05:28 +08:00
po-lan
6cb6034d43 对 get_group_member_list 增强 2024-05-27 17:01:24 +08:00
手瓜一十雪
25134c6ac6 fix: vite-env 2024-05-26 20:38:18 +08:00
手瓜一十雪
92bf42878a chore: sync core 2024-05-26 11:42:12 +08:00
手瓜一十雪
9f4582d158 docs: update 2024-05-25 19:30:48 +08:00
手瓜一十雪
68af73970e release: 1.4.0 2024-05-25 19:22:52 +08:00
手瓜一十雪
b6ed8d4975 docs: change 2024-05-25 16:55:02 +08:00
手瓜一十雪
d07d3645ce fix: typo 2024-05-25 13:42:10 +08:00
手瓜一十雪
123759ab17 fix: typo 2024-05-25 13:39:49 +08:00
手瓜一十雪
f2f1f893d8 feat: ocr image 2024-05-25 13:38:19 +08:00
手瓜一十雪
db93a8eed2 feat: /get_online_clients 2024-05-25 13:09:47 +08:00
手瓜一十雪
12ab6d4a7d fix 2024-05-25 12:48:13 +08:00
手瓜一十雪
add759e889 feat: try support get_online_clients 2024-05-25 12:02:09 +08:00
手瓜一十雪
f315f7977d feat: support card miniapp 2024-05-25 11:35:08 +08:00
手瓜一十雪
f2f6701ebd feat: support qzone.qq.com Cookies 2024-05-25 11:07:05 +08:00
手瓜一十雪
1a92794d33 chore: sync core 2024-05-24 23:25:14 +08:00
手瓜一十雪
7640deb798 feat: support mini app sign 2024-05-24 23:24:10 +08:00
手瓜一十雪
f1e8ef1cf6 fix: 紧急修复DetailInfo 2024-05-24 18:31:01 +08:00
手瓜一十雪
5e5ac0162e build: 1.3.8 2024-05-24 18:11:32 +08:00
手瓜一十雪
0c013820f0 chore: sync core 2024-05-24 13:51:40 +08:00
手瓜一十雪
4b3a9e5847 release: 1.3.8 2024-05-24 13:47:25 +08:00
手瓜一十雪
e4982256a4 fix: typo 2024-05-24 11:39:46 +08:00
手瓜一十雪
babc4927a8 feat: 注释解码 2024-05-24 11:28:43 +08:00
手瓜一十雪
6dd84cf469 build: 1.4.0-beta8 2024-05-24 11:21:34 +08:00
手瓜一十雪
a8800e3899 feat: 1.4.0-beta8 2024-05-24 11:18:32 +08:00
手瓜一十雪
5f03496046 build: 1.4.0-beta7 2024-05-24 10:45:12 +08:00
手瓜一十雪
41500c17a2 try: fix 2024-05-24 10:42:21 +08:00
手瓜一十雪
2dcfde8b9a build: 1.4.0-beta6 2024-05-23 18:23:11 +08:00
手瓜一十雪
5c3305d8fa Revert "feat: try support LiteLoader"
This reverts commit 8101d17482.
2024-05-23 18:10:18 +08:00
手瓜一十雪
0d1fe99f53 Merge pull request #32 from xihan123/main
fix: set_group_add_request reason 字段错误
2024-05-23 16:48:43 +08:00
xihan123
4c03ffeec7 fix: set_group_add_request reason 字段错误 2024-05-23 16:45:41 +08:00
手瓜一十雪
8101d17482 feat: try support LiteLoader 2024-05-23 16:30:29 +08:00
手瓜一十雪
bc7b4dcc2a build: 1.4.0-beta5 2024-05-23 15:16:35 +08:00
手瓜一十雪
3db8b9078d docs: change 2024-05-23 11:14:42 +08:00
手瓜一十雪
943dbbefd3 build: 1.4.0-beta4-兼容9.7.x换行符 2024-05-23 11:10:31 +08:00
手瓜一十雪
480abcb853 fix: HandlersClear 2024-05-23 10:23:37 +08:00
手瓜一十雪
60aaaff58e fix: UserDetail 2024-05-23 10:19:45 +08:00
手瓜一十雪
e3b889bbe8 fix: test 2024-05-22 21:44:12 +08:00
手瓜一十雪
ac5506a43b style: lint 2024-05-22 20:58:49 +08:00
手瓜一十雪
b29f533a3b feat: 1.4.0 2024-05-22 20:36:38 +08:00
手瓜一十雪
a8ee86b09e build: test 2024-05-22 20:31:16 +08:00
手瓜一十雪
0238c53302 build: 1.4.0-beta2 2024-05-22 20:19:28 +08:00
手瓜一十雪
665e3c806f build: 1.4.0 - beta2 2024-05-22 20:16:24 +08:00
手瓜一十雪
8c96838441 refactor: cjs to es 2024-05-22 20:13:18 +08:00
手瓜一十雪
4a722daec6 chore: sync core 2024-05-22 19:59:36 +08:00
手瓜一十雪
4e0cdbcb91 feat: 破坏性更新 cjs to es 2024-05-22 19:58:45 +08:00
手瓜一十雪
08976624cd feat: debug 2024-05-22 17:30:40 +08:00
手瓜一十雪
fdeba94653 chore: sync core 2024-05-22 16:11:01 +08:00
手瓜一十雪
d3b100b7e5 refactor: member info 2024-05-22 12:52:49 +08:00
手瓜一十雪
1de3e18b08 fix: remove unuse 2024-05-21 19:32:17 +08:00
手瓜一十雪
d5c3c95682 chore: sync core 2024-05-21 19:28:26 +08:00
手瓜一十雪
dabe1e29ed feat: GroupMemberDetailInfo 2024-05-21 19:27:59 +08:00
手瓜一十雪
203d1c0cfc release: v1.3.5 2024-05-20 21:24:11 +08:00
手瓜一十雪
7edd8601be fix 2024-05-20 18:11:13 +08:00
手瓜一十雪
a4423247f4 fix 2024-05-20 18:05:00 +08:00
手瓜一十雪
4834b203a0 fix: stop express 2024-05-20 17:56:36 +08:00
手瓜一十雪
bbabb32d13 fix: 移除调试代码 2024-05-20 17:49:15 +08:00
手瓜一十雪
95112d6bdf fix: 热重载问题 2024-05-20 17:47:13 +08:00
手瓜一十雪
36cdca5a3e fix: 热重载 2024-05-20 16:58:24 +08:00
手瓜一十雪
6980a9f3fc refactor: webui config 2024-05-20 16:56:34 +08:00
手瓜一十雪
7b09479cd2 fix: 拦截错误 2024-05-20 16:26:42 +08:00
手瓜一十雪
5825fd6f36 fix: 拦截异常 2024-05-20 12:35:50 +08:00
手瓜一十雪
2d5b45dd82 feat: test 2024-05-20 12:10:48 +08:00
手瓜一十雪
52dda1d1fe refactor: SysMessage Proto 2024-05-19 22:29:02 +08:00
手瓜一十雪
420624bee4 build: 1.3.5-catch error 2024-05-19 21:48:52 +08:00
手瓜一十雪
8abde7b7d0 Revert "build: 1.3.5-re"
This reverts commit 9e5b1ba28e.
2024-05-19 21:41:57 +08:00
手瓜一十雪
9e5b1ba28e build: 1.3.5-re 2024-05-19 21:18:33 +08:00
手瓜一十雪
b9c7d3c18e build: 1.3.5-re 2024-05-19 21:04:24 +08:00
手瓜一十雪
10aeccbbe5 build: 1.3.5 2024-05-19 20:46:02 +08:00
手瓜一十雪
15d351ebc2 build: 1.3.5-re 2024-05-19 13:30:42 +08:00
手瓜一十雪
7194f31cb6 build: 1.3.5-re 2024-05-19 13:18:29 +08:00
手瓜一十雪
84b7e82446 build: 1.4.0-beta1 2024-05-19 12:36:56 +08:00
手瓜一十雪
8264423b1a fix: 上报问题 2024-05-19 12:36:40 +08:00
手瓜一十雪
37f897f3bf feat: 上报戳一戳 2024-05-19 12:35:15 +08:00
手瓜一十雪
fe3efac145 feat: 解析戳一戳 2024-05-19 12:29:40 +08:00
手瓜一十雪
9773aebefc feat: sys msg decode 2024-05-19 12:12:03 +08:00
手瓜一十雪
06f2b8c371 docs: change init 2024-05-19 11:08:42 +08:00
手瓜一十雪
e8f0bb8350 build: fix check type 2024-05-18 20:48:06 +08:00
手瓜一十雪
9bfa6b827b build: 1.3.5 2024-05-18 20:36:16 +08:00
手瓜一十雪
b21bc17a58 build: 1.3.5 2024-05-18 20:28:35 +08:00
手瓜一十雪
f4d5d417d0 build: 1.3.5 2024-05-18 20:09:33 +08:00
手瓜一十雪
91fc83621e build: 1.3.5 2024-05-18 19:46:53 +08:00
手瓜一十雪
461feca0ca Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-18 19:33:24 +08:00
手瓜一十雪
5e9afab3f7 fix: workflow 2024-05-18 18:18:08 +08:00
Version
2599ca6450 chore:version change 2024-05-18 10:15:09 +00:00
手瓜一十雪
fc99ad3a39 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-18 18:08:29 +08:00
手瓜一十雪
10e1c3e72c build: 1.3.5-beta38 2024-05-18 18:08:18 +08:00
手瓜一十雪
af5dedd4d4 docs: change 2024-05-18 18:00:40 +08:00
手瓜一十雪
3b986c1076 build: 1.3.5-beta37 2024-05-18 17:58:09 +08:00
手瓜一十雪
72f77e8b7c feat: support get_group_system_msg 2024-05-18 17:57:42 +08:00
手瓜一十雪
e893bf676f build: 1.3.5-beta36
get_group_system_msg 未标准化
2024-05-18 17:37:10 +08:00
手瓜一十雪
80eb34f611 feat: try add get_group_system_msg 2024-05-18 16:58:46 +08:00
手瓜一十雪
5d01947552 feat: 快速操作msg默认reply模式回应 2024-05-18 16:27:53 +08:00
手瓜一十雪
d3a025ef7b build: 1.3.5-beta35 2024-05-18 14:40:46 +08:00
手瓜一十雪
c466df841e build: 1.3.5-beta34 2024-05-18 14:36:52 +08:00
手瓜一十雪
b3c6e2a0f3 feat: QuickHandle From LLOB 2024-05-18 14:35:24 +08:00
手瓜一十雪
076c9cfed7 feat: send timeout predict 2024-05-18 14:09:57 +08:00
手瓜一十雪
c3f3d12f83 build: 1.3.5-beta33 2024-05-18 13:35:57 +08:00
手瓜一十雪
44974034ec build: 1.3.5-beta32 2024-05-18 12:56:03 +08:00
手瓜一十雪
d6175acd38 feat: check action data 3 2024-05-18 12:40:41 +08:00
手瓜一十雪
62eee5f05c feat: check action data 2 2024-05-18 12:23:15 +08:00
手瓜一十雪
d4e5201913 feat: action check data 2024-05-18 11:48:38 +08:00
手瓜一十雪
f4d584765a build: 1.3.5-beta30 2024-05-17 21:58:48 +08:00
手瓜一十雪
26e224f852 fix: 热重载容错 2024-05-17 21:44:52 +08:00
手瓜一十雪
252358ed66 build: 1.3.5-beta29 2024-05-17 21:41:07 +08:00
手瓜一十雪
475afeb7c8 build: 1.3.5-beta28 2024-05-17 21:30:37 +08:00
手瓜一十雪
7cbbb846eb build: 1.3.5-beta27 2024-05-17 21:26:32 +08:00
手瓜一十雪
25f947968c fix: typo 2024-05-17 19:55:12 +08:00
手瓜一十雪
cad824dcbc refactor: powershell script 2024-05-17 19:22:36 +08:00
手瓜一十雪
e506f50b00 build: 1.3.5-beta24 2024-05-17 18:51:31 +08:00
手瓜一十雪
96ec149a98 fix: webui 2024-05-17 18:23:50 +08:00
手瓜一十雪
8c913512f6 fix: webui 2024-05-17 18:21:03 +08:00
手瓜一十雪
4cc307299d build: 1.3.5-beta23 2024-05-17 18:12:41 +08:00
手瓜一十雪
407c6b4c5f fix: webui 2024-05-17 18:11:53 +08:00
手瓜一十雪
8f87070434 build: 1.3.5-beta22 2024-05-17 17:17:49 +08:00
手瓜一十雪
4a63996ee2 docs: change 2024-05-17 17:08:01 +08:00
手瓜一十雪
0358fe7620 feat: UpdateConfig 2024-05-17 17:03:48 +08:00
手瓜一十雪
55e64395ed build: 1.3.5-beta20 2024-05-17 15:39:31 +08:00
手瓜一十雪
ff5fb18e14 chore: sync core 2024-05-16 20:47:12 +08:00
手瓜一十雪
52dd960857 build: 1.3.5-beta19 2024-05-16 20:24:49 +08:00
手瓜一十雪
430221c2de fix: check msgElement 2024-05-16 20:23:36 +08:00
手瓜一十雪
217bdf8f92 build: 1.3.5-beta17 2024-05-16 12:53:33 +08:00
手瓜一十雪
38c6c869bf docs: change 2024-05-16 12:52:45 +08:00
手瓜一十雪
84d46da67e fix: ws心跳问题 2024-05-16 12:46:27 +08:00
手瓜一十雪
eb9d6240d7 chore: move 2024-05-16 11:57:02 +08:00
linyuchen
2d44a871b0 chore: Sync core 2024-05-15 23:08:57 +08:00
手瓜一十雪
3f89f350ff fix: 移除umami 2024-05-15 22:18:05 +08:00
手瓜一十雪
1a8407a782 refactor: requests 2024-05-15 21:13:41 +08:00
手瓜一十雪
cf288a3f73 feat: 迁移配置辅助函数 2024-05-15 20:55:09 +08:00
手瓜一十雪
f1f37fb180 Merge pull request #23 from Wesley-Young/main
Refactoring onebot11/action/msg/SendMsg
2024-05-15 19:47:37 +08:00
手瓜一十雪
fb0dd079fd Merge branch 'main' into pr/23 2024-05-15 19:47:19 +08:00
手瓜一十雪
a6c584c85c Merge branch 'main' of https://github.com/Wesley-Young/NapCatQQ.Patch into pr/23 2024-05-15 19:46:46 +08:00
手瓜一十雪
77adf35a30 fix: export problem 2024-05-15 19:45:27 +08:00
linyuchen
dc6951c2a9 Merge remote-tracking branch 'origin/main' 2024-05-15 17:55:20 +08:00
linyuchen
d14ba3f0f7 feat: Cache decorator 2024-05-15 17:55:03 +08:00
Wesley F. Young
78ddf36e35 refactor: split types.ts into separate files 2024-05-15 17:02:24 +08:00
Wesley F. Young
d42734624d refactor: move checkSendMessage and handleForwardNode to separate files 2024-05-15 16:43:21 +08:00
Wesley F. Young
b5dbd9d59b refactor: rename function convertMessage2List to normalize 2024-05-15 16:33:15 +08:00
手瓜一十雪
bed3e1289b chore: sync core 2024-05-15 16:11:01 +08:00
手瓜一十雪
b11ca4e60e Merge branch 'main' into pr/23 2024-05-15 16:10:11 +08:00
Wesley F. Young
4fcf3aa2bd refactor: better type inferring; move createSendElement into another file 2024-05-15 14:53:58 +08:00
手瓜一十雪
dc39da8ca5 build: 1.3.5-beta15 2024-05-15 12:13:39 +08:00
手瓜一十雪
c10c87d28e build: 1.3.5-beta14 2024-05-15 12:10:52 +08:00
手瓜一十雪
c6fe6f1cc5 Merge pull request #22 from SherkeyXD/main
refactor: 重构 Onebot 配置格式,增强可读性
2024-05-15 12:07:46 +08:00
手瓜一十雪
1c2bbeb26d fix: webui renderer 2024-05-15 12:06:17 +08:00
SherkeyXD
17ed3692d0 refactor: webui 跟进 Onebot 配置重构 2024-05-15 11:43:20 +08:00
手瓜一十雪
966a00f41e chore: sync code 2024-05-15 11:40:25 +08:00
手瓜一十雪
fd8d8f89aa Merge branch 'main' into pr/22 2024-05-15 11:32:26 +08:00
手瓜一十雪
305bb74072 chore: sync core 2024-05-15 11:00:24 +08:00
手瓜一十雪
7f4dcdd134 Merge branch 'main' into pr/22 2024-05-15 10:59:46 +08:00
手瓜一十雪
aac37dcce1 docs: typo 2024-05-15 09:35:01 +08:00
手瓜一十雪
f539c662a5 docs: todo 2024-05-15 09:32:05 +08:00
SherkeyXD
c82f346dd0 refactor: 重构 Onebot 配置格式,增强可读性 2024-05-15 00:17:59 +08:00
手瓜一十雪
21b4a87837 docs: change 2024-05-14 23:05:01 +08:00
手瓜一十雪
ae73bcf24b chore: sync core 2024-05-14 22:56:24 +08:00
手瓜一十雪
2a3b56bde1 build: 1.3.5-beta12 2024-05-14 22:53:26 +08:00
手瓜一十雪
b8ebededd8 fix: Member Kick Event 2024-05-14 22:48:43 +08:00
手瓜一十雪
227c4c422c build: 1.3.5-beta11 2024-05-14 20:44:04 +08:00
手瓜一十雪
652bfb93cc docs: change 2024-05-14 17:24:17 +08:00
手瓜一十雪
c2278e3536 build: v1.3.5-beta10 2024-05-14 16:40:23 +08:00
手瓜一十雪
caa2fca4e8 refactor: http requests 2024-05-14 15:31:53 +08:00
手瓜一十雪
745cb0175c refactor: requests 2024-05-14 15:19:37 +08:00
手瓜一十雪
e5165a780f feat: 新增群荣誉信息 2024-05-14 14:08:57 +08:00
手瓜一十雪
b4b91af02b feat: 新增群荣誉信息 2024-05-14 14:02:29 +08:00
手瓜一十雪
5649ff9c2e chore: sync core 2024-05-14 11:38:39 +08:00
手瓜一十雪
5b4bf6c62a chore: sync core 2024-05-14 10:20:27 +08:00
手瓜一十雪
93cb662282 refactor: scipt and request 2024-05-14 10:16:30 +08:00
手瓜一十雪
00a8715e58 chore: sync core 2024-05-13 21:24:47 +08:00
手瓜一十雪
7ecd479b3e refactor: webapi http 2024-05-13 21:22:20 +08:00
手瓜一十雪
8fe7d3aaec refactor: sign music 2024-05-13 21:14:48 +08:00
手瓜一十雪
f32a693393 feat: 配置热重载 2024-05-13 21:07:19 +08:00
手瓜一十雪
17ebc01597 fix: linux script env 2024-05-13 18:39:59 +08:00
手瓜一十雪
827fb698e1 chore: version 2024-05-13 18:25:34 +08:00
手瓜一十雪
32bdf10fd2 refactor: check version 2024-05-13 18:13:52 +08:00
手瓜一十雪
b795e6c3d2 refactor: umami 2024-05-13 18:08:46 +08:00
手瓜一十雪
42ba524e4e refactor: HttpGetJson 2024-05-13 17:53:50 +08:00
手瓜一十雪
317c6d96e3 refactor: http_util 2024-05-13 17:41:10 +08:00
手瓜一十雪
3692d1499f refactor: boot script 2024-05-13 17:26:22 +08:00
手瓜一十雪
b21fbad8a3 refactor: boot scipt 2024-05-13 16:57:03 +08:00
手瓜一十雪
743334a68a refactor: version check 2024-05-13 16:46:40 +08:00
手瓜一十雪
951413eb38 docs: change 2024-05-13 16:44:30 +08:00
手瓜一十雪
32dcdef853 fix: build script 2024-05-13 16:43:16 +08:00
手瓜一十雪
34c9254d4a fix: typo 2024-05-13 16:39:24 +08:00
手瓜一十雪
14012a4668 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-13 16:38:19 +08:00
手瓜一十雪
575debca63 fix: reboot on win 2024-05-13 16:37:48 +08:00
linyuchen
763cac8532 Merge remote-tracking branch 'origin/main' 2024-05-13 16:32:52 +08:00
linyuchen
43faacd7a7 doc: changelog history 2024-05-13 16:32:40 +08:00
Version
1d4e307e96 chore:version change 2024-05-13 08:09:02 +00:00
linyuchen
7f8933b0de doc: changelog 2024-05-13 16:05:35 +08:00
手瓜一十雪
81608ff025 docs:change 2024-05-13 13:56:36 +08:00
手瓜一十雪
db63675b8e fix: 修复重启 但win无法及时结束父进程 2024-05-13 13:44:23 +08:00
linyuchen
f74a83bc46 doc: changelog 2024-05-13 12:53:44 +08:00
linyuchen
bc1deba3e4 style: eslint 2024-05-13 12:53:30 +08:00
手瓜一十雪
d6113a8f0a fix: 尝试修复 但仍然无法使用reboot 2024-05-13 12:35:15 +08:00
手瓜一十雪
2062cd48ea fix: RebootNormol 2024-05-13 09:33:00 +08:00
手瓜一十雪
1c965ef515 feat: api Extend RebootNormol 2024-05-13 09:32:25 +08:00
linyuchen
58291b7156 update core 2024-05-13 08:52:55 +08:00
linyuchen
afd1648d80 refactor: GetUserDetailInfo auto map uid2uin 2024-05-13 08:41:48 +08:00
linyuchen
21814ffa9a Merge remote-tracking branch 'origin/main' 2024-05-13 01:28:23 +08:00
手瓜一十雪
9d3522da54 fix: OnGroupNotifiesUpdated catch getUserDetailInfo 2024-05-13 01:28:11 +08:00
手瓜一十雪
e07a76755e docs: todo 2024-05-12 23:22:53 +08:00
手瓜一十雪
ba46bcdeae docs: change 2024-05-12 23:21:48 +08:00
手瓜一十雪
8d7e44314c build: 1.3.5-beta8 2024-05-12 23:18:59 +08:00
手瓜一十雪
35a67498c7 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-12 23:18:39 +08:00
手瓜一十雪
90dd934f95 feat: limit sendMsg 2024-05-12 23:18:27 +08:00
手瓜一十雪
4087045542 docs: change 2024-05-12 22:59:30 +08:00
手瓜一十雪
d11cef5907 build: 1.3.5-beta7 2024-05-12 22:57:32 +08:00
手瓜一十雪
76c91d226c build: 1.3.5-beta6 2024-05-12 22:23:27 +08:00
手瓜一十雪
c2b4dd2afd feat: Reboot Api(未经测试) 2024-05-12 22:19:03 +08:00
手瓜一十雪
25b39cb39a Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-12 22:12:13 +08:00
手瓜一十雪
35dcb7b88b feat: reboot util 2024-05-12 22:11:47 +08:00
手瓜一十雪
e5f7e7c26e docs: change 2024-05-12 22:05:07 +08:00
手瓜一十雪
c5c11fd6a6 docs: change 2024-05-12 22:04:49 +08:00
手瓜一十雪
8134083419 build: 1.3.5-beta5 2024-05-12 22:00:18 +08:00
linyuchen
a87e624198 build: fix fetch ua 2024-05-12 21:50:50 +08:00
linyuchen
e4c62d20b4 build: Fix http UA 2024-05-12 21:49:39 +08:00
手瓜一十雪
fa195d9e55 docs: change 2024-05-12 21:48:38 +08:00
linyuchen
5ef5773d23 update core 2024-05-12 21:48:30 +08:00
linyuchen
6eea52afdf Merge remote-tracking branch 'origin/main' 2024-05-12 21:46:27 +08:00
linyuchen
80e64af30f fix: Fetch miss ua 2024-05-12 21:46:13 +08:00
手瓜一十雪
563b6ddc36 refactor: rm SetGroupNotice 2024-05-12 21:24:22 +08:00
手瓜一十雪
c051ab9dc4 fix: rm exist GoCQHTTP_SendGroupNotice 2024-05-12 20:52:40 +08:00
linyuchen
87737a8bdb refactor: Remove random os hostname 2024-05-12 20:41:45 +08:00
linyuchen
94273d80b0 refactor: Random os hostname 2024-05-12 20:32:36 +08:00
手瓜一十雪
a08ec2a4bd docs: CHANGELOG 2024-05-12 18:41:28 +08:00
linyuchen
d246c556f4 update core.lib 2024-05-12 18:00:56 +08:00
linyuchen
65aa365e38 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/core.lib/src/adapters/NodeIDependsAdapter.js
#	src/core.lib/src/adapters/NodeIDispatcherAdapter.js
#	src/core.lib/src/adapters/NodeIGlobalAdapter.js
#	src/core.lib/src/adapters/index.js
#	src/core.lib/src/apis/file.js
#	src/core.lib/src/apis/friend.js
#	src/core.lib/src/apis/group.js
#	src/core.lib/src/apis/index.js
#	src/core.lib/src/apis/msg.js
#	src/core.lib/src/apis/sign.js
#	src/core.lib/src/apis/user.js
#	src/core.lib/src/apis/webapi.js
#	src/core.lib/src/core.js
#	src/core.lib/src/data.js
#	src/core.lib/src/entities/cache.js
#	src/core.lib/src/entities/constructor.js
#	src/core.lib/src/entities/group.js
#	src/core.lib/src/entities/index.js
#	src/core.lib/src/entities/msg.js
#	src/core.lib/src/entities/notify.js
#	src/core.lib/src/entities/user.js
#	src/core.lib/src/external/hook.js
#	src/core.lib/src/index.js
#	src/core.lib/src/listeners/NodeIKernelBuddyListener.js
#	src/core.lib/src/listeners/NodeIKernelFileAssistantListener.js
#	src/core.lib/src/listeners/NodeIKernelGroupListener.js
#	src/core.lib/src/listeners/NodeIKernelLoginListener.js
#	src/core.lib/src/listeners/NodeIKernelMsgListener.js
#	src/core.lib/src/listeners/NodeIKernelProfileListener.js
#	src/core.lib/src/listeners/NodeIKernelRobotListener.js
#	src/core.lib/src/listeners/NodeIKernelSessionListener.js
#	src/core.lib/src/listeners/NodeIKernelStorageCleanListener.js
#	src/core.lib/src/listeners/index.js
#	src/core.lib/src/services/common.js
#	src/core.lib/src/services/index.js
#	src/core.lib/src/sessionConfig.js
#	src/core.lib/src/utils/config.js
#	src/core.lib/src/utils/db.js
#	src/core.lib/src/utils/rkey.js
#	src/core.lib/src/wrapper.js
2024-05-12 18:00:42 +08:00
linyuchen
eeeae449b4 update core.lib 2024-05-12 18:00:23 +08:00
linyuchen
17c10a7ba2 update core.lib 2024-05-12 17:59:25 +08:00
手瓜一十雪
69f4383678 feat: try add reboot 2024-05-12 17:56:57 +08:00
linyuchen
07852a7295 fix: Log filename add milliseconds 2024-05-12 17:56:42 +08:00
手瓜一十雪
20b7e9b6b5 fix:build error 2024-05-12 16:59:03 +08:00
手瓜一十雪
75f43ccea4 chore: sync core 2024-05-12 16:56:07 +08:00
手瓜一十雪
59e5785e93 fix: build 2024-05-12 16:55:01 +08:00
手瓜一十雪
b38f52dba9 chore: sync core 2024-05-12 16:46:35 +08:00
手瓜一十雪
2a6b17a48e fix: try support win7 2024-05-12 16:21:04 +08:00
手瓜一十雪
a6c056a894 fix: SendGroupNotice Image Unlink 2024-05-12 15:49:53 +08:00
手瓜一十雪
5c3442a71f feat: 扩展SendGroupNotice 2024-05-12 15:27:02 +08:00
手瓜一十雪
390253242f build: 1.3.5-beta1 2024-05-12 15:21:35 +08:00
手瓜一十雪
9ab80fe1ac feat: Api SendGroupNotice 2024-05-12 12:07:51 +08:00
手瓜一十雪
91fdd09e7a docs: 2024-05-12 00:41:06 +08:00
手瓜一十雪
db5bd5c8a4 chore: 1.3.2 version 2024-05-11 14:42:49 +08:00
手瓜一十雪
ef94c2fe7c chore: remove debug code 2024-05-11 14:30:36 +08:00
手瓜一十雪
72a25ed8e1 docs: change fix image recv 2024-05-11 14:24:11 +08:00
手瓜一十雪
eb065e218f build: 1.3.2-beta7 2024-05-11 14:23:36 +08:00
手瓜一十雪
33426736fc docs: change 2024-05-11 13:51:01 +08:00
手瓜一十雪
896658d5ce build: 1.3.2-beta6 2024-05-11 13:45:41 +08:00
linyuchen
b14135ed72 refactor: Use remote rkey 2024-05-11 13:43:07 +08:00
linyuchen
a1baf2e32d Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/onebot11/action/extends/GetFriendWithCategory.ts
#	src/onebot11/action/types.ts
2024-05-11 13:42:05 +08:00
linyuchen
f9aa2d3bce refactor: Use remote rkey 2024-05-11 13:41:09 +08:00
手瓜一十雪
c95d0e0696 build: 1.3.2-beta5 2024-05-11 13:34:04 +08:00
手瓜一十雪
ad4b84d446 build: 1.3.2-beta3 2024-05-11 13:10:34 +08:00
手瓜一十雪
3e27d5fcb0 fix:roboot file 2024-05-11 13:06:35 +08:00
手瓜一十雪
48a100f49a feat: reboot-uncomplete 2024-05-11 10:51:07 +08:00
linyuchen
698649f981 Merge remote-tracking branch 'origin/main' 2024-05-11 10:45:22 +08:00
手瓜一十雪
780078c3aa build: 1.3.0-beta2 2024-05-11 10:15:08 +08:00
手瓜一十雪
4c25e4ddee build: 1.3.2-beta1 2024-05-10 23:52:18 +08:00
手瓜一十雪
c0a5ac2ac5 feat: ServerRkeyWrapper 2024-05-10 23:40:07 +08:00
student_2333
0435409870 fix 2024-05-10 21:41:06 +08:00
student_2333
c521269409 fix: custom music card content 2024-05-10 21:38:39 +08:00
linyuchen
1e252b7e4c Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/core.lib/src/adapters/NodeIDependsAdapter.js
#	src/core.lib/src/adapters/NodeIDispatcherAdapter.js
#	src/core.lib/src/adapters/NodeIGlobalAdapter.js
#	src/core.lib/src/adapters/index.js
#	src/core.lib/src/apis/file.js
#	src/core.lib/src/apis/friend.js
#	src/core.lib/src/apis/group.js
#	src/core.lib/src/apis/index.js
#	src/core.lib/src/apis/msg.js
#	src/core.lib/src/apis/sign.js
#	src/core.lib/src/apis/user.js
#	src/core.lib/src/apis/webapi.js
#	src/core.lib/src/core.js
#	src/core.lib/src/data.js
#	src/core.lib/src/entities/cache.js
#	src/core.lib/src/entities/constructor.js
#	src/core.lib/src/entities/group.js
#	src/core.lib/src/entities/index.js
#	src/core.lib/src/entities/msg.js
#	src/core.lib/src/entities/notify.js
#	src/core.lib/src/entities/user.js
#	src/core.lib/src/external/hook.js
#	src/core.lib/src/index.js
#	src/core.lib/src/listeners/NodeIKernelBuddyListener.js
#	src/core.lib/src/listeners/NodeIKernelFileAssistantListener.js
#	src/core.lib/src/listeners/NodeIKernelGroupListener.js
#	src/core.lib/src/listeners/NodeIKernelLoginListener.js
#	src/core.lib/src/listeners/NodeIKernelMsgListener.js
#	src/core.lib/src/listeners/NodeIKernelProfileListener.js
#	src/core.lib/src/listeners/NodeIKernelRobotListener.js
#	src/core.lib/src/listeners/NodeIKernelSessionListener.js
#	src/core.lib/src/listeners/NodeIKernelStorageCleanListener.js
#	src/core.lib/src/listeners/index.js
#	src/core.lib/src/services/common.js
#	src/core.lib/src/services/index.js
#	src/core.lib/src/sessionConfig.js
#	src/core.lib/src/utils/config.js
#	src/core.lib/src/utils/db.js
#	src/core.lib/src/wrapper.js
2024-05-10 21:35:49 +08:00
linyuchen
d72b1edc48 chore: build core.lib 2024-05-10 21:35:14 +08:00
手瓜一十雪
f7307e8e01 chore: sync core 2024-05-10 21:32:22 +08:00
手瓜一十雪
127905f04b docs: change 2024-05-10 20:29:37 +08:00
手瓜一十雪
261c6dabd5 feat: 扩展GetFriendCategory Api 2024-05-10 20:27:38 +08:00
手瓜一十雪
cae84bbf02 style: rename DataRuntime to WebUiDataRuntime 2024-05-10 17:55:29 +08:00
手瓜一十雪
cdb2bc52fa feat: add BuddyProfileLikeReq Type 2024-05-09 23:17:33 +08:00
手瓜一十雪
cd2972eee0 chore: sync core 2024-05-09 23:15:32 +08:00
手瓜一十雪
4036aa8d0e chore: version 2024-05-09 23:06:55 +08:00
手瓜一十雪
52c6927c44 chore: release script 2024-05-09 18:46:32 +08:00
Version
a16e0a21a2 chore:version change 2024-05-09 10:42:30 +00:00
手瓜一十雪
e796b21157 chore: version 2024-05-09 17:50:20 +08:00
手瓜一十雪
1c6bc478b4 build: 1.3.0-beta5 2024-05-09 17:05:11 +08:00
手瓜一十雪
98f39c6388 docs: change 2024-05-09 17:00:38 +08:00
手瓜一十雪
570c83571b build: 1.3.0-beta4 2024-05-09 16:55:38 +08:00
手瓜一十雪
c0c38d89e0 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-09 16:55:12 +08:00
手瓜一十雪
b866cfc03c fix: Group Into Member Info 2024-05-09 16:54:32 +08:00
手瓜一十雪
28c2755b37 docs: change thank list 2024-05-09 15:29:31 +08:00
手瓜一十雪
57bfc5c73a docs: change version 2024-05-09 12:48:25 +08:00
手瓜一十雪
0f3f7d53a3 docs: change 2024-05-09 00:10:41 +08:00
手瓜一十雪
529e50fd7f build: 1.3.0-beta3 2024-05-08 22:34:01 +08:00
手瓜一十雪
2fa283f91d buid: 1.3.0-beta3 2024-05-08 22:33:00 +08:00
手瓜一十雪
029a9ade93 build: 1.3.0-beta2 2024-05-08 21:42:23 +08:00
手瓜一十雪
f1ca8b15c8 feat:webui finish 2024-05-08 21:40:30 +08:00
手瓜一十雪
4d8edd5da9 fix:webui config some value 2024-05-08 21:29:40 +08:00
手瓜一十雪
6c63990653 fix: redirect html 2024-05-08 21:12:03 +08:00
手瓜一十雪
5b521409c6 fix: asset not load 2024-05-08 21:00:53 +08:00
手瓜一十雪
3268fc1014 fix: QQ Login Check 2024-05-08 20:54:43 +08:00
手瓜一十雪
19afb4941b feat: webui auth 2024-05-08 20:33:48 +08:00
手瓜一十雪
40e5111d41 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-08 20:11:30 +08:00
手瓜一十雪
a3a40e1e74 feat: webui finish without auth 2024-05-08 20:10:33 +08:00
手瓜一十雪
101caa6826 docs: add qrcode expired 2024-05-08 20:01:19 +08:00
手瓜一十雪
875fed8d77 fix: qrcode expired try 2024-05-08 19:59:42 +08:00
手瓜一十雪
69e28eb000 feat: qrcode expired try 2024-05-08 19:43:33 +08:00
手瓜一十雪
e5d3a8360c fix:config 2024-05-08 18:45:45 +08:00
手瓜一十雪
4545d9285b feat: webui finish!! 2024-05-08 18:37:11 +08:00
手瓜一十雪
6702024805 fix: webui getConfig 2024-05-08 18:31:30 +08:00
手瓜一十雪
78bad4842b style: webui 2024-05-08 18:24:24 +08:00
手瓜一十雪
b9a913cfed feat: Ui Config 2024-05-08 18:11:38 +08:00
手瓜一十雪
6f5a6f353f feat: get config 2024-05-08 15:42:22 +08:00
手瓜一十雪
790c4f589d feat: Login HeartBeat 2024-05-08 15:07:20 +08:00
手瓜一十雪
cd1bd3461f fix: GetQuickList 2024-05-08 14:46:51 +08:00
手瓜一十雪
0280dcd6a8 fix: webui Confi&webui Login 2024-05-08 14:29:18 +08:00
手瓜一十雪
fc337292bc feat: add QQLogin 2024-05-07 22:51:43 +08:00
手瓜一十雪
fb1daa0e21 fix 2024-05-07 22:45:36 +08:00
手瓜一十雪
579b9dc0c2 fix: WebUiConfig 2024-05-07 22:44:55 +08:00
手瓜一十雪
dedd0be352 feat:QQLogin Api 2024-05-07 22:35:15 +08:00
手瓜一十雪
1c7d9c3513 fix:webui login 2024-05-07 22:26:17 +08:00
手瓜一十雪
0c7dfe2af4 fix 2024-05-07 22:16:11 +08:00
手瓜一十雪
8d1351a8a3 fix:login 2024-05-07 22:15:07 +08:00
手瓜一十雪
e6e68a6036 feat: signCredential 2024-05-07 22:11:52 +08:00
手瓜一十雪
24658edc45 fix:webui auth ratelimit 2024-05-07 22:04:21 +08:00
手瓜一十雪
09eaa3116a feat:fix 2024-05-07 21:47:52 +08:00
手瓜一十雪
e9bff466b5 fix:port use 2024-05-07 21:24:49 +08:00
手瓜一十雪
5d77f50160 feat:webui-test 2024-05-07 21:17:31 +08:00
手瓜一十雪
2ab91e363f feat: auth api router 2024-05-07 21:06:04 +08:00
手瓜一十雪
34d881426f fear: webui quick login 2024-05-07 20:50:25 +08:00
手瓜一十雪
13ecaa0ad4 feat:webui log 2024-05-07 20:08:59 +08:00
手瓜一十雪
ce6185b1f7 feat: webui set config 2024-05-07 19:57:23 +08:00
手瓜一十雪
2cfde6b75a fix: webui not login get config 2024-05-07 19:55:11 +08:00
手瓜一十雪
37d0354751 feat: webui OB11Config 2024-05-07 19:48:25 +08:00
linyuchen
0a0edcf203 build: v1.3.0-beta1 2024-05-07 16:28:28 +08:00
linyuchen
d6aad2ea28 build-1.3.0-beta1 2024-05-07 16:27:26 +08:00
linyuchen
63084506ee chore(build): Update core.lib 2024-05-07 16:26:52 +08:00
手瓜一十雪
c5d313574f feat: webui OB11Config 2024-05-07 12:31:30 +08:00
手瓜一十雪
caab998212 feat: webui getQrcode 2024-05-07 12:23:58 +08:00
linyuchen
aa037cc3d9 doc: Update changelog 2024-05-07 08:42:48 +08:00
linyuchen
642bffe374 chore: rollback version 2024-05-07 08:13:56 +08:00
linyuchen
d682b154fc build: fix auto download image, fix rkey error 2024-05-07 08:12:12 +08:00
手瓜一十雪
d4a06d98cf Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-06 23:02:26 +08:00
手瓜一十雪
856b5e16b1 feat: webui LoginStatus 2024-05-06 23:02:00 +08:00
linyuchen
a0aa208860 Merge remote-tracking branch 'origin/main' 2024-05-06 22:53:53 +08:00
linyuchen
037a11e04f chore: Update submodule core 2024-05-06 22:53:38 +08:00
手瓜一十雪
bd8a1d715f feat: login handler 2024-05-06 22:52:57 +08:00
手瓜一十雪
54ab1dc091 feat: webui Login Router 2024-05-06 22:40:21 +08:00
手瓜一十雪
9471e63857 feat: webui login limit 2024-05-06 22:24:27 +08:00
手瓜一十雪
fa4a403f38 feat: webui auth helper 2024-05-06 22:11:13 +08:00
手瓜一十雪
d608d65bf4 fix:useport try 2024-05-06 21:46:43 +08:00
手瓜一十雪
c0f2df172a feat: webui config 2024-05-06 21:34:17 +08:00
手瓜一十雪
788ef5d81c chore: web ui/api move 2024-05-06 21:12:34 +08:00
手瓜一十雪
1c6b5cffe1 feat: webuiapi init 2024-05-06 21:10:37 +08:00
手瓜一十雪
c04382b623 chore: sync core repo 2024-05-06 20:59:30 +08:00
linyuchen
0bbe51f8fd fix: rkey cached 2024-05-06 19:45:20 +08:00
linyuchen
ff7d7d15a0 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/core
2024-05-06 19:44:50 +08:00
linyuchen
4b3d083d3a fix: rkey cached 2024-05-06 19:44:36 +08:00
linyuchen
a566dd390b fix: rkey cached 2024-05-06 19:44:25 +08:00
手瓜一十雪
7d1442da04 build: 1.3.0-disable webui 2024-05-06 17:49:12 +08:00
手瓜一十雪
17fc982f55 build: 1.3.0-beta2 2024-05-06 17:01:16 +08:00
手瓜一十雪
ba417e2274 build: 1.3.0-beta1 2024-05-06 16:06:16 +08:00
手瓜一十雪
d345094b75 fix:rkey 2024-05-06 16:05:15 +08:00
手瓜一十雪
6da477480d feat: sync core 2024-05-06 16:04:29 +08:00
手瓜一十雪
e274088c06 feat:webui index 2024-05-06 15:12:27 +08:00
手瓜一十雪
1bcaa73c5c fix: webui style 2024-05-06 12:36:02 +08:00
手瓜一十雪
ca94e8f621 fix: webui ui 2024-05-06 12:32:21 +08:00
手瓜一十雪
1c4e198f59 fix 2024-05-06 12:30:26 +08:00
手瓜一十雪
fdd13f9c66 fix:Login 2024-05-05 22:49:56 +08:00
手瓜一十雪
4333ab624e fix: version check 2024-05-05 21:41:36 +08:00
手瓜一十雪
9fe1eb3a42 remove: webui log 2024-05-05 21:29:09 +08:00
linyuchen
ad251a7682 fix: http download filename special character 2024-05-05 20:05:52 +08:00
linyuchen
1fa740de2d refactor: OB11Message add filed message_seq 2024-05-05 19:40:26 +08:00
linyuchen
466b89064a Merge remote-tracking branch 'origin/main' 2024-05-05 19:25:37 +08:00
linyuchen
2748cb0ba3 refactor: Moehoo和QQ版本绑定,不再兼容多个版本 2024-05-05 19:25:17 +08:00
手瓜一十雪
aef0d5bdde Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-05 15:51:39 +08:00
手瓜一十雪
c71e8f024a chore:sync core 2024-05-05 15:51:23 +08:00
手瓜一十雪
9411f07321 fix:docs 2024-05-05 15:45:05 +08:00
手瓜一十雪
9b2a5c9bbf feat: ChangeLog 2024-05-05 15:44:38 +08:00
手瓜一十雪
2b275523a0 fix: webui api 2024-05-05 15:34:07 +08:00
手瓜一十雪
31fe2f6da4 fix: webui build 2024-05-05 15:17:17 +08:00
手瓜一十雪
f95db623a5 feat: webui style 2024-05-05 14:39:16 +08:00
手瓜一十雪
a46313e483 fix:webui-style 2024-05-05 14:35:49 +08:00
手瓜一十雪
31c330826e feat: webui-test-0 2024-05-05 14:32:48 +08:00
手瓜一十雪
c4cf800142 fix: webui-10 2024-05-05 14:14:27 +08:00
手瓜一十雪
b64a2b0006 fix:webui-9 2024-05-05 14:11:51 +08:00
手瓜一十雪
a3702f2270 fix: webapi config 2024-05-05 14:04:29 +08:00
手瓜一十雪
d221b1d470 fix: webui - 8 2024-05-05 13:49:08 +08:00
手瓜一十雪
0b22a6bc1d fix: webui-7 2024-05-05 13:45:44 +08:00
手瓜一十雪
07e8acd003 fix: remove unuse 2024-05-05 13:42:43 +08:00
手瓜一十雪
9fce617c57 fix: webui-6 2024-05-05 13:40:54 +08:00
手瓜一十雪
8d5c736975 fix: webui-6 2024-05-05 13:36:53 +08:00
手瓜一十雪
4ccec05186 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-05 13:28:30 +08:00
手瓜一十雪
a4f456f002 fix: webui-5 2024-05-05 13:28:16 +08:00
linyuchen
fbdb941c27 Merge remote-tracking branch 'origin/main' 2024-05-05 13:26:52 +08:00
linyuchen
a41cd42e8d build-1.2.1-beta1,fix: webapi群成员列表加入缓存,表情回应兼容int类型emoji_id 2024-05-05 13:26:33 +08:00
手瓜一十雪
77521e4627 feat: webui-4 2024-05-05 13:23:05 +08:00
手瓜一十雪
b6a1242bac feat:webui-3 2024-05-05 13:03:56 +08:00
手瓜一十雪
2f325cfe26 feat:webui-2 2024-05-05 13:01:23 +08:00
手瓜一十雪
193b0ad0f0 feat: webui-1 2024-05-05 12:57:32 +08:00
手瓜一十雪
ed476b7793 fix 2024-05-05 12:43:32 +08:00
linyuchen
720fd94b7f Merge remote-tracking branch 'origin/main' 2024-05-04 23:24:41 +08:00
linyuchen
ff87da105c fix: /get_cookies return 2024-05-04 23:24:32 +08:00
手瓜一十雪
a875e65536 doc: change 2024-05-04 23:23:45 +08:00
手瓜一十雪
0b2c6bb662 style&feat: cache cookies&group member 2024-05-04 23:22:21 +08:00
手瓜一十雪
e44e2fbbb7 fix 2024-05-04 22:41:37 +08:00
手瓜一十雪
b3c93644fd fix 2024-05-04 22:32:22 +08:00
手瓜一十雪
a56b7ff636 fix 2024-05-04 22:26:36 +08:00
linyuchen
c724236930 fix: Get group member list no_cache 2024-05-04 22:09:46 +08:00
linyuchen
4853320b2b Update submodule 2024-05-04 22:02:08 +08:00
linyuchen
ba1acb6ac1 Merge remote-tracking branch 'origin/main' 2024-05-04 21:57:02 +08:00
linyuchen
f32a6320fc remove webapi get group members 2024-05-04 21:56:45 +08:00
手瓜一十雪
9f914ce36a change: toDo 2024-05-04 18:13:30 +08:00
手瓜一十雪
b037644e5a chore: release script 2024-05-03 21:51:42 +08:00
linyuchen
afd8c59f83 style: eslint 2024-05-03 21:34:16 +08:00
linyuchen
8aa4af3e91 Merge remote-tracking branch 'origin/main' 2024-05-03 21:29:30 +08:00
linyuchen
630a8a2b97 doc: update 2024-05-03 21:29:14 +08:00
手瓜一十雪
dc34c4d00c fix 2024-05-03 21:22:16 +08:00
linyuchen
fb42729dec doc: update 2024-05-03 21:06:50 +08:00
手瓜一十雪
b06989216a fix 2024-05-03 21:03:13 +08:00
手瓜一十雪
e5144f08cd fix 2024-05-03 21:00:17 +08:00
手瓜一十雪
c4a60190e8 fix 2024-05-03 20:44:04 +08:00
手瓜一十雪
efe9e4fa4c fix 2024-05-03 20:34:32 +08:00
Version
45800b1559 chore:version change 2024-05-03 12:29:17 +00:00
linyuchen
b0b2b8104f build: update core.lib 2024-05-03 20:27:46 +08:00
linyuchen
8dbc012825 Merge remote-tracking branch 'origin/main' 2024-05-03 20:26:55 +08:00
手瓜一十雪
a434176063 docs: change 2024-05-03 20:26:25 +08:00
linyuchen
a013f750c7 fix: Sync get_group_notice return structure to gocq 2024-05-03 20:24:25 +08:00
手瓜一十雪
aa1f49d02f build: 1.2.0-beta18 2024-05-03 20:16:37 +08:00
手瓜一十雪
7125a26309 update: appid 2024-05-03 20:13:08 +08:00
手瓜一十雪
329a35ebf0 docs: change 2024-05-03 18:06:05 +08:00
手瓜一十雪
d30043f595 build: 1.2.0-beta17 2024-05-03 16:59:10 +08:00
手瓜一十雪
745dfa1911 build: 1.2.0-beta16 2024-05-03 14:36:39 +08:00
手瓜一十雪
76203f49a7 fix 2024-05-03 14:06:23 +08:00
手瓜一十雪
870a915377 fix 2024-05-03 14:02:40 +08:00
linyuchen
c174fce227 chore: update submodule core 2024-05-03 13:04:49 +08:00
linyuchen
2b6e42e919 Merge remote-tracking branch 'origin/main' 2024-05-03 13:04:19 +08:00
linyuchen
df73e1e5a3 refactor: ordered onebot11.json keys 2024-05-03 13:04:02 +08:00
手瓜一十雪
3e902311d4 docs: change 2024-05-03 12:58:15 +08:00
linyuchen
64a0037265 update core.lib 2024-05-03 12:34:35 +08:00
linyuchen
bcd4e38093 Merge remote-tracking branch 'origin/main' 2024-05-03 12:32:04 +08:00
linyuchen
181a77d627 fix: Unset other admin notice not work 2024-05-03 12:31:35 +08:00
手瓜一十雪
b353595ba9 build: 1.2.0-beta15 2024-05-03 12:24:39 +08:00
linyuchen
75e3bb4f17 docs: update README.md 2024-05-03 11:12:36 +08:00
linyuchen
d2fa9192d4 chore: build core 2024-05-03 10:00:29 +08:00
linyuchen
4bcadc2de4 chore: build core 2024-05-03 09:59:25 +08:00
linyuchen
8ddff74260 update submodule core 2024-05-03 01:18:27 +08:00
linyuchen
95940fdb64 update core.lib 2024-05-03 01:01:05 +08:00
linyuchen
9cd5708948 feat: forward single msg
feat: statistic sent receive msg count by api get_status
2024-05-03 00:59:07 +08:00
linyuchen
d361683d79 Merge remote-tracking branch 'origin/main' 2024-05-02 23:29:35 +08:00
手瓜一十雪
9ad17a01f7 fix 2024-05-02 23:06:57 +08:00
手瓜一十雪
22ca1d443c fix 2024-05-02 23:05:14 +08:00
linyuchen
2662e875ca refactor: send music card
feat: send mface
2024-05-02 22:23:59 +08:00
手瓜一十雪
8ae0d07ec1 chore: sync core to core.lib 2024-05-02 21:42:13 +08:00
手瓜一十雪
76a9edb7f5 build: 1.2.0-beta14 2024-05-02 21:34:38 +08:00
手瓜一十雪
0ccb464e5b feat: add log 2024-05-02 21:26:14 +08:00
手瓜一十雪
bef600efa2 fix 2024-05-02 21:25:29 +08:00
手瓜一十雪
58a182cd33 docs: change 2024-05-02 20:55:54 +08:00
手瓜一十雪
aa43334f41 Build: 1.2.0-beta12 2024-05-02 20:47:29 +08:00
手瓜一十雪
a2a4c97f6c fix: sync core 2024-05-02 18:47:01 +08:00
手瓜一十雪
4217ba99fd build: 1.2.0-beta12 2024-05-02 18:33:52 +08:00
linyuchen
589725f5cc build: v1.2.0.beta11.修复linux图链 2024-05-02 18:23:44 +08:00
linyuchen
3fea4602f8 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/core
#	src/core.lib/src/adapters/NodeIDependsAdapter.js
#	src/core.lib/src/adapters/NodeIDispatcherAdapter.js
#	src/core.lib/src/adapters/NodeIGlobalAdapter.js
#	src/core.lib/src/adapters/index.js
#	src/core.lib/src/apis/file.js
#	src/core.lib/src/apis/friend.js
#	src/core.lib/src/apis/group.js
#	src/core.lib/src/apis/index.js
#	src/core.lib/src/apis/msg.js
#	src/core.lib/src/apis/sign.js
#	src/core.lib/src/apis/user.js
#	src/core.lib/src/apis/webapi.js
#	src/core.lib/src/apis/window.js
#	src/core.lib/src/core.js
#	src/core.lib/src/data.js
#	src/core.lib/src/entities/cache.js
#	src/core.lib/src/entities/constructor.js
#	src/core.lib/src/entities/group.js
#	src/core.lib/src/entities/index.js
#	src/core.lib/src/entities/msg.js
#	src/core.lib/src/entities/notify.js
#	src/core.lib/src/entities/user.js
#	src/core.lib/src/external/hook.js
#	src/core.lib/src/index.js
#	src/core.lib/src/listeners/NodeIKernelBuddyListener.js
#	src/core.lib/src/listeners/NodeIKernelFileAssistantListener.js
#	src/core.lib/src/listeners/NodeIKernelGroupListener.js
#	src/core.lib/src/listeners/NodeIKernelLoginListener.js
#	src/core.lib/src/listeners/NodeIKernelMsgListener.js
#	src/core.lib/src/listeners/NodeIKernelProfileListener.js
#	src/core.lib/src/listeners/NodeIKernelRobotListener.js
#	src/core.lib/src/listeners/NodeIKernelSessionListener.js
#	src/core.lib/src/listeners/NodeIKernelStorageCleanListener.js
#	src/core.lib/src/listeners/index.js
#	src/core.lib/src/services/common.js
#	src/core.lib/src/services/index.js
#	src/core.lib/src/sessionConfig.js
#	src/core.lib/src/utils/config.js
#	src/core.lib/src/utils/db.js
#	src/core.lib/src/wrapper.js
2024-05-02 18:20:52 +08:00
linyuchen
8ea6aae875 build: v1.2.0.beta11.修复linux图链 2024-05-02 18:17:41 +08:00
linyuchen
2c70b2af68 build: v1.2.0.beta11.修复linux图链 2024-05-02 18:17:33 +08:00
手瓜一十雪
54a2cbcb42 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-05-02 18:16:19 +08:00
手瓜一十雪
fdef821c60 style: lint 2024-05-02 18:16:03 +08:00
手瓜一十雪
dfa798a35d fix 2024-05-02 18:15:26 +08:00
手瓜一十雪
39b8eb6ff1 script: mail change 2024-05-02 18:13:32 +08:00
手瓜一十雪
6cf71f67a9 update: core.lib 2024-05-02 18:11:59 +08:00
手瓜一十雪
f2e919725e build: 1.2.0-beta11 2024-05-02 18:08:26 +08:00
linyuchen
869599126e Update README.md 2024-05-02 03:33:29 +08:00
linyuchen
3b1b200f6f Update README.md 2024-05-02 01:28:24 +08:00
linyuchen
93c646e3e4 Update README.md 2024-05-02 01:27:37 +08:00
手瓜一十雪
3552f80a21 fix 2024-05-01 23:56:43 +08:00
linyuchen
66d3a63998 build: v1.2.0.beta10 2024-05-01 19:12:30 +08:00
linyuchen
6447825978 build: v1.2.0.beta10 2024-05-01 18:48:47 +08:00
linyuchen
18b7df9fca feat: get_group_list, get_friend_list no_cache 2024-05-01 18:46:13 +08:00
linyuchen
c3781cab96 Merge remote-tracking branch 'origin/main' 2024-05-01 18:35:57 +08:00
linyuchen
776098dba6 fix: listener crash 2024-05-01 18:35:40 +08:00
linyuchen
8d1b4f61e7 fix: listener crash 2024-05-01 18:35:16 +08:00
手瓜一十雪
c13e2bdb96 build: 1.2.0-beta9 2024-05-01 17:24:32 +08:00
手瓜一十雪
4682254157 build: 1.2.0-beta.8 2024-05-01 16:14:13 +08:00
linyuchen
d7ca6b9213 refactor AsyncQueue 2024-05-01 16:04:23 +08:00
linyuchen
4a76afbde8 refactor AsyncQueue 2024-05-01 16:03:53 +08:00
手瓜一十雪
a68349c23a build: 1.2.0-beta 2024-05-01 14:18:36 +08:00
linyuchen
920e005366 build: v1.2.0.beta7 2024-05-01 12:22:48 +08:00
linyuchen
659f339020 build: v1.2.0.beta7 2024-05-01 12:19:50 +08:00
linyuchen
3ee2d463af Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/core
2024-05-01 12:18:07 +08:00
linyuchen
686ddb5460 优化rkey获取 2024-05-01 12:17:30 +08:00
linyuchen
e5d62488b7 优化rkey获取 2024-05-01 12:17:25 +08:00
linyuchen
eb93dd5005 fix: no_cache param of api get_group_list 2024-04-30 18:49:55 +08:00
手瓜一十雪
6999d02d2d fix 2024-04-30 12:11:28 +08:00
手瓜一十雪
790e2b1427 docs: change 2024-04-29 21:08:26 +08:00
手瓜一十雪
a29c7cdfe4 build: 1.2.0-beta 2024-04-29 20:53:52 +08:00
手瓜一十雪
6b7cd692a6 build: 1.2.0-beta 2024-04-29 20:50:50 +08:00
手瓜一十雪
4d3925872a fix 2024-04-29 20:49:31 +08:00
linyuchen
2bd0f6934a update core.lib 2024-04-29 20:35:22 +08:00
linyuchen
51783f17ed Merge remote-tracking branch 'origin/main' 2024-04-29 20:32:59 +08:00
linyuchen
ce3aef3526 update core.lib 2024-04-29 20:32:39 +08:00
手瓜一十雪
ee70afdfbb build: 1.2.0-beta 2024-04-29 20:22:30 +08:00
手瓜一十雪
d96c4a56a2 fix 2024-04-29 20:21:36 +08:00
手瓜一十雪
9a39513dea fix 2024-04-29 17:57:11 +08:00
手瓜一十雪
8f22d63315 build: 1.2.0-beta 2024-04-29 16:58:07 +08:00
手瓜一十雪
7f2a5bb95e fix 2024-04-29 16:46:16 +08:00
手瓜一十雪
0118dbd5fb fix 2024-04-29 16:21:21 +08:00
手瓜一十雪
09405de26c fix 2024-04-29 15:55:28 +08:00
手瓜一十雪
efa5ee0e57 fix 2024-04-29 15:48:50 +08:00
手瓜一十雪
80d558f37a fix 2024-04-29 15:37:12 +08:00
linyuchen
901adc3fc7 update submodule core ref 2024-04-29 15:17:41 +08:00
linyuchen
01417be954 refactor: optimize msg db 2024-04-29 15:17:24 +08:00
linyuchen
43b780cbe6 refactor: show quick login error 2024-04-29 11:46:03 +08:00
linyuchen
e83f36a12f refactor: show quick login error 2024-04-29 11:45:43 +08:00
linyuchen
77e3fc4ab0 refactor: get image url 2024-04-29 11:45:26 +08:00
linyuchen
eafd1adaba build: test music sign 2024-04-29 00:24:52 +08:00
linyuchen
6b53abb7c9 Merge remote-tracking branch 'origin/main' 2024-04-29 00:24:26 +08:00
linyuchen
f994c5d284 build: test music sign 2024-04-29 00:24:12 +08:00
手瓜一十雪
6fda220107 fix: typo 2024-04-29 00:14:50 +08:00
手瓜一十雪
da290ed1c3 fix: typo 2024-04-29 00:14:12 +08:00
手瓜一十雪
7e9cd80a1c fix 2024-04-29 00:13:39 +08:00
linyuchen
379b7413d8 refactor: music sign 2024-04-29 00:11:58 +08:00
linyuchen
9181a4df16 Merge remote-tracking branch 'origin/main' 2024-04-29 00:11:51 +08:00
linyuchen
df982afd51 refactor: music sign 2024-04-29 00:11:32 +08:00
手瓜一十雪
5c2c3b4317 build: 1.2.0-beta 2024-04-28 23:11:48 +08:00
手瓜一十雪
92d1309103 fix 2024-04-28 22:26:28 +08:00
手瓜一十雪
c43ee3c1d6 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-28 22:15:32 +08:00
手瓜一十雪
e0726e5283 fix 2024-04-28 21:58:23 +08:00
手瓜一十雪
5f3775584b fix 2024-04-28 21:55:22 +08:00
手瓜一十雪
77873d63c5 fix 2024-04-28 21:44:43 +08:00
手瓜一十雪
9e6b09765e fix 2024-04-28 21:43:41 +08:00
手瓜一十雪
1ad6ea4049 add: GetEssenceMsg 2024-04-28 21:43:15 +08:00
手瓜一十雪
7c41da1cb9 docs:change 2024-04-28 21:32:49 +08:00
linyuchen
adcf4bfc53 build: test prod 2024-04-28 21:05:30 +08:00
linyuchen
7a6321a9c1 Merge remote-tracking branch 'origin/main' 2024-04-28 21:03:11 +08:00
linyuchen
d56b27a7b0 build: test prod 2024-04-28 21:02:56 +08:00
手瓜一十雪
ed7657ab5f build: 1.2.0-beta 2024-04-28 20:55:24 +08:00
手瓜一十雪
a414838416 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-28 20:54:21 +08:00
手瓜一十雪
93646577dc fix:ref to main 2024-04-28 20:53:34 +08:00
linyuchen
46db66038e build: test core.lib 2024-04-28 20:49:54 +08:00
linyuchen
efc4e9ce56 build: pre-release 2024-04-28 20:40:37 +08:00
linyuchen
8d5eac7f80 Merge remote-tracking branch 'origin/main' 2024-04-28 20:39:33 +08:00
linyuchen
7b94e49b81 fix: log send msg group name 2024-04-28 20:39:16 +08:00
手瓜一十雪
c35fd4bdc8 build:test 2024-04-28 20:38:44 +08:00
手瓜一十雪
98590e2d90 fix 2024-04-28 20:36:52 +08:00
手瓜一十雪
e6da0e5dd5 fix 2024-04-28 20:36:30 +08:00
手瓜一十雪
cb2baf747d fix 2024-04-28 20:32:37 +08:00
手瓜一十雪
a2f2eb03ce Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-28 20:30:56 +08:00
手瓜一十雪
5c6acbb780 fix 2024-04-28 20:30:53 +08:00
linyuchen
1be7031199 update core 2024-04-28 19:46:09 +08:00
linyuchen
ed6399bde9 Merge remote-tracking branch 'origin/main' 2024-04-28 19:40:44 +08:00
linyuchen
6709893781 refactor: sent msg log 2024-04-28 19:40:28 +08:00
手瓜一十雪
686a426cda fix 2024-04-28 19:37:26 +08:00
linyuchen
4f90bc7813 refactor: sent msg log 2024-04-28 19:34:16 +08:00
linyuchen
e307b289ae Merge remote-tracking branch 'origin/main' 2024-04-28 18:54:03 +08:00
手瓜一十雪
3baeff61a7 chore: 新增手动打包测试 2024-04-28 18:44:32 +08:00
手瓜一十雪
93ab9d12ee fix 2024-04-28 18:42:04 +08:00
手瓜一十雪
36e1317792 fix 2024-04-28 18:32:12 +08:00
手瓜一十雪
fa3e90a021 fix 2024-04-28 18:23:59 +08:00
手瓜一十雪
782a69cf13 fix 2024-04-28 18:22:58 +08:00
linyuchen
d495f351c0 Merge remote-tracking branch 'origin/main' 2024-04-28 18:22:27 +08:00
linyuchen
30bd3d2d52 refactor: ws log 2024-04-28 18:22:17 +08:00
手瓜一十雪
ff5a21cca5 fix 2024-04-28 18:21:36 +08:00
linyuchen
f8abb73c92 refactor: get friends, get groups, get group members, get group member 2024-04-28 18:14:21 +08:00
linyuchen
e97f323d9a Update musicSignUrl to docs & onebot11 config 2024-04-28 13:08:56 +08:00
linyuchen
3d27a4c05d doc: typo 2024-04-28 12:58:34 +08:00
linyuchen
9dbc13dbe4 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	CHANGELOG.md
2024-04-28 12:57:38 +08:00
linyuchen
c46a4c75b1 feat: Music sign 2024-04-28 12:56:51 +08:00
手瓜一十雪
0bded73f16 fix 2024-04-28 12:50:24 +08:00
手瓜一十雪
1333733684 build: change 2024-04-28 12:49:04 +08:00
手瓜一十雪
003be934de fix 2024-04-28 12:40:43 +08:00
手瓜一十雪
93ef20d358 fix 2024-04-28 12:34:13 +08:00
手瓜一十雪
94e1a6f0ba fix 2024-04-28 12:30:03 +08:00
手瓜一十雪
8661d09d57 fix 2024-04-28 11:19:09 +08:00
手瓜一十雪
0e5e21dc4e fix 2024-04-28 10:13:39 +08:00
linyuchen
3b25c4987c Merge remote-tracking branch 'origin/main' 2024-04-28 09:18:26 +08:00
linyuchen
2212eb17aa optimize: send record msg error 2024-04-28 09:18:04 +08:00
手瓜一十雪
768bac1db8 fix: remove darwin build 2024-04-28 00:02:26 +08:00
手瓜一十雪
3aef75085f build: new 2024-04-27 23:51:09 +08:00
手瓜一十雪
ce8bef638a fix:token workflow 2024-04-27 23:50:34 +08:00
手瓜一十雪
f0a0c90304 feat:设置自身在线状态 2024-04-27 23:18:03 +08:00
手瓜一十雪
cd6c32b21d docs:CHANGELOG 2024-04-27 22:54:05 +08:00
手瓜一十雪
b31876d2d1 fix 2024-04-27 22:52:57 +08:00
手瓜一十雪
ebab8a190e fix 2024-04-27 22:10:54 +08:00
手瓜一十雪
1b7ce8e7a5 fix 2024-04-27 22:10:07 +08:00
linyuchen
646bb6bd79 doc: change log 2024-04-27 21:21:52 +08:00
linyuchen
5a84b97ca9 fix: first get image rkey 2024-04-27 21:15:24 +08:00
linyuchen
6d41b5a4a1 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/core
2024-04-27 21:07:32 +08:00
linyuchen
a8bce36f3b fix: first get image rkey 2024-04-27 21:06:58 +08:00
手瓜一十雪
ac2132f8ba fix 2024-04-27 20:50:28 +08:00
手瓜一十雪
cab4b57abe fix 2024-04-27 20:49:41 +08:00
手瓜一十雪
938fb30359 fix 2024-04-27 20:49:00 +08:00
linyuchen
62346d7d9d Merge remote-tracking branch 'origin/main' 2024-04-27 20:14:26 +08:00
linyuchen
cf1e5ca64b doc: changelog 2024-04-27 20:13:59 +08:00
手瓜一十雪
7d2d683d96 fix 2024-04-27 20:12:42 +08:00
手瓜一十雪
fe5042f1c3 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-27 20:11:53 +08:00
手瓜一十雪
a1dd76aee0 fix 2024-04-27 20:09:08 +08:00
linyuchen
d1c91be167 feat: 表情回应api和上报 2024-04-27 19:51:59 +08:00
linyuchen
9748d99f34 optimize: log 2024-04-27 19:21:54 +08:00
linyuchen
c90ffbeb62 refactor: config使用QQ号区分 2024-04-27 19:06:39 +08:00
linyuchen
eb7fafeabf optimize: 不支持的消息类型提示 2024-04-27 19:06:08 +08:00
linyuchen
3e50629462 optimize: log 2024-04-27 18:41:03 +08:00
linyuchen
65281a4554 optimize: log 2024-04-27 18:40:45 +08:00
手瓜一十雪
454ec09d6a fix 2024-04-27 17:58:00 +08:00
手瓜一十雪
60e3c6858d build: test 2024-04-27 17:53:31 +08:00
手瓜一十雪
f911f5b4fc fix:update win appid to 23159 2024-04-27 17:49:00 +08:00
手瓜一十雪
ad1694d291 fix 2024-04-27 17:42:28 +08:00
手瓜一十雪
1130965f26 fix 2024-04-27 17:41:49 +08:00
linyuchen
fe1f28998b fix: listener proxy 2024-04-27 17:05:43 +08:00
linyuchen
45727fce05 Merge remote-tracking branch 'origin/main' 2024-04-27 17:05:16 +08:00
linyuchen
d5c23e5add fix: listener proxy 2024-04-27 17:05:09 +08:00
linyuchen
e3a8285f6c fix: listener proxy 2024-04-27 17:04:53 +08:00
手瓜一十雪
a791221cf6 fix 2024-04-27 16:28:43 +08:00
手瓜一十雪
b954d9b403 fix 2024-04-27 16:05:59 +08:00
手瓜一十雪
5e7e24a271 chore: script move 2024-04-27 15:13:53 +08:00
手瓜一十雪
ffb1e598f6 fix 2024-04-27 15:06:59 +08:00
linyuchen
bc2da8a645 fix: log config 2024-04-27 12:20:28 +08:00
linyuchen
6f2be3ed30 fix: log config 2024-04-27 12:20:17 +08:00
linyuchen
033a7bffb3 refactor: log 2024-04-27 11:45:24 +08:00
linyuchen
f2b2ea61a1 refactor: core 2024-04-27 01:03:13 +08:00
linyuchen
6f0783acc4 refactor: core 2024-04-27 01:02:58 +08:00
linyuchen
ce60aa3823 Merge remote-tracking branch 'origin/main' 2024-04-27 00:53:01 +08:00
linyuchen
8075e70606 refactor: core 2024-04-27 00:51:10 +08:00
linyuchen
4402fc2d0a refactor: core 2024-04-27 00:50:08 +08:00
手瓜一十雪
3e3ecda551 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-26 22:56:49 +08:00
手瓜一十雪
50beb8f346 fix: Linux Script CRLF to LF 2024-04-26 22:56:38 +08:00
手瓜一十雪
8e033e3e06 fix 2024-04-26 22:53:46 +08:00
linyuchen
dc029a318b refactor: core addListener 2024-04-26 20:21:41 +08:00
手瓜一十雪
8e91bc2c8e fix 2024-04-26 18:46:12 +08:00
linyuchen
0ff5b4e90b refactor: core 2024-04-26 13:55:35 +08:00
手瓜一十雪
20dec19bfe Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-26 11:30:51 +08:00
手瓜一十雪
d261fbff26 fix 2024-04-26 11:30:05 +08:00
手瓜一十雪
6594b33bcc docs: change 2024-04-26 08:09:15 +08:00
linyuchen
a1bb6cc1b1 refactor: mface url 2024-04-26 00:16:36 +08:00
linyuchen
7ce195b68e Merge remote-tracking branch 'origin/main'
# Conflicts:
#	src/onebot11/index.ts
2024-04-25 22:11:10 +08:00
手瓜一十雪
16d8d04aaa fix 2024-04-25 20:40:32 +08:00
手瓜一十雪
59565f7d90 fix 2024-04-25 18:34:40 +08:00
手瓜一十雪
43784a2495 fix 2024-04-25 18:29:31 +08:00
手瓜一十雪
3811d7469e fix 2024-04-25 18:15:40 +08:00
手瓜一十雪
c72b40a1e1 fix 2024-04-25 18:15:03 +08:00
linyuchen
f00933969d refactor: get image rkey 2024-04-25 15:13:26 +08:00
linyuchen
759adc45e3 refactor: mark msg as read 2024-04-25 15:13:11 +08:00
linyuchen
27ecf78372 refactor: mark msg as read 2024-04-25 15:12:53 +08:00
手瓜一十雪
c91b83a7ba docs: change 2024-04-25 10:38:01 +08:00
手瓜一十雪
39373ee63a Merge pull request #8 from Fripine/feat/add_FriendAddNoticeEvent
feat: add FriendAddNoticeEvent
2024-04-25 10:27:01 +08:00
Fripine
2db64c69ae Update constructor.ts 2024-04-25 00:54:36 +08:00
linyuchen
a699b71c02 fix: check rkey 2024-04-24 21:05:51 +08:00
linyuchen
6c07d22cda Merge remote-tracking branch 'origin/main'
# Conflicts:
#	package.json
2024-04-24 21:04:34 +08:00
linyuchen
a2ee900ed5 fix: check rkey 2024-04-24 21:03:47 +08:00
Fripine
e709f31b99 Update constructor.ts 2024-04-24 19:19:36 +08:00
Fripine
35afb12756 Update constructor.ts 2024-04-24 18:48:03 +08:00
Fripine
9bed9fe162 Update constructor.ts 2024-04-24 17:47:01 +08:00
Fripine
4ff5553804 construct FriendAddEvent 2024-04-24 17:38:35 +08:00
Fripine
32213be7a7 add FriendAddEvent 2024-04-24 17:34:22 +08:00
Fripine
84894a73e1 Create OB11FriendAddNoticeEvent.ts 2024-04-24 17:32:31 +08:00
手瓜一十雪
b6ea185ce7 build: test 2024-04-24 15:31:51 +08:00
手瓜一十雪
814ac0f731 fix:package 2024-04-24 12:20:41 +08:00
手瓜一十雪
a40bb29da3 fix: build 2024-04-24 12:19:30 +08:00
手瓜一十雪
e9b90079c0 fix 2024-04-24 12:13:34 +08:00
手瓜一十雪
dba383c27e fix 2024-04-24 12:09:26 +08:00
手瓜一十雪
42059b5817 fix 2024-04-24 12:01:32 +08:00
手瓜一十雪
f92a17c01b fix 2024-04-24 12:00:13 +08:00
手瓜一十雪
d6552ce333 fix: native hook debug to release 2024-04-24 10:19:28 +08:00
手瓜一十雪
0db89bde5a docs: noify CQCode 2024-04-24 10:14:27 +08:00
手瓜一十雪
56a12185d4 Merge pull request #7 from initialencounter/patch-1
feat(onebot11):  Improve error handling in JSON parsing
2024-04-24 00:07:55 +08:00
风宝宝
c40170db5d feat(onebot11): Improve error handling in JSON parsing
发生错误直接被 catch 掉了,没有提示,[使用docker启动后,请求被重置](https://github.com/NapNeko/NapCat-Docker/issues/8)
2024-04-23 21:33:09 +08:00
linyuchen
1df3e9c414 doc: update 2024-04-23 18:58:51 +08:00
linyuchen
b1570df8b9 update core 2024-04-23 18:39:58 +08:00
linyuchen
023fd1ce36 Merge remote-tracking branch 'origin/main' 2024-04-23 18:38:44 +08:00
linyuchen
a7fe74bc0c fix: rkey 2024-04-23 18:38:13 +08:00
手瓜一十雪
26c9abd9da docs: rf install with build
移除编译安装教程 因不指定参数编译和下载到的一样 指定后编译需要编译环境 例如msvc/gcc
2024-04-21 19:17:22 +08:00
linyuchen
a5e34645c5 fix: ffmpeg path for video.ts 2024-04-20 08:21:48 +08:00
linyuchen
b2831c0a19 doc: update 2024-04-20 08:21:03 +08:00
linyuchen
648c1ea0f9 fix: reading qq version 2024-04-19 11:31:47 +08:00
linyuchen
9cd927e06a doc: update README.md 2024-04-19 10:28:20 +08:00
linyuchen
4272413f55 Merge remote-tracking branch 'origin/main' 2024-04-19 10:27:40 +08:00
linyuchen
e1711b7af6 doc: update README.md 2024-04-19 10:27:26 +08:00
Version
f7d3f27d45 chore:version change 2024-04-18 12:17:53 +00:00
linyuchen
3a7a47f82d style: eslint 2024-04-18 20:17:06 +08:00
linyuchen
cc211706d5 fix: check version catch 2024-04-18 20:10:09 +08:00
linyuchen
22f74be4cd try send markdown 2024-04-18 18:23:20 +08:00
linyuchen
5a00d14f94 Merge remote-tracking branch 'origin/main' 2024-04-18 17:44:06 +08:00
linyuchen
ecb4e7bf9f fix: ws token not work 2024-04-18 17:43:43 +08:00
linyuchen
56e5b546e1 Update README.md 2024-04-17 21:44:40 +08:00
linyuchen
272f5a2f4f Update README.md 2024-04-17 21:33:25 +08:00
linyuchen
ddcbe78a01 chore: release.yml 2024-04-17 18:40:49 +08:00
linyuchen
00b6c964e2 chore: release not need git submodule 2024-04-17 18:37:11 +08:00
linyuchen
d7d2b06ecc chore: change action token 2024-04-17 18:27:08 +08:00
Version
fafc59360d chore:version change 2024-04-17 09:50:56 +00:00
linyuchen
19e105785e update core 2024-04-17 17:38:02 +08:00
linyuchen
b87ac09e43 update core 2024-04-17 17:37:23 +08:00
linyuchen
af9092d7c7 fix: send forward msg 2024-04-17 17:35:14 +08:00
linyuchen
24a1ffd652 fix: http server cors 2024-04-17 17:06:24 +08:00
linyuchen
662813cc58 fix: postLoginStatus on error 2024-04-17 17:01:29 +08:00
linyuchen
d890b78290 refactor: auto_escape of send msg 2024-04-16 23:22:37 +08:00
linyuchen
58747d7d4a fix: delete group 2024-04-16 23:10:29 +08:00
linyuchen
0773a4f39c feat: Support post url params 2024-04-16 23:09:56 +08:00
linyuchen
66cc7f8a1f feat: http heart 2024-04-16 20:58:29 +08:00
linyuchen
01ab40bf4a Merge remote-tracking branch 'origin/main' 2024-04-16 20:28:26 +08:00
linyuchen
4c09147fd1 fix: cq code auto escape
fix: get groups no cache
2024-04-16 20:28:05 +08:00
手瓜一十雪
f9f426d788 build:friend history 2024-04-16 18:50:39 +08:00
手瓜一十雪
ff8fa1bf31 fix 2024-04-16 18:39:15 +08:00
手瓜一十雪
59f99e4f6a fix 2024-04-16 18:36:51 +08:00
手瓜一十雪
7449ce9c3b fix 2024-04-16 18:32:02 +08:00
手瓜一十雪
f6bc8f0a1f fix 2024-04-16 18:26:50 +08:00
手瓜一十雪
4d10b8cdee Revert "chore:version change"
This reverts commit 36ce3b08fe.
2024-04-16 14:13:22 +08:00
手瓜一十雪
5a61c5de09 limit:workflow 2024-04-16 14:10:31 +08:00
手瓜一十雪
f84d0db811 fix 2024-04-16 14:01:05 +08:00
Version
36ce3b08fe chore:version change 2024-04-16 05:57:37 +00:00
手瓜一十雪
da8ea5b545 Revert "chore:version change"
This reverts commit 034d12c347.
2024-04-16 13:57:04 +08:00
手瓜一十雪
fad3dbf4cd fix 2024-04-16 13:56:07 +08:00
Version
034d12c347 chore:version change 2024-04-16 05:54:20 +00:00
手瓜一十雪
c94dbf1d9a fix:workflow 2024-04-16 13:53:14 +08:00
手瓜一十雪
e516687a9e fix 2024-04-16 13:50:01 +08:00
手瓜一十雪
4a2f77b0a6 fix 2024-04-16 13:49:32 +08:00
手瓜一十雪
7b29ecba71 fix 2024-04-16 13:47:42 +08:00
手瓜一十雪
11241b8e07 Revert "chore:version change"
This reverts commit 52bbd1f20b.
2024-04-16 13:44:22 +08:00
Version
52bbd1f20b chore:version change 2024-04-16 05:42:48 +00:00
手瓜一十雪
4044750515 fix 2024-04-16 13:42:22 +08:00
手瓜一十雪
b670c546b9 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-16 13:38:00 +08:00
手瓜一十雪
f37bbf93cb fix 2024-04-16 13:37:42 +08:00
linyuchen
87311ab41a Merge remote-tracking branch 'origin/main' 2024-04-16 13:28:15 +08:00
linyuchen
ecb4d1845c update core 2024-04-16 13:28:05 +08:00
手瓜一十雪
35c232ab25 fix 2024-04-16 13:27:33 +08:00
linyuchen
df0be2e251 Merge remote-tracking branch 'origin/main' 2024-04-16 13:25:25 +08:00
linyuchen
871b3a102b refactor: recall get_group_list if groups is empty 2024-04-16 13:25:12 +08:00
手瓜一十雪
02299e3892 fix 2024-04-16 13:17:30 +08:00
手瓜一十雪
6af4d6f5b8 fix 2024-04-16 13:14:09 +08:00
手瓜一十雪
4fb5700367 fix 2024-04-16 13:12:33 +08:00
手瓜一十雪
8579276381 fix 2024-04-16 13:10:07 +08:00
手瓜一十雪
7ba60b22c5 fix 2024-04-16 13:06:07 +08:00
linyuchen
031932f41c Merge remote-tracking branch 'origin/main' 2024-04-16 13:00:02 +08:00
linyuchen
079d0a89b1 fix: tsconfig path alias 2024-04-16 12:59:52 +08:00
手瓜一十雪
c4fdce6d64 fix 2024-04-16 12:55:16 +08:00
手瓜一十雪
5604c2b29f Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-16 12:55:05 +08:00
手瓜一十雪
74b5ab2b47 fix 2024-04-16 12:53:37 +08:00
linyuchen
c29cbfe123 Merge remote-tracking branch 'origin/main' 2024-04-16 12:51:42 +08:00
手瓜一十雪
6fe5cb1ffd remove 2024-04-16 12:51:12 +08:00
linyuchen
7edd5a7a8e Merge remote-tracking branch 'origin/main' 2024-04-16 12:50:22 +08:00
linyuchen
c1edc1b99b fix: Send empty forward msg 2024-04-16 12:50:14 +08:00
手瓜一十雪
4d1d890f72 fix 2024-04-16 12:47:36 +08:00
手瓜一十雪
fe0f82fa2b fix:checkVesion 2024-04-16 12:46:37 +08:00
手瓜一十雪
84083a65a8 fix:checkVesion 2024-04-16 12:45:07 +08:00
手瓜一十雪
fc91c6bc08 fix 2024-04-16 12:43:39 +08:00
手瓜一十雪
09120171ba fix 2024-04-16 12:42:07 +08:00
手瓜一十雪
a362f920dc fix:workflow 2024-04-16 12:41:18 +08:00
手瓜一十雪
9d7729f548 fix:workflow 2024-04-16 12:21:50 +08:00
手瓜一十雪
ed56e177cf chore:workflow version 2024-04-16 11:49:44 +08:00
手瓜一十雪
9db28bd502 fix:version output 2024-04-16 11:43:14 +08:00
linyuchen
aded70eb2e Create LICENSE 2024-04-16 10:27:32 +08:00
手瓜一十雪
dfbad85465 re:version 2024-04-16 10:02:40 +08:00
手瓜一十雪
52076fe182 chore: version 2024-04-16 08:50:48 +08:00
linyuchen
5575c3cb13 style: remove unused import 2024-04-15 22:44:48 +08:00
linyuchen
637d32efff fix: calculate qq level 2024-04-15 22:44:29 +08:00
linyuchen
fd54658e53 todo: retry get groups if groups length is 0 2024-04-15 22:42:31 +08:00
linyuchen
2f39a8d76e refactor: rename extends api folder 2024-04-15 22:39:31 +08:00
linyuchen
6a3e793500 style: comment unused function 2024-04-15 22:39:06 +08:00
linyuchen
3b3ffeda6b script: gen version 2024-04-15 22:36:06 +08:00
linyuchen
f7d92a3b11 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	script/napcat.bat
2024-04-15 22:31:18 +08:00
linyuchen
d9d9ba8bf1 fix: Support Onebot v11 get_forward_msg 2024-04-15 17:39:18 +08:00
手瓜一十雪
f5d9090183 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-15 11:26:19 +08:00
手瓜一十雪
705ecd1ef1 fix:build 2024-04-15 11:26:11 +08:00
linyuchen
08b5266a86 Update README.md 2024-04-15 11:12:28 +08:00
linyuchen
ecc4846ba8 Update README.md 2024-04-15 11:11:51 +08:00
手瓜一十雪
4aab705d11 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-15 11:08:45 +08:00
手瓜一十雪
4615a68bcc style:lint 2024-04-15 11:08:31 +08:00
linyuchen
bf6934e8ac Update README.md 2024-04-15 10:55:23 +08:00
手瓜一十雪
af8c304bd4 fix:build workflow 2024-04-15 10:54:36 +08:00
手瓜一十雪
51dac5a5a8 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-15 10:53:04 +08:00
手瓜一十雪
56463d9e36 chore: issue 2024-04-15 10:52:41 +08:00
linyuchen
a6a339dc59 Update README.md 2024-04-15 10:52:34 +08:00
手瓜一十雪
8423304ab5 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-04-15 10:48:26 +08:00
手瓜一十雪
bb7408dbe9 chore:workflow-build 2024-04-15 10:48:08 +08:00
linyuchen
7eff4dcf02 Update README.md 2024-04-15 10:44:31 +08:00
linyuchen
d7ee3fec3d Update README.md 2024-04-15 10:36:48 +08:00
linyuchen
d66ab7d389 chore: start bat 2024-04-15 01:38:46 +08:00
376 changed files with 14927 additions and 3085 deletions

View File

@@ -5,7 +5,7 @@ root = true
# Unix-style newlines with a newline ending every file # Unix-style newlines with a newline ending every file
[*] [*]
end_of_line = lf end_of_line = lf|crlf
insert_final_newline = true insert_final_newline = true
# Matches multiple files with brace expansion notation # Matches multiple files with brace expansion notation
@@ -18,4 +18,4 @@ indent_style = space
indent_size = 2 indent_size = 2
# Unfortunately, EditorConfig doesn't support space configuration inside import braces directly. # Unfortunately, EditorConfig doesn't support space configuration inside import braces directly.
# You'll need to rely on your linter/formatter like ESLint or Prettier for that. # You'll need to rely on your linter/formatter like ESLint or Prettier for that.

View File

@@ -1 +1 @@
VITE_BUILD_TYPE = Production VITE_BUILD_TYPE = Production

View File

@@ -1,9 +1,10 @@
module.exports = { module.exports = {
'env': { 'env': {
'browser': true,
'es2021': true, 'es2021': true,
'node': true 'node': true
}, },
'ignorePatterns': ['src/core/'], 'ignorePatterns': ['src/core/', 'src/core.lib/','src/proto/'],
'extends': [ 'extends': [
'eslint:recommended', 'eslint:recommended',
'plugin:@typescript-eslint/recommended' 'plugin:@typescript-eslint/recommended'

81
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,81 @@
name: Bug 反馈
description: 报告可能的 NapCat 异常行为
title: '[BUG] '
labels: bug
body:
- type: markdown
attributes:
value: |
欢迎来到 NapCat 的 Issue Tracker请填写以下表格来提交 Bug。
在提交新的 Bug 反馈前,请确保您:
* 已经搜索了现有的 issues并且没有找到可以解决您问题的方法
* 不与现有的某一 issue 重复
- type: input
id: system-version
attributes:
label: 系统版本
description: 运行 QQNT 的系统版本
placeholder: Windows 10 Pro Workstation 22H2
validations:
required: true
- type: input
id: qqnt-version
attributes:
label: QQNT 版本
description: 可在 QQNT 的「关于」的设置页中找到
placeholder: 9.9.7-21804
validations:
required: true
- type: input
id: napcat-version
attributes:
label: NapCat 版本
description: 可在 LiteLoaderQQNT 的设置页或是 QQNT 的设置页侧栏中找到
placeholder: 1.0.0
validations:
required: true
- type: input
id: onebot-client-version
attributes:
label: OneBot 客户端
description: 连接至 NapCat 的客户端版本信息
placeholder: Overflow 2.16.0-2cf7991-SNAPSHOT
validations:
required: true
- type: textarea
id: what-happened
attributes:
label: 发生了什么?
description: 填写你认为的 NapCat 的不正常行为
validations:
required: true
- type: textarea
id: how-reproduce
attributes:
label: 如何复现
description: 填写应当如何操作才能触发这个不正常行为
placeholder: |
1. xxx
2. xxx
3. xxx
validations:
required: true
- type: textarea
id: what-expected
attributes:
label: 期望的结果?
description: 填写你认为 NapCat 应当执行的正常行为
validations:
required: true
- type: textarea
id: napcat-log
attributes:
label: NapCat 运行日志
description: 粘贴相关日志内容到此处
render: shell
- type: textarea
id: onebot-client-log
attributes:
label: OneBot 客户端运行日志
description: 粘贴 OneBot 客户端的相关日志内容到此处
render: shell

74
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: "Build"
on:
workflow_dispatch:
push:
branches:
- main
permissions: write-all
jobs:
build-linux:
if: ${{ startsWith(github.event.head_commit.message, 'build:') }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target_platform: [linux]
target_arch: [x64, arm64]
steps:
- name: Clone Main Repository
uses: actions/checkout@v4
with:
repository: 'NapNeko/NapCatQQ'
submodules: true
ref: main
token: ${{ secrets.NAPCAT_BUILD }}
- name: Use Node.js 20.X
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Build NuCat Linux
run: |
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
npm run build:prod
cd dist
npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
cd ..
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }}
path: dist
build-win32:
if: ${{ startsWith(github.event.head_commit.message, 'build:') }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target_platform: [win32]
target_arch: [x64]
steps:
- name: Clone Main Repository
uses: actions/checkout@v4
with:
repository: 'NapNeko/NapCatQQ'
submodules: true
ref: main
token: ${{ secrets.NAPCAT_BUILD }}
- name: Use Node.js 20.X
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Build NuCat Linux
run: |
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
npm run build:prod
cd dist
npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
cd ..
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }}
path: dist

View File

@@ -1,30 +1,60 @@
name: "release" name: "release"
on: on:
push: push:
tags: tags:
- "v*" - "v*"
permissions: write-all
jobs: jobs:
check-version:
runs-on: ubuntu-latest
steps:
- name: Clone Repository
uses: actions/checkout@v4
with:
ref: main
token: ${{ secrets.GITHUB_TOKEN }}
- name: Extract version from tag
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Use Node.js 20.X
uses: actions/setup-node@v4
with:
node-version: 20.x
- name: Check Version
run: |
ls
node ./script/checkVersion.cjs
sh ./checkVersion.sh
build-linux: build-linux:
needs: [check-version]
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
target_platform: [linux,darwin] target_platform: [linux]
target_arch: [x64, arm64] target_arch: [x64, arm64]
steps: steps:
- name: Clone Main Repository - name: Clone Main Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
repository: 'NapNeko/NapCat' repository: 'NapNeko/NapCatQQ'
submodules: true submodules: true
ref: main
token: ${{ secrets.NAPCAT_BUILD }} token: ${{ secrets.NAPCAT_BUILD }}
- name: Use Node.js 20.X - name: Use Node.js 20.X
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20.x node-version: 20.x
- name: Build NuCat Linux - name: Build NuCat Linux
run: | run: |
export NAPCAT_BUILDSYS=${{ matrix.target_platform }}
export NAPCAT_BUILDARCH=${{ matrix.target_arch }}
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }} npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
npm run build:prod npm run build:prod
cd dist cd dist
@@ -37,6 +67,7 @@ jobs:
path: dist path: dist
build-win32: build-win32:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [check-version]
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@@ -46,25 +77,32 @@ jobs:
- name: Clone Main Repository - name: Clone Main Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
repository: 'NapNeko/NapCat' repository: 'NapNeko/NapCatQQ'
submodules: true submodules: true
ref: main
token: ${{ secrets.NAPCAT_BUILD }} token: ${{ secrets.NAPCAT_BUILD }}
- name: Use Node.js 20.X - name: Use Node.js 20.X
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 20.x node-version: 20.x
- name: Build NuCat Linux - name: Build NuCat Linux
run: | run: |
export NAPCAT_BUILDSYS=${{ matrix.target_platform }}
export NAPCAT_BUILDARCH=${{ matrix.target_arch }}
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }} npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
npm run build:prod npm run build:prod
cd dist cd dist
npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }} npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
cd .. cd ..
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }} name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }}
path: dist path: dist
release-napcat: release-napcat:
needs: [build-win32,build-linux] needs: [build-win32,build-linux]
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -78,15 +116,23 @@ jobs:
base=$(basename "$dir") base=$(basename "$dir")
zip -r "${base}.zip" "$dir" zip -r "${base}.zip" "$dir"
done done
- name: Extract version from tag
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Clone Changes Log
run: curl -o CHANGELOG.md https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/docs/changelogs/CHANGELOG.v${{ env.VERSION }}.md
- name: Create Release Draft and Upload Artifacts - name: Create Release Draft and Upload Artifacts
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
with: with:
name: NapCat V0.0.0 name: NapCat V${{ env.VERSION }}
token: ${{ secrets.NAPCAT_BUILD }} token: ${{ secrets.GITHUB_TOKEN }}
body_path: CHANGELOG.md
files: | files: |
NapCat.win32.x64.zip NapCat.win32.x64.zip
NapCat.linux.x64.zip NapCat.linux.x64.zip
NapCat.linux.arm64.zip NapCat.linux.arm64.zip
NapCat.darwin.x64.zip # NapCat.darwin.x64.zip
NapCat.darwin.arm64.zip # NapCat.darwin.arm64.zip
draft: true draft: true

7
.gitignore vendored
View File

@@ -1,11 +1,11 @@
# Logs
# Develop # Develop
node_modules/ node_modules/
package-lock.json package-lock.json
pnpm-lock.yaml
out/ out/
dist/ dist/
src/core.lib/common/ /src/core.lib/common/
/localdebug/
# Editor # Editor
.vscode/* .vscode/*
@@ -14,3 +14,4 @@ src/core.lib/common/
# Build # Build
*.db *.db
checkVersion.sh

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 NapCatQQ
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

153
README.md
View File

@@ -4,159 +4,30 @@
## 项目介绍 ## 项目介绍
NapCatQQ瞌睡猫QQ不准叫我NCQQ像睡着了一样在后台低占用运行的无头(没有界面)的NTQQ NapCatQQ 是基于 PC NTQQ 本体实现一套无头 Bot 框架。
目前测试在 Windows 上表现优秀,最低可达只占用内存 **20M**左右 名字寓意 瞌睡猫QQ像睡着了一样在后台低占用运行的无需GUI界面的NTQQ。
由于 Linux 上的 QQ 图形依赖较多,会导致内存占用小高,大约 **100+M**,目前正在研究如何优化 ## 如何使用
具体占用会因人而异QQ 群、好友越多占用越高 可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 页面下载最新版本
## 下载 **首次使用** 请务必前往 [官方文档](https://napneko.github.io/) 查看使用文档与教程
前往 Release 页面下载最新版本
## 启动
NapCat 是基于 官方NTQQ 实现的Bot框架因此先需要安装官方QQ
*如果没有安装 QQ 请往后翻查看安装方法*
修改 `config/onebot11.json`内容,并重名为 `onebot11_<你的QQ号>.json`,如`onebot11_1234567.json`
json 配置内容参数解释:
```json5
{
// 是否启用http服务如果启用可以通过http接口发送消息
"enableHttp": false,
// http服务端口
"httpPort": 3000,
// 是否启用正向websocket服务
"enableWs": false,
// 正向websocket服务端口
"wsPort": 3001,
// 是否启用反向websocket服务
"enableWsReverse": false,
// 反向websocket对接的地址, 如["ws://127.0.0.1:8080/onebot/v11/ws"]
"wsReverseUrls": [],
// 是否启用http上报服务
"enableHttpPost": false,
// http上报地址, 如["http://127.0.0.1:8080/onebot/v11/http"]
"httpPostUrls": [],
// http上报密钥可为空
"httpSecret": "",
// 消息上报格式array为消息组string为cq码字符串
"messagePostFormat": "array",
// 是否上报自己发送的消息
"reportSelfMessage": false,
// 是否开启调试模式开启后上报消息会携带一个raw字段为原始消息内容
"debug": false,
// 调用get_file接口时如果获取不到url则使用base64字段返回文件内容
"enableLocalFile2Url": true,
// ws心跳间隔单位毫秒
"heartInterval": 30000,
// access_token可以为空
"token": ""
}
```
### Windows 启动
运行`powershell ./napcat.ps1`, 或者 `napcat.bat`,如果出现乱码,可以尝试运行`napcat_utf8.ps1`
### Linux 启动
运行`napcat.sh`
## 使用无需扫码快速登录
前提是你已经成功登录过QQ可以加参数` -q <你的QQ>` 进行登录,如`napcat.sh -q 1234567`
## 安装
### Linux安装
#### 安装 Linux QQ(22741),已经安装了的可以跳过
目前还在研究怎么精简安装暂时只能安装官方QQ整体依赖
```bash
下载QQ的deb包
[deb x86版本](https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.7_240403_amd64_01.deb)
[deb arm版本](https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.7_240403_arm64_01.deb)
[rpm x86版本](https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.7_240403_x86_64_01.rpm)
[rpm arm版本](https://dldir1.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.7_240403_aarch64_01.rpm)
```
```bash
sudo apt install ./qq.deb
```
```bash
安装QQ的依赖
sudo apt install libgbm1 libasound2
```
### Windows 安装
#### 安装Windows QQ(22741),已经安装了的可以跳过
[Windows版本QQ下载](https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.9_240403_x64_01.exe)
### 编译安装 NapCat
**如果你是直接下载编译好的版本,可以跳过这一步**
准备环境 [node18.18](https://nodejs.org/download/release/v18.18.2/)
```
export NODE_ENV=production
npm install
```
## 常见问题
### 二维码无法扫描
NapCat 会自动保存二维码到目录,可以手动打开图片扫描
如果没有条件访问本地目录,可以将二维码解析的 url 复制到二维码生成网站上生成二维码然后手机QQ扫描
### 语音、视频发送失败
需要配置 ffmpeg将 ffmpeg 目录加入环境变量,如果仍未生效,可以修改 napcat 启动脚本加入 FFMPEG_PATH 变量指定到 ffmpeg
程序的完整路径
如 Windows 上修改 napcat.ps1在第一行加入
```powershell
$env:FFMPEG_PATH="d:\ffmpeg\bin\ffmpeg.exe"
```
### 出现 error code v2:-1 之类的提示
不用管,这是正常现象,是因为 QQ 本身的问题,不影响使用
<!-- ## 项目声明
QQ群545402644
-->
## 声明
* 请不要在无关地方宣传NapCatQQ本项目只是用于学习 node 相关知识,切勿用于违法用途 * 请不要在无关地方宣传NapCatQQ本项目只是用于学习 node 相关知识,切勿用于违法用途
* NapCat 不会收集用户隐私信息,但是未来可能会为了更好的利于 NapCat 的优化会收集一些设备信息,如 cpu 架构,系统版本等 * NapCat 不会收集用户隐私信息,但是未来可能会为了更好的利于 NapCat 的优化会收集一些设备信息,如 cpu 架构,系统版本等
## 相关链接 ## 相关链接
[Telegram Link](https://t.me/+nLZEnpne-pQ1OWFl)
[TG群](https://t.me/+nLZEnpne-pQ1OWFl)
## 鸣谢名单 ## 鸣谢名单
[OpenShamrock]()
[Lagrange]() [Lagrange](https://github.com/LagrangeDev/Lagrange.Core)
<!--
QQ群545402644
-->

View File

@@ -0,0 +1,17 @@
# v1.3.3
QQ Version: Windows 9.9.9-23424 / Linux 3.2.7-23361
## 修复与优化
* 尝试修复多开崩溃问题
* 修复群列表更新问题
* 修复兼容性问题支持Win7
* 修复下载 http 资源缺少UA
* 优化少量消息合并转发速度
* 修复加载群通知时出现 getUserDetailInfo timeout 导致程序崩溃
## 新增与调整
* 新增设置群公告 Api: /_send_group_notice
* 新增重启实现 包括重启快速登录/普通重启 副作用: 原进程 无法清理
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,18 @@
# v1.3.5
QQ Version: Windows 9.9.9-23424 / Linux 3.2.7-23361
## 修复与优化
* 优化启动脚本
* 修复非管理时群成员减少事件上报 **无法获取操作者与操作类型**
* 修复快速重启进程清理问题
* 优化配置文件格式 支持自动更新配置 但仍然建议 **备份配置**
* 修复正向反向ws多个客户端周期多次心跳问题
## 新增与调整
* 支持WebUi热重载
* 新增启动输出WEBUI秘钥
* 新增群荣誉信息 /get_group_honor_info
* 支持获取群系统消息 /get_group_system_msg
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,11 @@
# v1.3.6
QQ Version: Windows 9.9.9-23424 / Linux 3.2.7-23361
## 修复与优化
* 修复戳一戳多次上报问题
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,15 @@
# v1.3.8
QQ Version: Windows 9.9.9-23873 / Linux 3.2.7-23361
## 修复与优化
* 优化打包后体积问题
* 修复QQ等级获取
* 兼容 9.7.x 版本换行符 统一为 \n
* 修复处理加群请求 字段异常情况
* 修复退群通知问题
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,11 @@
# v1.3.9
QQ Version: Windows 9.9.10-23873 / Linux 3.2.7-23361
## 修复与优化
* 修复QQ等级获取与兼容性问题
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,12 @@
# v1.4.0
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
## 新增与调整
* 支持空间Cookies获取
* 支持获取在线设备 API /get_online_clients
* 支持图片OCR API /.ocr_image /ocr_image
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,14 @@
# v1.4.1
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 提高部分Api兼容性
* 优化日志膨胀问题
* 在线状态刷新问题修复
## 新增与调整
* 支持非管理群 本地记录时间数据 (建议 **备份配置 清空配置 重新配置**)
* 新增英译中接口 Api: /translate_en2zh
* 新增群文件管理相关扩展接口 Api: /get_group_file_count /get_group_file_list /set_group_file_folder /del_group_file /del_group_file_folder
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,12 @@
# v1.4.2
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 修复获取群文件列表Api
* 修复退群通知问题
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,11 @@
# v1.4.3
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 修复名片通知
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,10 @@
# v1.4.4
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 更新
* **重大更新:**更新了版本号
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,12 @@
# v1.4.5
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 紧急修复二维扫码问题
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,12 @@
# v1.4.6
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 优化整体稳定性
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,11 @@
# v1.4.7
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 临时扩展 Api: GoCQHTTPUploadGroupFile folder_id字段 用于选择文件夹
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,12 @@
# v1.4.8
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 优化Guid的生成方式
* 支持临时消息获取群来源
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,11 @@
# v1.4.9
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 修复接口调用问题 接口标准化 APIset_group_add_request
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,11 @@
# v1.5.0
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
## 修复与优化
* 修正各Api默认值
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -1,63 +1,66 @@
{ {
"name": "napcat", "name": "napcat",
"private": true, "private": true,
"type": "module", "type": "module",
"version": "1.0.1", "version": "1.5.0",
"scripts": { "scripts": {
"watch:dev": "vite --mode development", "watch:dev": "vite --mode development",
"watch:prod": "vite --mode production", "watch:prod": "vite --mode production",
"build:dev": "vite build --mode development", "build:dev": "vite build --mode development",
"build:prod": "vite build --mode production", "build:prod": "vite build --mode production",
"build": "npm run build:dev", "build": "npm run build:dev",
"build:core": "cd ./src/core && vite build --mode production", "build:core": "cd ./src/core && npm run build && cd ../.. && node ./script/copy-core.cjs",
"watch": "npm run watch:dev", "build:webui": "cd ./src/webui && vite build",
"debug-win": "powershell dist/napcat.ps1", "watch": "npm run watch:dev",
"lint": "eslint --fix src/**/*.{js,ts}", "debug-win": "powershell dist/napcat.ps1",
"release": "npm run build:prod", "lint": "eslint --fix src/**/*.{js,ts}",
"depend": "cd dist && npm install --omit=dev" "release": "npm run build:prod",
}, "depend": "cd dist && npm install --omit=dev"
"devDependencies": { },
"@log4js-node/log4js-api": "^1.0.2", "devDependencies": {
"@rollup/plugin-commonjs": "^25.0.7", "@log4js-node/log4js-api": "^1.0.2",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.6", "@rollup/plugin-typescript": "^11.1.6",
"@types/express": "^4.17.21", "@types/cors": "^2.8.17",
"@types/figlet": "^1.5.8", "@types/express": "^4.17.21",
"@types/fluent-ffmpeg": "^2.1.24", "@types/figlet": "^1.5.8",
"@types/node": "^20.11.30", "@types/fluent-ffmpeg": "^2.1.24",
"@types/qrcode-terminal": "^0.12.2", "@types/node": "^20.11.30",
"@types/uuid": "^9.0.8", "@types/qrcode-terminal": "^0.12.2",
"@types/ws": "^8.5.10", "@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^7.4.0", "@types/ws": "^8.5.10",
"@typescript-eslint/parser": "^7.4.0", "@typescript-eslint/eslint-plugin": "^7.4.0",
"eslint": "^8.57.0", "@typescript-eslint/parser": "^7.4.0",
"eslint-import-resolver-typescript": "^3.6.1", "eslint": "^8.57.0",
"eslint-plugin-import": "^2.29.1", "eslint-import-resolver-typescript": "^3.6.1",
"i": "^0.3.7", "eslint-plugin-import": "^2.29.1",
"javascript-obfuscator": "^4.1.0", "i": "^0.3.7",
"protobufjs-cli": "^1.1.2", "javascript-obfuscator": "^4.1.0",
"rollup": "^4.13.2", "rollup": "^4.13.2",
"rollup-plugin-dts": "^6.1.0", "rollup-plugin-dts": "^6.1.0",
"rollup-plugin-obfuscator": "^1.1.0", "rollup-plugin-obfuscator": "^1.1.0",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vite": "^5.2.6", "vite": "^5.2.6",
"vite-plugin-cp": "^4.0.8", "vite-plugin-cp": "^4.0.8",
"vite-plugin-dts": "^3.8.2", "vite-plugin-dts": "^3.8.2",
"vite-tsconfig-paths": "^4.3.2" "vite-tsconfig-paths": "^4.3.2",
}, "@protobuf-ts/plugin": "^2.9.4"
"dependencies": { },
"commander": "^12.0.0", "dependencies": {
"express": "^5.0.0-beta.2", "ajv": "^8.13.0",
"file-type": "^19.0.0", "commander": "^12.0.0",
"fluent-ffmpeg": "^2.1.2", "cors": "^2.8.5",
"image-size": "^1.1.1", "express": "^5.0.0-beta.2",
"log4js": "^6.9.1", "fast-xml-parser": "^4.3.6",
"protobufjs": "^7.2.6", "file-type": "^19.0.0",
"qrcode-terminal": "^0.12.0", "fluent-ffmpeg": "^2.1.2",
"silk-wasm": "^3.3.4", "image-size": "^1.1.1",
"sqlite3": "^5.1.7", "json-schema-to-ts": "^3.1.0",
"uuid": "^9.0.1", "log4js": "^6.9.1",
"ws": "^8.16.0", "qrcode-terminal": "^0.12.0",
"yaml": "^2.4.1" "silk-wasm": "^3.3.4",
} "sqlite3": "^5.1.7",
} "uuid": "^9.0.1",
"ws": "^8.16.0"
}
}

42
script/checkVersion.cjs Normal file
View File

@@ -0,0 +1,42 @@
const fs = require("fs");
const process = require("process");
console.log("[NapCat] [CheckVersion] 开始检测当前仓库版本...");
try {
const packageJson = require("../package.json");
const currentVersion = packageJson.version;
const targetVersion = process.env.VERSION;
console.log("[NapCat] [CheckVersion] currentVersion:", currentVersion, "targetVersion:", targetVersion);
// 验证 targetVersion 格式
if (!targetVersion || typeof targetVersion !== 'string') {
console.error("[NapCat] [CheckVersion] 目标版本格式不正确或未设置!");
return;
}
// 写入脚本文件的统一函数
const writeScriptToFile = (content) => {
fs.writeFileSync("./checkVersion.sh", content, { flag: 'w' });
console.log("[NapCat] [CheckVersion] checkVersion.sh 文件已更新。");
};
if (currentVersion === targetVersion) {
// 不需要更新版本,写入一个简单的脚本
const simpleScript = "#!/bin/bash\necho \"CheckVersion Is Done\"";
writeScriptToFile(simpleScript);
} else {
// 更新版本构建安全的sed命令
const safeScriptContent = `
#!/bin/bash
git config --global user.email "bot@test.wumiao.wang"
git config --global user.name "Version"
sed -i "s/\\\"version\\\": \\\"${currentVersion}\\\"/\\\"version\\\": \\\"${targetVersion}\\\"/g" package.json
git add .
git commit -m "chore:version change"
git push -u origin main`;
writeScriptToFile(safeScriptContent);
}
} catch (error) {
console.error("[NapCat] [CheckVersion] 检测过程中发生错误:", error);
}

32
script/copy-core.cjs Normal file
View File

@@ -0,0 +1,32 @@
let fs = require('fs');
let path = require('path');
const coreDistDir = path.join(path.resolve(__dirname, '../'), 'src/core/dist/core/src');
const coreLibDir = path.join(path.resolve(__dirname, '../'), 'src/core.lib/src');
function copyDir(currentPath, outputDir) {
fs.readdir(currentPath, { withFileTypes: true }, (err, entries) => {
if (err?.errno === -4058) return;
entries.forEach(entry => {
const localBasePath = path.join(currentPath, entry.name);
const outputLocalBasePath = path.join(outputDir, entry.name);
if (entry.isDirectory()) {
// 如果是目录,递归调用
if (!fs.existsSync(outputLocalBasePath)) {
fs.mkdirSync(outputLocalBasePath, { recursive: true });
}
copyDir(localBasePath, outputLocalBasePath);
}
else{
// 如果是文件,直接复制
fs.copyFile(localBasePath, outputLocalBasePath, (err) => {
if (err) throw err;
});
}
});
});
}
copyDir(coreDistDir, coreLibDir);

21
script/gen-version.ts Normal file
View File

@@ -0,0 +1,21 @@
import fs from 'fs'
import path from 'path'
import { version } from '../src/onebot11/version'
const manifestPath = path.join(__dirname, '../package.json')
function readManifest (): any {
if (fs.existsSync(manifestPath)) {
return JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))
}
}
function writeManifest (manifest: any) {
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))
}
const manifest = readManifest()
if (version !== manifest.version) {
manifest.version = version
writeManifest(manifest)
}

3
script/napcat-custom.bat Normal file
View File

@@ -0,0 +1,3 @@
chcp 65001
set ELECTRON_RUN_AS_NODE=1
"H:\Program Files\QQNT最新版\QQ.exe" %~dp0/napcat.cjs %*

View File

@@ -15,4 +15,4 @@ for %%a in ("!RetString!") do (
set "QQPath=!pathWithoutUninstall!QQ.exe" set "QQPath=!pathWithoutUninstall!QQ.exe"
set ELECTRON_RUN_AS_NODE=1 set ELECTRON_RUN_AS_NODE=1
echo !QQPath! echo !QQPath!
"!QQPath!" ./napcat.cjs %* "!QQPath!" ./napcat.mjs %*

View File

@@ -5,11 +5,39 @@ function Get-QQpath {
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe" return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe"
} }
catch { catch {
return "D:\QQ.exe" throw "get QQ path error: $_"
} }
} }
function Select-QQPath {
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$dialogTitle = "Select QQ.exe"
$filePicker = New-Object System.Windows.Forms.OpenFileDialog
$filePicker.Title = $dialogTitle
$filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*"
$filePicker.FilterIndex = 1
$null = $filePicker.ShowDialog()
if (-not ($filePicker.FileName)) {
throw "User did not select an .exe file."
}
return $filePicker.FileName
}
$params = $args -join " " $params = $args -join " "
$QQpath = Get-QQpath Try {
$Bootfile = Join-Path $PSScriptRoot "napcat.cjs" $QQpath = Get-QQpath
}
Catch {
$QQpath = Select-QQPath
}
if (!(Test-Path $QQpath)) {
throw "provided QQ path is invalid: $QQpath"
}
$Bootfile = Join-Path $PSScriptRoot "napcat.mjs"
$env:ELECTRON_RUN_AS_NODE = 1 $env:ELECTRON_RUN_AS_NODE = 1
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& chcp 65001;& '$QQpath' $Bootfile $params}" $commandInfo = Get-Command $QQpath -ErrorAction Stop
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& chcp 65001;& '$($commandInfo.Path)' $Bootfile $params}"

View File

@@ -14,4 +14,4 @@ for %%a in ("!RetString!") do (
set "QQPath=!pathWithoutUninstall!QQ.exe" set "QQPath=!pathWithoutUninstall!QQ.exe"
set ELECTRON_RUN_AS_NODE=1 set ELECTRON_RUN_AS_NODE=1
echo !QQPath! echo !QQPath!
"!QQPath!" ./napcat.cjs %* "!QQPath!" ./napcat.mjs %*

View File

@@ -5,11 +5,39 @@ function Get-QQpath {
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe" return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe"
} }
catch { catch {
return "D:\QQ.exe" throw "get QQ path error: $_"
} }
} }
function Select-QQPath {
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$dialogTitle = "Select QQ.exe"
$filePicker = New-Object System.Windows.Forms.OpenFileDialog
$filePicker.Title = $dialogTitle
$filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*"
$filePicker.FilterIndex = 1
$null = $filePicker.ShowDialog()
if (-not ($filePicker.FileName)) {
throw "User did not select an .exe file."
}
return $filePicker.FileName
}
$params = $args -join " " $params = $args -join " "
$QQpath = Get-QQpath Try {
$Bootfile = Join-Path $PSScriptRoot "napcat.cjs" $QQpath = Get-QQpath
}
Catch {
$QQpath = Select-QQPath
}
if (!(Test-Path $QQpath)) {
throw "provided QQ path is invalid: $QQpath"
}
$Bootfile = Join-Path $PSScriptRoot "napcat.mjs"
$env:ELECTRON_RUN_AS_NODE = 1 $env:ELECTRON_RUN_AS_NODE = 1
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& '$QQpath' $Bootfile $params}" $commandInfo = Get-Command $QQpath -ErrorAction Stop
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& '$($commandInfo.Path)' $Bootfile $params}"

View File

@@ -1,4 +1,21 @@
#!/bin/bash #!/bin/bash
SCRIPT_DIR=$(realpath $(dirname "${BASH_SOURCE[0]}"))
get_script_dir() {
local script_path="${1:-$0}"
local script_dir
script_path=$(readlink -f "$script_path")
script_dir=$(dirname "$script_path")
echo "$script_dir"
}
SCRIPT_DIR=$(get_script_dir)
export ELECTRON_RUN_AS_NODE=1 export ELECTRON_RUN_AS_NODE=1
/opt/QQ/qq ${SCRIPT_DIR}/napcat.cjs $@
if ! [ -x /opt/QQ/qq ]; then
echo "Error: /opt/QQ/qq is not executable or does not exist." >&2
exit 1
fi
/opt/QQ/qq "${SCRIPT_DIR}/napcat.mjs" "$@"

View File

@@ -1,85 +0,0 @@
import {
type Friend,
type FriendRequest,
type Group,
type GroupMember, GroupNotify,
type SelfInfo
} from '@/core/qqnt/entities';
import { isNumeric } from './utils/helper';
import { log } from '@/common/utils/log';
export const selfInfo: SelfInfo = {
uid: '',
uin: '',
nick: '',
online: true
};
// groupCode -> Group
export const groups: Map<string, Group> = new Map<string, Group>();
// 群号 -> 群成员map(uid=>GroupMember)
export const groupMembers: Map<string, Map<string, GroupMember>> = new Map<string, Map<string, GroupMember>>();
// uid -> Friend
export const friends: Map<string, Friend> = new Map<string, Friend>();
export const friendRequests: Record<string, FriendRequest> = {}; // flag->FriendRequest
export const groupNotifies: Record<string, GroupNotify> = {}; // flag->GroupNotify
export const napCatError = {
ffmpegError: '',
httpServerError: '',
wsServerError: '',
otherError: 'NapCat未能正常启动请检查日志查看错误'
};
export async function getFriend(uinOrUid: string): Promise<Friend | undefined> {
uinOrUid = uinOrUid.toString();
if (isNumeric(uinOrUid)) {
const friendList = Array.from(friends.values());
return friendList.find(friend => friend.uin === uinOrUid);
} else {
return friends.get(uinOrUid);
}
}
export async function getGroup(qq: string): Promise<Group | undefined> {
const group = groups.get(qq.toString());
return group;
}
export async function getGroupMember(groupQQ: string | number, memberUinOrUid: string | number) {
groupQQ = groupQQ.toString();
memberUinOrUid = memberUinOrUid.toString();
const members = groupMembers.get(groupQQ);
if (!members) {
return null;
}
// log('getGroupMember', members);
if (isNumeric(memberUinOrUid)) {
return Array.from(members.values()).find(member => member.uin === memberUinOrUid);
} else {
return members.get(memberUinOrUid);
}
}
export async function refreshGroupMembers(groupQQ: string) {
// const group = groups.find(group => group.groupCode === groupQQ)
// if (group) {
// group.members = await NTQQGroupApi.getGroupMembers(groupQQ)
// }
}
export const uid2UinMap: Record<string, string> = {}; // 一串加密的字符串(uid) -> qq号
export function getUidByUin(uin: string) {
for (const uid in uid2UinMap) {
if (uid2UinMap[uid] === uin) {
return uid;
}
}
}
export const tempGroupCodeMap: Record<string, string> = {}; // peerUid => 群号

View File

@@ -1,17 +1,19 @@
import express, { Express, Request, Response } from 'express'; import express, { Express, Request, Response } from 'express';
import cors from 'cors';
import http from 'http'; import http from 'http';
import { log } from '../utils/log'; import { log, logDebug, logError } from '../utils/log';
import { ob11Config } from '@/onebot11/config'; import { ob11Config } from '@/onebot11/config';
type RegisterHandler = (res: Response, payload: any) => Promise<any> type RegisterHandler = (res: Response, payload: any) => Promise<any>
export abstract class HttpServerBase { export abstract class HttpServerBase {
name: string = 'LLOneBot'; name: string = 'NapCatQQ';
private readonly expressAPP: Express; private readonly expressAPP: Express;
private server: http.Server | null = null; private server: http.Server | null = null;
constructor() { constructor() {
this.expressAPP = express(); this.expressAPP = express();
this.expressAPP.use(cors());
this.expressAPP.use(express.urlencoded({ extended: true, limit: '5000mb' })); this.expressAPP.use(express.urlencoded({ extended: true, limit: '5000mb' }));
this.expressAPP.use((req, res, next) => { this.expressAPP.use((req, res, next) => {
// 兼容处理没有带content-type的请求 // 兼容处理没有带content-type的请求
@@ -21,7 +23,7 @@ export abstract class HttpServerBase {
// 调用原始的express.json()处理器 // 调用原始的express.json()处理器
originalJson(req, res, (err) => { originalJson(req, res, (err) => {
if (err) { if (err) {
log('Error parsing JSON:', err); logError('Error parsing JSON:', err);
return res.status(400).send('Invalid JSON'); return res.status(400).send('Invalid JSON');
} }
next(); next();
@@ -35,14 +37,14 @@ export abstract class HttpServerBase {
const authHeader = req.get('authorization'); const authHeader = req.get('authorization');
if (authHeader) { if (authHeader) {
clientToken = authHeader.split('Bearer ').pop() || ''; clientToken = authHeader.split('Bearer ').pop() || '';
log('receive http header token', clientToken); //logDebug('receive http header token', clientToken);
} else if (req.query.access_token) { } else if (req.query.access_token) {
if (Array.isArray(req.query.access_token)) { if (Array.isArray(req.query.access_token)) {
clientToken = req.query.access_token[0].toString(); clientToken = req.query.access_token[0].toString();
} else { } else {
clientToken = req.query.access_token.toString(); clientToken = req.query.access_token.toString();
} }
log('receive http url token', clientToken); //logDebug('receive http url token', clientToken);
} }
if (serverToken && clientToken != serverToken) { if (serverToken && clientToken != serverToken) {
@@ -51,29 +53,29 @@ export abstract class HttpServerBase {
next(); next();
} }
start(port: number) { start(port: number, host: string) {
try { try {
this.expressAPP.get('/', (req: Request, res: Response) => { this.expressAPP.get('/', (req: Request, res: Response) => {
res.send(`${this.name}已启动`); res.send(`${this.name}已启动`);
}); });
this.listen(port); this.listen(port, host);
} catch (e: any) { } catch (e: any) {
log('HTTP服务启动失败', e.toString()); logError('HTTP服务启动失败', e.toString());
// llonebotError.httpServerError = "HTTP服务启动失败, " + e.toString() // httpServerError = "HTTP服务启动失败, " + e.toString()
} }
} }
stop() { stop() {
// llonebotError.httpServerError = "" // httpServerError = ""
if (this.server) { if (this.server) {
this.server.close(); this.server.close();
this.server = null; this.server = null;
} }
} }
restart(port: number) { restart(port: number, host: string) {
this.stop(); this.stop();
this.start(port); this.start(port, host);
} }
abstract handleFailed(res: Response, payload: any, err: any): void abstract handleFailed(res: Response, payload: any, err: any): void
@@ -86,7 +88,7 @@ export abstract class HttpServerBase {
// @ts-expect-error wait fix // @ts-expect-error wait fix
if (!this.expressAPP[method]) { if (!this.expressAPP[method]) {
const err = `${this.name} register router failed${method} not exist`; const err = `${this.name} register router failed${method} not exist`;
log(err); logError(err);
throw err; throw err;
} }
// @ts-expect-error wait fix // @ts-expect-error wait fix
@@ -94,8 +96,10 @@ export abstract class HttpServerBase {
let payload = req.body; let payload = req.body;
if (method == 'get') { if (method == 'get') {
payload = req.query; payload = req.query;
} else if (req.query) {
payload = { ...req.query, ...req.body };
} }
log('收到http请求', url, payload); logDebug('收到http请求', url, payload);
try { try {
res.send(await handler(res, payload)); res.send(await handler(res, payload));
} catch (e: any) { } catch (e: any) {
@@ -104,10 +108,17 @@ export abstract class HttpServerBase {
}); });
} }
protected listen(port: number) { protected listen(port: number, host: string = '0.0.0.0') {
this.server = this.expressAPP.listen(port, '0.0.0.0', () => { host = host || '0.0.0.0';
const info = `${this.name} started 0.0.0.0:${port}`; try {
log(info); this.server = this.expressAPP.listen(port, host, () => {
}); const info = `${this.name} started ${host}:${port}`;
log(info);
}).on('error', (err) => {
logError('HTTP服务启动失败', err.toString());
});
} catch (e: any) {
logError('HTTP服务启动失败, 请检查监听的ip地址和端口', e.stack.toString());
}
} }
} }

View File

@@ -27,11 +27,17 @@ export class WebsocketServerBase {
constructor() { constructor() {
} }
start(port: number) { start(port: number, host: string = '') {
try { try {
this.ws = new WebSocketServer({ port }); this.ws = new WebSocketServer({
port,
host: '',
maxPayload: 1024 * 1024 * 1024
}).on('error', () => {
});
log(`ws服务启动成功, ${host}:${port}`);
} catch (e: any) { } catch (e: any) {
throw Error('ws服务启动失败, ' + e.toString()); throw Error('ws服务启动失败, 请检查监听的ip和端口' + e.toString());
} }
this.ws.on('connection', (wsClient, req) => { this.ws.on('connection', (wsClient, req) => {
const url: string = req.url!.split('?').shift() || '/'; const url: string = req.url!.split('?').shift() || '/';

View File

@@ -0,0 +1,35 @@
import { sleep } from '@/common/utils/helper';
type AsyncQueueTask = (() => void) | (()=>Promise<void>);
export class AsyncQueue {
private tasks: (AsyncQueueTask)[] = [];
public addTask(task: AsyncQueueTask) {
this.tasks.push(task);
// console.log('addTask', this.tasks.length);
if (this.tasks.length === 1) {
this.runQueue().then().catch(()=>{});
}
}
private async runQueue() {
// console.log('runQueue', this.tasks.length);
while (this.tasks.length > 0) {
const task = this.tasks[0];
// console.log('typeof task', typeof task);
try {
const taskRet = task();
// console.log('type of taskRet', typeof taskRet, taskRet);
if (taskRet instanceof Promise) {
await taskRet;
}
} catch (e) {
console.error(e);
}
this.tasks.shift();
await sleep(100);
}
}
}

View File

@@ -0,0 +1,73 @@
import path from 'node:path';
import fs from 'node:fs';
import { log, logDebug, logError } from '@/common/utils/log';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const configDir = path.resolve(__dirname, 'config');
fs.mkdirSync(configDir, { recursive: true });
export class ConfigBase<T>{
constructor() {
}
protected getKeys(): string[] | null {
// 决定 key 在json配置文件中的顺序
return null;
}
getConfigDir(){
const configDir = path.resolve(__dirname, 'config');
fs.mkdirSync(configDir, { recursive: true });
return configDir;
}
getConfigPath(): string {
throw new Error('Method not implemented.');
}
read() {
const configPath = this.getConfigPath();
if (!fs.existsSync(configPath)) {
try{
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`);
}
catch (e: any) {
logError(`创建配置文件 ${configPath} 时发生错误:`, e.message);
}
return this;
}
try {
const data = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
logDebug(`配置文件${configPath}已加载`, data);
Object.assign(this, data);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
this.save(this); // 保存一次,让新版本的字段写入
return this;
} catch (e: any) {
if (e instanceof SyntaxError) {
logError(`配置文件 ${configPath} 格式错误,请检查配置文件:`, e.message);
} else {
logError(`读取配置文件 ${configPath} 时发生错误:`, e.message);
}
return this;
}
}
save(config: T) {
Object.assign(this, config);
const configPath = this.getConfigPath();
try {
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
} catch (e: any) {
logError(`保存配置文件 ${configPath} 时发生错误:`, e.message);
}
}
}

View File

@@ -0,0 +1,182 @@
import { NodeIKernelMsgListener } from '@/core';
import { NodeIQQNTWrapperSession } from '@/core/wrapper';
import { randomUUID } from 'crypto';
interface Internal_MapKey {
timeout: number,
createtime: number,
func: (...arg: any[]) => any,
}
export class ListenerClassBase {
[key: string]: string;
}
export interface ListenerIBase {
// eslint-disable-next-line @typescript-eslint/no-misused-new
new(listener: any): ListenerClassBase;
}
export class NTEventWrapper {
private ListenerMap: { [key: string]: ListenerIBase } | undefined;//ListenerName-Unique -> Listener构造函数
private WrapperSession: NodeIQQNTWrapperSession | undefined;//WrapperSession
private ListenerManger: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>(); //ListenerName-Unique -> Listener实例
private EventTask = new Map<string, Map<string, Map<string, Internal_MapKey>>>();//tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func}
constructor() {
}
createProxyDispatch(ListenerMainName: string) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const current = this;
return new Proxy({}, {
get(target: any, prop: any, receiver: any) {
// console.log('get', prop, typeof target[prop]);
if (typeof target[prop] === 'undefined') {
// 如果方法不存在返回一个函数这个函数调用existentMethod
return (...args: any[]) => {
current.DispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then();
};
}
// 如果方法存在,正常返回
return Reflect.get(target, prop, receiver);
}
});
}
init({ ListenerMap, WrapperSession }: { ListenerMap: { [key: string]: typeof ListenerClassBase }, WrapperSession: NodeIQQNTWrapperSession }) {
this.ListenerMap = ListenerMap;
this.WrapperSession = WrapperSession;
}
CreatEventFunction<T extends (...args: any) => any>(eventName: string): T | undefined {
const eventNameArr = eventName.split('/');
type eventType = {
[key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>> }
}
if (eventNameArr.length > 1) {
const serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', '');
const eventName = eventNameArr[1];
//getNodeIKernelGroupListener,GroupService
//console.log('2', eventName);
const services = (this.WrapperSession as unknown as eventType)[serviceName]();
let event = services[eventName];
//重新绑定this
event = event.bind(services);
if (event) {
return event as T;
}
return undefined;
}
}
CreatListenerFunction<T>(listenerMainName: string, uniqueCode: string = ''): T {
const ListenerType = this.ListenerMap![listenerMainName];
let Listener = this.ListenerManger.get(listenerMainName + uniqueCode);
if (!Listener && ListenerType) {
Listener = new ListenerType(this.createProxyDispatch(listenerMainName));
const ServiceSubName = listenerMainName.match(/^NodeIKernel(.*?)Listener$/)![1];
const Service = 'NodeIKernel' + ServiceSubName + 'Service/addKernel' + ServiceSubName + 'Listener';
const addfunc = this.CreatEventFunction<(listener: T) => number>(Service);
addfunc!(Listener as T);
//console.log(addfunc!(Listener as T));
this.ListenerManger.set(listenerMainName + uniqueCode, Listener);
}
return Listener as T;
}
//统一回调清理事件
async DispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) {
//console.log(ListenerMainName, this.EventTask.get(ListenerMainName), ListenerSubName, this.EventTask.get(ListenerMainName)?.get(ListenerSubName));
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.forEach((task, uuid) => {
//console.log(task.func, uuid, task.createtime, task.timeout);
if (task.createtime + task.timeout < Date.now()) {
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid);
return;
}
task.func(...args);
});
}
async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any>,>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
return new Promise<ReturnType<EventType>>(async (resolve, reject) => {
const EventFunc = this.CreatEventFunction<EventType>(EventName);
let complete = false;
const Timeouter = setTimeout(() => {
if (!complete) {
reject(new Error('NTEvent EventName:' + EventName + ' timeout'));
}
}, timeout);
const retData = await EventFunc!(...args);
complete = true;
resolve(retData);
});
}
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, ...args: Parameters<EventType>) {
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
const id = randomUUID();
let complete = 0;
let retData: ArrayLike<Parameters<ListenerType>> | undefined = undefined;
let retEvent: any = {};
const databack = () => {
if (complete < waitTimes) {
reject(new Error('NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' timeout'));
} else {
resolve([retEvent as Awaited<ReturnType<EventType>>, ...(retData as Parameters<ListenerType>)]);
}
};
const Timeouter = setTimeout(databack, timeout);
const ListenerNameList = ListenerName.split('/');
const ListenerMainName = ListenerNameList[0];
const ListenerSubName = ListenerNameList[1];
const eventCallbak = {
timeout: timeout,
createtime: Date.now(),
func: (...args: any[]) => {
complete++;
//console.log('func', ...args);
retData = args as ArrayLike<Parameters<ListenerType>>;
if (complete >= waitTimes) {
clearTimeout(Timeouter);
databack();
}
}
};
if (!this.EventTask.get(ListenerMainName)) {
this.EventTask.set(ListenerMainName, new Map());
}
if (!(this.EventTask.get(ListenerMainName)?.get(ListenerSubName))) {
this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map());
}
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak);
this.CreatListenerFunction(ListenerMainName);
const EventFunc = this.CreatEventFunction<EventType>(EventName);
retEvent = await EventFunc!(...args);
});
}
}
export const NTEventDispatch = new NTEventWrapper();
// 示例代码 快速创建事件
// let NTEvent = new NTEventWrapper();
// let TestEvent = NTEvent.CreatEventFunction<(force: boolean) => Promise<Number>>('NodeIKernelProfileLikeService/GetTest');
// if (TestEvent) {
// TestEvent(true);
// }
// 示例代码 快速创建监听Listener类
// let NTEvent = new NTEventWrapper();
// NTEvent.CreatListenerFunction<NodeIKernelMsgListener>('NodeIKernelMsgListener', 'core')
// 调用接口
//let NTEvent = new NTEventWrapper();
//let ret = await NTEvent.CallNormalEvent<(force: boolean) => Promise<Number>, (data1: string, data2: number) => void>('NodeIKernelProfileLikeService/GetTest', 'NodeIKernelMsgListener/onAddSendMsg', 1, 3000, true);
// 注册监听 解除监听
// NTEventDispatch.RigisterListener('NodeIKernelMsgListener/onAddSendMsg','core',cb);
// NTEventDispatch.UnRigisterListener('NodeIKernelMsgListener/onAddSendMsg','core');
// let GetTest = NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode);
// GetTest('test');
// always模式
// NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode,(...args:any[])=>{ console.log(args) });

View File

@@ -0,0 +1,145 @@
import { logError, logDebug } from '@/common/utils/log';
type group_id = number;
type user_id = number;
class cacheNode<T> {
value: T;
groupId: group_id;
userId: user_id;
prev: cacheNode<T> | null;
next: cacheNode<T> | null;
timestamp: number;
constructor(groupId: group_id, userId: user_id, value: T) {
this.groupId = groupId;
this.userId = userId;
this.value = value;
this.prev = null;
this.next = null;
this.timestamp = Date.now();
}
}
type cache<T> = { [key: group_id]: { [key: user_id]: cacheNode<T> } };
class LRU<T> {
private maxAge: number;
private maxSize: number;
private currentSize: number;
private cache: cache<T>;
private head: cacheNode<T> | null = null;
private tail: cacheNode<T> | null = null;
private onFuncs: ((node: cacheNode<T>) => void)[] = [];
constructor(maxAge: number = 2e4, maxSize: number = 5e3) {
this.maxAge = maxAge;
this.maxSize = maxSize;
this.cache = Object.create(null);
this.currentSize = 0;
if (maxSize == 0) return;
setInterval(() => this.removeExpired(), this.maxAge);
}
// 移除LRU节点
private removeLRUNode(node: cacheNode<T>) {
logDebug(
'removeLRUNode',
node.groupId,
node.userId,
node.value,
this.currentSize
);
node.prev = node.next = null;
delete this.cache[node.groupId][node.userId];
this.removeNode(node);
this.onFuncs.forEach((func) => func(node));
this.currentSize--;
}
public on(func: (node: cacheNode<T>) => void) {
this.onFuncs.push(func);
}
private removeExpired() {
const now = Date.now();
let current = this.tail;
const nodesToRemove: cacheNode<T>[] = [];
let removedCount = 0;
// 收集需要删除的节点
while (current && now - current.timestamp > this.maxAge) {
nodesToRemove.push(current);
current = current.prev;
removedCount++;
if (removedCount >= 100) break;
}
// 更新链表指向
if (nodesToRemove.length > 0) {
const newTail = nodesToRemove[nodesToRemove.length - 1].prev;
if (newTail) {
newTail.next = null;
} else {
this.head = null;
}
this.tail = newTail;
}
nodesToRemove.forEach((node) => {
node.prev = node.next = null;
delete this.cache[node.groupId][node.userId];
this.currentSize--;
this.onFuncs.forEach((func) => func(node));
});
}
private addNode(node: cacheNode<T>) {
node.next = this.head;
if (this.head) this.head.prev = node;
if (!this.tail) this.tail = node;
this.head = node;
}
private removeNode(node: cacheNode<T>) {
if (node.prev) node.prev.next = node.next;
if (node.next) node.next.prev = node.prev;
if (node === this.head) this.head = node.next;
if (node === this.tail) this.tail = node.prev;
}
private moveToHead(node: cacheNode<T>) {
if (this.head === node) return;
this.removeNode(node);
this.addNode(node);
node.prev = null;
}
public set(groupId: group_id, userId: user_id, value: T) {
if (!this.cache[groupId]) {
this.cache[groupId] = Object.create(null);
}
const groupObject = this.cache[groupId];
if (groupObject[userId]) {
const node = groupObject[userId];
node.value = value;
node.timestamp = Date.now();
this.moveToHead(node);
} else {
const node = new cacheNode(groupId, userId, value);
groupObject[userId] = node;
this.currentSize++;
this.addNode(node);
if (this.currentSize > this.maxSize) {
const tail = this.tail!;
this.removeLRUNode(tail);
}
}
}
}
export default LRU;

View File

@@ -37,24 +37,36 @@ type QQVersionConfigInfo = {
} }
let _qqVersionConfigInfo: QQVersionConfigInfo = { let _qqVersionConfigInfo: QQVersionConfigInfo = {
'baseVersion': '9.9.9-22578', 'baseVersion': '9.9.9-23361',
'curVersion': '9.9.9-22578', 'curVersion': '9.9.9-23361',
'prevVersion': '', 'prevVersion': '',
'onErrorVersions': [], 'onErrorVersions': [],
'buildId': '22578' 'buildId': '23361'
}; };
if (fs.existsSync(configVersionInfoPath)) { if (fs.existsSync(configVersionInfoPath)) {
_qqVersionConfigInfo = JSON.parse(fs.readFileSync(configVersionInfoPath).toString()); try {
const _ =JSON.parse(fs.readFileSync(configVersionInfoPath).toString());
_qqVersionConfigInfo = Object.assign(_qqVersionConfigInfo, _);
} catch (e) {
console.error('Load QQ version config info failed, Use default version', e);
}
} }
export const qqVersionConfigInfo: QQVersionConfigInfo = _qqVersionConfigInfo; export const qqVersionConfigInfo: QQVersionConfigInfo = _qqVersionConfigInfo;
export const qqPkgInfo: QQPkgInfo = require(pkgInfoPath); export const qqPkgInfo: QQPkgInfo = JSON.parse(fs.readFileSync(pkgInfoPath).toString());
// platform_type: 3,
// app_type: 4,
// app_version: '9.9.9-23159',
// qua: 'V1_WIN_NQ_9.9.9_23159_GW_B',
// appid: '537213764',
// platVer: '10.0.26100',
// clientVer: '9.9.9-23159',
let _appid: string = '537213335'; // 默认为 Windows 平台的 appid let _appid: string = '537213803'; // 默认为 Windows 平台的 appid
if (systemPlatform === 'linux') { if (systemPlatform === 'linux') {
_appid = '537213710'; _appid = '537213827';
} }
// todo: mac 平台的 appid // todo: mac 平台的 appid
export const appid = _appid; export const appid = _appid;

View File

@@ -1,7 +1,7 @@
import fs from 'fs'; import fs from 'fs';
import { encode, getDuration, getWavFileInfo, isWav } from 'silk-wasm'; import { encode, getDuration, getWavFileInfo, isWav } from 'silk-wasm';
import fsPromise from 'fs/promises'; import fsPromise from 'fs/promises';
import { log } from './log'; import { log, logError } from './log';
import path from 'node:path'; import path from 'node:path';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { spawn } from 'node:child_process'; import { spawn } from 'node:child_process';
@@ -129,7 +129,7 @@ export async function encodeSilk(filePath: string) {
}; };
} }
} catch (error: any) { } catch (error: any) {
log('convert silk failed', error.stack); logError('convert silk failed', error.stack);
return {}; return {};
} }
} }

View File

@@ -0,0 +1,24 @@
import * as os from 'os';
import path from 'node:path';
import fs from 'fs';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export function getModuleWithArchName(moduleName: string) {
const systemPlatform = os.platform();
const cpuArch = os.arch();
return `${moduleName}-${systemPlatform}-${cpuArch}.node`;
}
export function cpModule(moduleName: string) {
const currentDir = path.resolve(__dirname);
const fileName = `./${getModuleWithArchName(moduleName)}`;
try {
fs.copyFileSync(path.join(currentDir, fileName), path.join(currentDir, `${moduleName}.node`));
} catch (e) {
console.error(e);
}
}

View File

@@ -1,14 +1,24 @@
import { ElementType, FileElement, PicElement, PttElement, RawMessage, VideoElement } from '@/core/qqnt/entities'; import { ElementType, FileElement, PicElement, PttElement, RawMessage, VideoElement } from '../../core/src/entities';
import sqlite3 from 'sqlite3'; import sqlite3 from 'sqlite3';
import { log } from '@/common/utils/log'; import { log, logDebug, logError } from '@/common/utils/log';
import { NTQQMsgApi } from '@/core';
import LRU from '@/common/utils/LRUCache';
export interface IRember {
last_sent_time: number;
join_time: number;
user_id: number;
}
type DBMsg = { type DBMsg = {
id: number, id: number,
shortId: number,
longId: string, longId: string,
seq: number, seq: number,
peerUid: string, peerUid: string,
msg: string chatType: number,
} }
type DBFile = { type DBFile = {
@@ -27,16 +37,20 @@ type DBFile = {
class DBUtilBase { class DBUtilBase {
protected db: sqlite3.Database | undefined; protected db: sqlite3.Database | undefined;
createConnection(dbPath: string) { async init(dbPath: string) {
if (this.db) { if (this.db) {
return; return;
} }
this.db = new sqlite3.Database(dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => { return new Promise<void>((resolve, reject) => {
if (err) { this.db = new sqlite3.Database(dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
log('Could not connect to database', err); if (err) {
return; logError('Could not connect to database', err);
} reject(err);
this.createTable(); return;
}
this.createTable();
resolve();
});
}); });
} }
@@ -50,13 +64,38 @@ class DBUtilBase {
} }
class DBUtil extends DBUtilBase { class DBUtil extends DBUtilBase {
private msgCache: Map<string, RawMessage> = new Map<string, RawMessage>(); private msgCache: Map<string | number, RawMessage> = new Map<string | number, RawMessage>();
private globalMsgShortId = -2147483640;
private groupIds: number[] = [];
private LURCache = new LRU<number>();
private LastSentCache = new (class {
private cache: { gid: number; uid: number }[] = [];
private maxSize: number;
constructor(maxSize: number = 5000) {
this.maxSize = maxSize;
}
get(gid: number, uid: number): boolean {
const exists = this.cache.some(
(entry) => entry.gid === gid && entry.uid === uid
);
if (!exists) {
this.cache.push({ gid, uid });
if (this.cache.length > this.maxSize) {
this.cache.shift();
}
}
return exists;
}
})();
constructor() { constructor() {
super(); super();
const interval = 1000 * 60 * 10; // 10分钟清理一次缓存 const interval = 1000 * 60 * 10; // 10分钟清理一次缓存
setInterval(() => { setInterval(() => {
log('清理消息缓存'); logDebug('清理消息缓存');
this.msgCache.forEach((msg, key) => { this.msgCache.forEach((msg, key) => {
if ((Date.now() - parseInt(msg.msgTime) * 1000) > interval) { if ((Date.now() - parseInt(msg.msgTime) * 1000) > interval) {
this.msgCache.delete(key); this.msgCache.delete(key);
@@ -65,20 +104,112 @@ class DBUtil extends DBUtilBase {
}, interval); }, interval);
} }
async init(dbPath: string) {
await super.init(dbPath);
this.globalMsgShortId = await this.getCurrentMaxShortId();
// 初始化群缓存列表
this.db!.serialize(() => {
const sql = 'SELECT * FROM sqlite_master WHERE type=\'table\'';
this.db!.all(sql, [], (err, rows: { name: string }[]) => {
if (err) return logError(err);
rows.forEach((row) => this.groupIds.push(parseInt(row.name)));
//logDebug(`已加载 ${groupIds.length} 个群`);
});
});
this.LURCache.on(async (node) => {
const { value: time, groupId, userId } = node;
logDebug('插入发言时间', userId, groupId);
await this.createGroupInfoTimeTableIfNotExist(groupId);
const method = await this.getDataSetMethod(groupId, userId);
logDebug('插入发言时间方法判断', userId, groupId, method);
const sql =
method == 'update'
? `UPDATE "${groupId}" SET last_sent_time = ? WHERE user_id = ?`
: `INSERT INTO "${groupId}" (last_sent_time, user_id) VALUES (?, ?)`;
this.db!.all(sql, [time, userId], (err) => {
if (err) {
return logError('插入/更新发言时间失败', userId, groupId);
}
logDebug('插入/更新发言时间成功', userId, groupId);
});
});
}
async getDataSetMethod(groupId: number, userId: number) {
// 缓存记录
if (this.LastSentCache.get(groupId, userId)) {
logDebug('缓存命中', userId, groupId);
return 'update';
}
// 数据库判断
return new Promise<'insert' | 'update'>((resolve, reject) => {
this.db!.all(
`SELECT * FROM "${groupId}" WHERE user_id = ?`,
[userId],
(err, rows) => {
if (err) {
logError('查询发言时间存在失败', userId, groupId, err);
return logError('插入发言时间失败', userId, groupId, err);
}
if (rows.length === 0) {
logDebug('查询发言时间不存在', userId, groupId);
return resolve('insert');
}
logDebug('查询发言时间存在', userId, groupId);
resolve('update');
}
);
});
}
async createGroupInfoTimeTableIfNotExist(groupId: number) {
const createTableSQL = (groupId: number) =>
`CREATE TABLE IF NOT EXISTS "${groupId}" (
user_id INTEGER,
last_sent_time INTEGER,
join_time INTEGER,
PRIMARY KEY (user_id)
);`;
if (this.groupIds.includes(groupId)) {
return;
}
return new Promise((resolve, reject) => {
const sql = createTableSQL(groupId);
this.db!.all(sql, (err) => {
if (err) {
reject(err);
return;
}
this.groupIds.push(groupId);
resolve(true);
});
});
}
protected createTable() { protected createTable() {
// 消息记录 // 消息记录
const createTableSQL = ` const createTableSQL = `
CREATE TABLE IF NOT EXISTS msgs ( CREATE TABLE IF NOT EXISTS msgs (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
long_id TEXT NOT NULL UNIQUE, shortId INTEGER NOT NULL UNIQUE,
longId TEXT NOT NULL UNIQUE,
seq INTEGER NOT NULL, seq INTEGER NOT NULL,
peer_uid TEXT NOT NULL, peerUid TEXT NOT NULL,
msg TEXT NOT NULL chatType INTEGER NOT NULL
)`; )`;
this.db!.run(createTableSQL, function (err) { this.db!.run(createTableSQL, function (err) {
if (err) { if (err) {
log('Could not create table', err); logError('Could not create table msgs', err.stack);
} }
}); });
@@ -98,7 +229,7 @@ class DBUtil extends DBUtilBase {
)`; )`;
this.db!.run(createFileTableSQL, function (err) { this.db!.run(createFileTableSQL, function (err) {
if (err) { if (err) {
log('Could not create table files', err); logError('Could not create table files', err);
} }
}); });
@@ -111,33 +242,59 @@ class DBUtil extends DBUtilBase {
)`; )`;
this.db!.run(createTempUinTableSQL, function (err) { this.db!.run(createTempUinTableSQL, function (err) {
if (err) { if (err) {
log('Could not create table temp_uins', err); logError('Could not create table temp_uins', err);
} }
}); });
} }
private async getCurrentMaxShortId() {
return new Promise<number>((resolve, reject) => {
this.db!.get('SELECT MAX(shortId) as maxId FROM msgs', (err, row: { maxId: number }) => {
if (err) {
logDebug('Could not get max short id, Use default -2147483640', err);
return resolve(-2147483640);
}
logDebug('数据库中消息最大短id', row?.maxId);
resolve(row?.maxId ?? -2147483640);
});
});
}
private async getMsg(query: string, params: any[]) { private async getMsg(query: string, params: any[]) {
const stmt = this.db!.prepare(query); const stmt = this.db!.prepare(query);
return new Promise<RawMessage | null>((resolve, reject) => { return new Promise<RawMessage | null>((resolve, reject) => {
stmt.get(...params, (err: any, row: DBMsg) => { stmt.get(...params, (err: any, row: DBMsg) => {
// log("getMsg", row, err); // log("getMsg", row, err);
if (err) { if (err) {
log('Could not get msg by short id', err); logError('Could not get msg', err, query, params);
resolve(null);
}
try {
const msg = JSON.parse(row.msg);
msg.id = row.id;
return resolve(msg);
} catch (e) {
return resolve(null); return resolve(null);
} }
if (!row) {
// logDebug('不存在数据库中的消息,不进行处理', query, params);
resolve(null);
return;
}
const msgId = row.longId;
NTQQMsgApi.getMsgsByMsgId({ peerUid: row.peerUid, chatType: row.chatType }, [msgId]).then(res => {
const msg = res.msgList[0];
if (!msg) {
resolve(null);
return;
}
msg.id = row.shortId;
resolve(msg);
}).catch(e => {
resolve(null);
});
}); });
}); });
} }
async getMsgByShortId(shortId: number): Promise<RawMessage | null> { async getMsgByShortId(shortId: number): Promise<RawMessage | null> {
const getStmt = 'SELECT * FROM msgs WHERE id = ?'; if (this.msgCache.has(shortId)) {
return this.msgCache.get(shortId)!;
}
const getStmt = 'SELECT * FROM msgs WHERE shortId = ?';
return this.getMsg(getStmt, [shortId]); return this.getMsg(getStmt, [shortId]);
} }
@@ -145,60 +302,46 @@ class DBUtil extends DBUtilBase {
if (this.msgCache.has(longId)) { if (this.msgCache.has(longId)) {
return this.msgCache.get(longId)!; return this.msgCache.get(longId)!;
} }
return this.getMsg('SELECT * FROM msgs WHERE long_id = ?', [longId]); return this.getMsg('SELECT * FROM msgs WHERE longId = ?', [longId]);
} }
async getMsgBySeq(peerUid: string, seq: string): Promise<RawMessage | null> { async getMsgBySeq(peerUid: string, seq: string): Promise<RawMessage | null> {
const stmt = 'SELECT * FROM msgs WHERE peer_uid = ? AND seq = ?'; const stmt = 'SELECT * FROM msgs WHERE peerUid = ? AND seq = ?';
return this.getMsg(stmt, [peerUid, seq]); return this.getMsg(stmt, [peerUid, seq]);
} }
async addMsg(msg: RawMessage, update = true): Promise<number> { async addMsg(msg: RawMessage, update = true): Promise<number> {
log('正在记录消息到数据库', msg.msgId);
const existMsg = await this.getMsgByLongId(msg.msgId); const existMsg = await this.getMsgByLongId(msg.msgId);
if (existMsg) { if (existMsg) {
// log('消息已存在,更新数据库', msg.msgId); // logDebug('消息已存在,更新数据库', msg.msgId);
if (update) this.updateMsg(msg).then(); if (update) this.updateMsg(msg).then();
return existMsg.id!; return existMsg.id!;
} }
const stmt = this.db!.prepare('INSERT INTO msgs (long_id, seq, peer_uid, msg) VALUES (?, ?, ?, ?)'); const stmt = this.db!.prepare('INSERT INTO msgs (shortId, longId, seq, peerUid, chatType) VALUES (?, ?, ?, ?, ?)');
// const runAsync = promisify(stmt.run.bind(stmt)); // const runAsync = promisify(stmt.run.bind(stmt));
return new Promise((resolve, reject) => { const shortId = ++this.globalMsgShortId;
// eslint-disable-next-line @typescript-eslint/no-this-alias msg.id = shortId;
const dbInstance = this; //logDebug(`记录消息到数据库, 消息长id: ${msg.msgId}, 短id: ${msg.id}`);
stmt.run(msg.msgId, msg.msgSeq, msg.peerUid, JSON.stringify(msg), function (err: any) { this.msgCache.set(shortId, msg);
if (err) { this.msgCache.set(msg.msgId, msg);
if (err.errno === 19) { stmt.run(this.globalMsgShortId, msg.msgId, msg.msgSeq.toString(), msg.peerUid, msg.chatType, (err: any) => {
// log('消息已存在,更新数据库', msg.msgId); if (err) {
dbInstance.getMsgByLongId(msg.msgId).then((msg: RawMessage | null) => { if (err.errno === 19) {
if (msg) { this.getMsgByLongId(msg.msgId).then((msg: RawMessage | null) => {
dbInstance.msgCache.set(msg.msgId, msg); if (msg) {
// log('获取消息短id成功', msg.id); this.msgCache.set(shortId, msg);
resolve(msg.id!); this.msgCache.set(msg.msgId, msg);
} else { // logDebug('获取消息短id成功', msg.id);
log('db could not get msg by long id', err); } else {
resolve(-1); logError('db could not get msg by long id', err);
} }
}); }).catch(e => logError('db getMsgByLongId error', e));
} else {
log('db could not add msg', err);
resolve(-1);
}
} else { } else {
// log("addMsg", this); logError('db could not add msg', err);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
msg.id = this.lastID;
dbInstance.msgCache.set(msg.msgId, msg);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// log('获取消息短id成功', this.lastID);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
resolve(this.lastID);
} }
}); }
}); });
return shortId;
} }
async updateMsg(msg: RawMessage) { async updateMsg(msg: RawMessage) {
@@ -206,12 +349,14 @@ class DBUtil extends DBUtilBase {
if (existMsg) { if (existMsg) {
Object.assign(existMsg, msg); Object.assign(existMsg, msg);
} }
const stmt = this.db!.prepare('UPDATE msgs SET msg = ?, seq = ? WHERE long_id = ?'); //logDebug(`更新消息, shortId:${msg.id}, seq: ${msg.msgSeq}, msgId: ${msg.msgId}`);
try { const stmt = this.db!.prepare('UPDATE msgs SET seq=? WHERE longId=?');
stmt.run(JSON.stringify(msg), msg.msgSeq, msg.msgId); stmt.run(msg.msgSeq, msg.msgId, (err: any) => {
} catch (e) { if (err) {
log('updateMsg db error', e); logError('updateMsg db error', err);
} }
});
} }
async addFileCache(file: DBFile) { async addFileCache(file: DBFile) {
@@ -224,7 +369,7 @@ class DBUtil extends DBUtilBase {
file.msgId, file.msgId,
function (err: any) { function (err: any) {
if (err) { if (err) {
log('db could not add file', err); logError('db could not add file', err);
reject(err); reject(err);
} }
resolve(null); resolve(null);
@@ -237,7 +382,7 @@ class DBUtil extends DBUtilBase {
return new Promise<DBFile | null>((resolve, reject) => { return new Promise<DBFile | null>((resolve, reject) => {
stmt.get(...params, (err: any, row: DBFile & { element: string }) => { stmt.get(...params, (err: any, row: DBFile & { element: string }) => {
if (err) { if (err) {
log('db could not get file cache', err); logError('db could not get file cache', err);
reject(err); reject(err);
} }
if (row) { if (row) {
@@ -260,9 +405,9 @@ class DBUtil extends DBUtilBase {
async updateFileCache(file: DBFile) { async updateFileCache(file: DBFile) {
const stmt = this.db!.prepare('UPDATE files SET path = ?, url = ? WHERE uuid = ?'); const stmt = this.db!.prepare('UPDATE files SET path = ?, url = ? WHERE uuid = ?');
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
stmt.run(file.path, file.url, function (err: any) { stmt.run(file.path, file.url, file.uuid, function (err: any) {
if (err) { if (err) {
log('db could not update file cache', err); logError('db could not update file cache', err);
reject(err); reject(err);
} }
resolve(null); resolve(null);
@@ -276,7 +421,7 @@ class DBUtil extends DBUtilBase {
return new Promise<Record<string, string>>((resolve, reject) => { return new Promise<Record<string, string>>((resolve, reject) => {
this.db!.all(stmt, (err, rows: { uin: string, uid: string }[]) => { this.db!.all(stmt, (err, rows: { uin: string, uid: string }[]) => {
if (err) { if (err) {
log('db could not get temp uin map', err); logError('db could not get temp uin map', err);
reject(err); reject(err);
} }
const map: Record<string, string> = {}; const map: Record<string, string> = {};
@@ -294,7 +439,7 @@ class DBUtil extends DBUtilBase {
return new Promise<string>((resolve, reject) => { return new Promise<string>((resolve, reject) => {
this.db!.get(stmt, [uid], (err, row: { uin: string, uid: string }) => { this.db!.get(stmt, [uid], (err, row: { uin: string, uid: string }) => {
if (err) { if (err) {
log('db could not get temp uin map', err); logError('db could not get temp uin map', err);
reject(err); reject(err);
} }
resolve(row?.uid); resolve(row?.uid);
@@ -309,7 +454,7 @@ class DBUtil extends DBUtilBase {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
stmt.run(uin, uid, function (err: any) { stmt.run(uin, uid, function (err: any) {
if (err) { if (err) {
log('db could not add temp uin', err); logError('db could not add temp uin', err);
reject(err); reject(err);
} }
resolve(null); resolve(null);
@@ -317,6 +462,47 @@ class DBUtil extends DBUtilBase {
}); });
} }
} }
async getLastSentTimeAndJoinTime(
groupId: number
): Promise<IRember[]> {
logDebug('读取发言时间', groupId);
return new Promise<IRember[]>((resolve, reject) => {
this.db!.all(`SELECT * FROM "${groupId}" `, (err, rows: IRember[]) => {
if (err) {
logError('查询发言时间失败', groupId);
return resolve([]);
}
logDebug('查询发言时间成功', groupId, rows);
resolve(rows);
});
});
}
insertLastSentTime(
groupId: number,
userId: number,
time: number
) {
this.LURCache.set(groupId, userId, time);
}
async insertJoinTime(
groupId: number,
userId: number,
time: number
) {
await this.createGroupInfoTimeTableIfNotExist(groupId);
this.db!.all(
`INSERT OR REPLACE INTO "${groupId}" (user_id, last_sent_time, join_time) VALUES (?,?,?)`,
[userId, time, time],
(err) => {
if (err)
logError(err),
Promise.reject(),
console.log('插入入群时间失败', userId, groupId);
}
);
}
} }

View File

@@ -4,14 +4,13 @@ import crypto from 'crypto';
import util from 'util'; import util from 'util';
import path from 'node:path'; import path from 'node:path';
import { log } from './log'; import { log } from './log';
import { dbUtil } from './db'; import { dbUtil } from '@/common/utils/db';
import * as fileType from 'file-type'; import * as fileType from 'file-type';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { napCatCore } from '@/core'; import { napCatCore } from '@/core';
import os from 'node:os';
export const getNapCatDir = () => { export const getNapCatDir = () => {
const p = path.join(napCatCore.wrapper.dataPath, 'NapCat'); const p = path.join(napCatCore.dataPath, 'NapCat');
fs.mkdirSync(p, { recursive: true }); fs.mkdirSync(p, { recursive: true });
return p; return p;
}; };
@@ -126,7 +125,7 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
} }
} }
} }
const fetchRes = await fetch(url, headers); const fetchRes = await fetch(url, { headers });
if (!fetchRes.ok) throw new Error(`下载文件失败: ${fetchRes.statusText}`); if (!fetchRes.ok) throw new Error(`下载文件失败: ${fetchRes.statusText}`);
const blob = await fetchRes.blob(); const blob = await fetchRes.blob();
@@ -194,6 +193,7 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
// res.ext = pathInfo.ext // res.ext = pathInfo.ext
} }
} }
fileName = fileName.replace(/[/\\:*?"<>|]/g, '_');
res.fileName = fileName; res.fileName = fileName;
filePath = path.join(getTempDir(), uuidv4() + fileName); filePath = path.join(getTempDir(), uuidv4() + fileName);
fs.writeFileSync(filePath, buffer); fs.writeFileSync(filePath, buffer);

View File

@@ -1,6 +1,13 @@
import crypto from 'node:crypto'; import crypto from 'node:crypto';
import { resolve } from 'dns'; import path from 'node:path';
import fs from 'fs/promises';
import { log, logDebug } from './log';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export function sleep(ms: number): Promise<void> { export function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
@@ -19,3 +26,159 @@ export function isNull(value: any) {
export function isNumeric(str: string) { export function isNumeric(str: string) {
return /^\d+$/.test(str); return /^\d+$/.test(str);
} }
export function truncateString(obj: any, maxLength = 500) {
if (obj !== null && typeof obj === 'object') {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'string') {
// 如果是字符串且超过指定长度,则截断
if (obj[key].length > maxLength) {
obj[key] = obj[key].substring(0, maxLength) + '...';
}
} else if (typeof obj[key] === 'object') {
// 如果是对象或数组,则递归调用
truncateString(obj[key], maxLength);
}
});
}
return obj;
}
/**
* 函数缓存装饰器根据方法名、参数、自定义key生成缓存键在一定时间内返回缓存结果
* @param ttl 超时时间,单位毫秒
* @param customKey 自定义缓存键前缀,可为空,防止方法名参数名一致时导致缓存键冲突
* @returns 处理后缓存或调用原方法的结果
*/
export function cacheFunc(ttl: number, customKey: string = '') {
const cache = new Map<string, { expiry: number; value: any }>();
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor {
const originalMethod = descriptor.value;
const className = target.constructor.name; // 获取类名
const methodName = propertyKey; // 获取方法名
descriptor.value = async function (...args: any[]) {
const cacheKey = `${customKey}${className}.${methodName}:${JSON.stringify(args)}`;
const cached = cache.get(cacheKey);
if (cached && cached.expiry > Date.now()) {
return cached.value;
} else {
const result = await originalMethod.apply(this, args);
cache.set(cacheKey, { value: result, expiry: Date.now() + ttl });
return result;
}
};
return descriptor;
};
}
export function isValidOldConfig(config: any) {
if (typeof config !== 'object') {
return false;
}
const requiredKeys = [
'httpHost', 'httpPort', 'httpPostUrls', 'httpSecret',
'wsHost', 'wsPort', 'wsReverseUrls', 'enableHttp',
'enableHttpHeart', 'enableHttpPost', 'enableWs', 'enableWsReverse',
'messagePostFormat', 'reportSelfMessage', 'enableLocalFile2Url',
'debug', 'heartInterval', 'token', 'musicSignUrl'
];
for (const key of requiredKeys) {
if (!(key in config)) {
return false;
}
}
if (!Array.isArray(config.httpPostUrls) || !Array.isArray(config.wsReverseUrls)) {
return false;
}
if (config.httpPostUrls.some((url: any) => typeof url !== 'string')) {
return false;
}
if (config.wsReverseUrls.some((url: any) => typeof url !== 'string')) {
return false;
}
if (typeof config.httpPort !== 'number' || typeof config.wsPort !== 'number' || typeof config.heartInterval !== 'number') {
return false;
}
if (
typeof config.enableHttp !== 'boolean' ||
typeof config.enableHttpHeart !== 'boolean' ||
typeof config.enableHttpPost !== 'boolean' ||
typeof config.enableWs !== 'boolean' ||
typeof config.enableWsReverse !== 'boolean' ||
typeof config.enableLocalFile2Url !== 'boolean' ||
typeof config.reportSelfMessage !== 'boolean'
) {
return false;
}
if (config.messagePostFormat !== 'array' && config.messagePostFormat !== 'string') {
return false;
}
return true;
}
export function migrateConfig(oldConfig: any) {
const newConfig = {
http: {
enable: oldConfig.enableHttp,
host: oldConfig.httpHost,
port: oldConfig.httpPort,
secret: oldConfig.httpSecret,
enableHeart: oldConfig.enableHttpHeart,
enablePost: oldConfig.enableHttpPost,
postUrls: oldConfig.httpPostUrls,
},
ws: {
enable: oldConfig.enableWs,
host: oldConfig.wsHost,
port: oldConfig.wsPort,
},
reverseWs: {
enable: oldConfig.enableWsReverse,
urls: oldConfig.wsReverseUrls,
},
GroupLocalTime: {
Record: false,
RecordList: []
},
debug: oldConfig.debug,
heartInterval: oldConfig.heartInterval,
messagePostFormat: oldConfig.messagePostFormat,
enableLocalFile2Url: oldConfig.enableLocalFile2Url,
musicSignUrl: oldConfig.musicSignUrl,
reportSelfMessage: oldConfig.reportSelfMessage,
token: oldConfig.token,
};
return newConfig;
}
// 升级旧的配置到新的
export async function UpdateConfig() {
const configFiles = await fs.readdir(path.join(__dirname, 'config'));
for (const file of configFiles) {
if (file.match(/^onebot11_\d+.json$/)) {
const CurrentConfig = JSON.parse(await fs.readFile(path.join(__dirname, 'config', file), 'utf8'));
if (isValidOldConfig(CurrentConfig)) {
log('正在迁移旧配置到新配置 File:', file);
const NewConfig = migrateConfig(CurrentConfig);
await fs.writeFile(path.join(__dirname, 'config', file), JSON.stringify(NewConfig, null, 2));
}
}
}
}
export function isEqual(obj1: any, obj2: any) {
if (obj1 === obj2) return true;
if (obj1 == null || obj2 == null) return false;
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return obj1 === obj2;
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
for (const key of keys1) {
if (!isEqual(obj1[key], obj2[key])) return false;
}
return true;
}

View File

@@ -1,4 +1,123 @@
import log4js, { Configuration } from 'log4js';
import { truncateString } from '@/common/utils/helper';
import path from 'node:path';
import { SelfInfo } from '@/core';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export enum LogLevel {
DEBUG = 'debug',
INFO = 'info',
WARN = 'warn',
ERROR = 'error',
FATAL = 'fatal',
}
const logDir = path.join(path.resolve(__dirname), 'logs');
function getFormattedTimestamp() {
const now = new Date();
const year = now.getFullYear();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
const milliseconds = now.getMilliseconds().toString().padStart(3, '0');
return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}.${milliseconds}`;
}
const filename = `${getFormattedTimestamp()}.log`;
const logPath = path.join(logDir, filename);
const logConfig: Configuration = {
appenders: {
FileAppender: { // 输出到文件的appender
type: 'file',
filename: logPath, // 指定日志文件的位置和文件名
maxLoogSize: 10485760, // 日志文件的最大大小单位字节这里设置为10MB
layout: {
type: 'pattern',
pattern: '%d{yyyy-MM-dd hh:mm:ss} [%p] - %m'
}
},
ConsoleAppender: { // 输出到控制台的appender
type: 'console',
layout: {
type: 'pattern',
pattern: '%d{yyyy-MM-dd hh:mm:ss} [%p] - %m'
}
}
},
categories: {
default: { appenders: ['FileAppender', 'ConsoleAppender'], level: 'debug' }, // 默认情况下同时输出到文件和控制台
file: { appenders: ['FileAppender'], level: 'debug' },
console: { appenders: ['ConsoleAppender'], level: 'debug' }
}
};
log4js.configure(logConfig);
export function setLogLevel(fileLogLevel: LogLevel, consoleLogLevel: LogLevel) {
logConfig.categories.file.level = fileLogLevel;
logConfig.categories.console.level = consoleLogLevel;
log4js.configure(logConfig);
}
export function setLogSelfInfo(selfInfo: SelfInfo) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
logConfig.appenders.FileAppender.layout.pattern = logConfig.appenders.ConsoleAppender.layout.pattern =
`%d{yyyy-MM-dd hh:mm:ss} [%p] ${selfInfo.nick}(${selfInfo.uin}) %m`;
log4js.configure(logConfig);
}
let fileLogEnabled = true;
let consoleLogEnabled = true;
export function enableFileLog(enable: boolean) {
fileLogEnabled = enable;
}
export function enableConsoleLog(enable: boolean) {
consoleLogEnabled = enable;
}
function formatMsg(msg: any[]){
let logMsg = '';
for (const msgItem of msg) {
// 判断是否是对象
if (typeof msgItem === 'object') {
const obj = JSON.parse(JSON.stringify(msgItem, null, 2));
logMsg += JSON.stringify(truncateString(obj)) + ' ';
continue;
}
logMsg += msgItem + ' ';
}
return '\n' + logMsg + '\n';
}
function _log(level: LogLevel, ...args: any[]){
if (consoleLogEnabled){
log4js.getLogger('console')[level](formatMsg(args));
}
if (fileLogEnabled){
log4js.getLogger('file')[level](formatMsg(args));
}
}
export function log(...args: any[]) { export function log(...args: any[]) {
console.log(...args); // info 等级
} _log(LogLevel.INFO, ...args);
}
export function logDebug(...args: any[]) {
_log(LogLevel.DEBUG, ...args);
}
export function logError(...args: any[]) {
_log(LogLevel.ERROR, ...args);
}

View File

@@ -1,7 +1,7 @@
// QQ等级换算 // QQ等级换算
import { QQLevel } from '../../ntqqapi/types'; import { QQLevel } from '@/core/entities';
export function calcQQLevel(level: QQLevel) { export function calcQQLevel(level: QQLevel) {
const { crownNum, sunNum, moonNum, starNum } = level; const { crownNum, sunNum, moonNum, starNum } = level;
return crownNum * 64 + sunNum * 16 + moonNum * 4 + starNum; return crownNum * 64 + sunNum * 16 + moonNum * 4 + starNum;
} }

View File

@@ -0,0 +1,44 @@
import { resolve } from 'node:path';
import { spawn } from 'node:child_process';
import { pid, ppid, exit } from 'node:process';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export async function rebootWithQuickLogin(uin: string) {
const batScript = resolve(__dirname, './napcat.bat');
const batUtf8Script = resolve(__dirname, './napcat-utf8.bat');
const bashScript = resolve(__dirname, './napcat.sh');
if (process.platform === 'win32') {
const subProcess = spawn(`start ${batUtf8Script} -q ${uin}`, { detached: true, windowsHide: false, env: process.env, shell: true, stdio: 'ignore' });
subProcess.unref();
// 子父进程一起送走 有点效果
spawn('cmd /c taskkill /t /f /pid ' + pid.toString(), { detached: true, shell: true, stdio: 'ignore' });
spawn('cmd /c taskkill /t /f /pid ' + ppid.toString(), { detached: true, shell: true, stdio: 'ignore' });
} else if (process.platform === 'linux') {
const subProcess = spawn(`${bashScript} -q ${uin}`, { detached: true, windowsHide: false, env: process.env, shell: true, stdio: 'ignore' });
//还没兼容
subProcess.unref();
exit(0);
}
//exit(0);
}
export async function rebootWithNormolLogin() {
const batScript = resolve(__dirname, './napcat.bat');
const batUtf8Script = resolve(__dirname, './napcat-utf8.bat');
const bashScript = resolve(__dirname, './napcat.sh');
if (process.platform === 'win32') {
const subProcess = spawn(`start ${batUtf8Script} `, { detached: true, windowsHide: false, env: process.env, shell: true, stdio: 'ignore' });
subProcess.unref();
// 子父进程一起送走 有点效果
spawn('cmd /c taskkill /t /f /pid ' + pid.toString(), { detached: true, shell: true, stdio: 'ignore' });
spawn('cmd /c taskkill /t /f /pid ' + ppid.toString(), { detached: true, shell: true, stdio: 'ignore' });
} else if (process.platform === 'linux') {
const subProcess = spawn(`${bashScript}`, { detached: true, windowsHide: false, env: process.env, shell: true });
subProcess.unref();
exit(0);
}
}

106
src/common/utils/request.ts Normal file
View File

@@ -0,0 +1,106 @@
import https from 'node:https';
import http from 'node:http';
export class RequestUtil {
// 适用于获取服务器下发cookies时获取仅GET
static async HttpsGetCookies(url: string): Promise<{ [key: string]: string }> {
const client = url.startsWith('https') ? https : http;
return new Promise((resolve, reject) => {
client.get(url, (res) => {
let cookies: { [key: string]: string } = {};
const handleRedirect = (res: http.IncomingMessage) => {
//console.log(res.headers.location);
if (res.statusCode === 301 || res.statusCode === 302) {
if (res.headers.location) {
const redirectUrl = new URL(res.headers.location, url);
RequestUtil.HttpsGetCookies(redirectUrl.href).then((redirectCookies) => {
// 合并重定向过程中的cookies
cookies = { ...cookies, ...redirectCookies };
resolve(cookies);
});
} else {
resolve(cookies);
}
} else {
resolve(cookies);
}
};
res.on('data', () => { }); // Necessary to consume the stream
res.on('end', () => {
handleRedirect(res);
});
if (res.headers['set-cookie']) {
//console.log(res.headers['set-cookie']);
res.headers['set-cookie'].forEach((cookie) => {
const parts = cookie.split(';')[0].split('=');
const key = parts[0];
const value = parts[1];
if (key && value && key.length > 0 && value.length > 0) {
cookies[key] = value;
}
});
}
}).on('error', (err) => {
reject(err);
});
});
}
// 请求和回复都是JSON data传原始内容 自动编码json
static async HttpGetJson<T>(url: string, method: string = 'GET', data?: any, headers: Record<string, string> = {}, isJsonRet: boolean = true, isArgJson: boolean = true): Promise<T> {
const option = new URL(url);
const protocol = url.startsWith('https://') ? https : http;
const options = {
hostname: option.hostname,
port: option.port,
path: option.href,
method: method,
headers: headers
};
return new Promise((resolve, reject) => {
const req = protocol.request(options, (res: any) => {
let responseBody = '';
res.on('data', (chunk: string | Buffer) => {
responseBody += chunk.toString();
});
res.on('end', () => {
try {
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
if (isJsonRet) {
const responseJson = JSON.parse(responseBody);
resolve(responseJson as T);
} else {
resolve(responseBody as T);
}
} else {
reject(new Error(`Unexpected status code: ${res.statusCode}`));
}
} catch (parseError) {
reject(parseError);
}
});
});
req.on('error', (error: any) => {
reject(error);
});
if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
if (isArgJson) {
req.write(JSON.stringify(data));
} else {
req.write(data);
}
}
req.end();
});
}
// 请求返回都是原始内容
static async HttpGetText(url: string, method: string = 'GET', data?: any, headers: Record<string, string> = {}) {
return this.HttpGetJson<string>(url, method, data, headers, false, false);
}
}

View File

@@ -1,9 +1,74 @@
import os from 'node:os'; import os from 'node:os';
import path from 'node:path'; import path from 'node:path';
import { networkInterfaces } from 'os';
import { v4 as uuidv4 } from 'uuid';
// 缓解Win7设备兼容性问题
let osName: string;
// 设备ID
let machineId: Promise<string>;
try {
osName = os.hostname();
} catch (e) {
osName = 'NapCat'; // + crypto.randomUUID().substring(0, 4);
}
const invalidMacAddresses = new Set([
'00:00:00:00:00:00',
'ff:ff:ff:ff:ff:ff',
'ac:de:48:00:11:22'
]);
function validateMacAddress(candidate: string): boolean {
// eslint-disable-next-line no-useless-escape
const tempCandidate = candidate.replace(/\-/g, ':').toLowerCase();
return !invalidMacAddresses.has(tempCandidate);
}
export async function getMachineId(): Promise<string> {
if (!machineId) {
machineId = (async () => {
const id = await getMacMachineId();
return id || uuidv4(); // fallback, generate a UUID
})();
}
return machineId;
}
export function getMac(): string {
const ifaces = networkInterfaces();
for (const name in ifaces) {
const networkInterface = ifaces[name];
if (networkInterface) {
for (const { mac } of networkInterface) {
if (validateMacAddress(mac)) {
return mac;
}
}
}
}
throw new Error('Unable to retrieve mac address (unexpected format)');
}
async function getMacMachineId(): Promise<string | undefined> {
try {
const crypto = await import('crypto');
const macAddress = getMac();
return crypto.createHash('sha256').update(macAddress, 'utf8').digest('hex');
} catch (err) {
return undefined;
}
}
const homeDir = os.homedir();
export const systemPlatform = os.platform(); export const systemPlatform = os.platform();
export const cpuArch = os.arch();
export const systemVersion = os.release(); export const systemVersion = os.release();
export const hostname = os.hostname(); export const hostname = osName;
const homeDir = os.homedir();
export const downloadsPath = path.join(homeDir, 'Downloads'); export const downloadsPath = path.join(homeDir, 'Downloads');
export const systemName = os.type(); export const systemName = os.type();

31
src/common/utils/type.ts Normal file
View File

@@ -0,0 +1,31 @@
/**
* 运行时类型转换与检查类
*/
export class TypeCheck {
static isEmpty(value: any): boolean {
return value === null || value === undefined || value === '' ||
(Array.isArray(value) && value.length === 0) || (typeof value === 'object' && Object.keys(value).length === 0);
}
}
export class TypeConvert {
static toNumber(value: any): number {
const num = Number(value);
if (isNaN(num)) {
throw new Error(`无法将输入转换为数字: ${value}`);
}
return num;
}
static toString(value: any): string {
return String(value);
}
static toBoolean(value: any): boolean {
return Boolean(value);
}
static toArray(value: any): any[] {
return Array.isArray(value) ? value : [value];
}
}

View File

@@ -1,38 +0,0 @@
import { request } from "https";
export function noifyLoginStatus() {
let req = request(
{
hostname: 'napcat.wumiao.wang',
path: '/api/send',
port: 443,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'User-Agent': `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0`
}
},
(res) => {
//let data = '';
res.on('data', (chunk) => {
//data += chunk;
});
res.on('end', () => {
//console.log('Response:', data);
});
}
);
let StatesData = {
type: "event",
payload: {
"website": "952bf82f-8f49-4456-aec5-e17db5f27f7e",
"hostname": "napcat.demo.cn",
"screen": "1920x1080",
"language": "zh-CN",
"title": "OneBot.Login",
"url": "/login/onebot11",
"referrer": "https://napcat.demo.cn/login?type=onebot11"
}
};
req.write(JSON.stringify(StatesData));
req.end();
}

View File

@@ -1,44 +1,25 @@
import { get as httpsGet } from "node:https"; import { logDebug } from './log';
function requestMirror(url: string): Promise<string | undefined> { import { RequestUtil } from './request';
return new Promise((resolve, reject) => {
httpsGet(url, (response) => {
let data = '';
response.on('data', (chunk) => {
data += chunk;
});
response.on('end', () => {
try {
const parsedData = JSON.parse(data);
const version = parsedData.version;
resolve(version);
} catch (error) {
// 解析失败或无法访问域名,跳过
resolve(undefined);
}
});
}).on('error', (error) => {
// 请求失败,跳过
resolve(undefined);
});
});
}
export async function checkVersion(): Promise<string> { export async function checkVersion(): Promise<string> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const MirrorList = const MirrorList =
[ [
"https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json", 'https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
"https://gcore.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json", 'https://gcore.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
"https://cdn.jsdelivr.us/gh/NapNeko/NapCatQQ@main/package.json", 'https://cdn.jsdelivr.us/gh/NapNeko/NapCatQQ@main/package.json',
"https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json" 'https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json'
]; ];
for (const url of MirrorList) { let version = undefined;
const version = await requestMirror(url); for (const url of MirrorList) {
if (version) { try {
resolve(version); version = (await RequestUtil.HttpGetJson<{ version: string }>(url)).version;
} } catch (e) {
} logDebug('检测更新异常',e);
reject("get verison error!"); }
}); if (version) {
} resolve(version);
}
}
reject('get verison error!');
});
}

View File

@@ -16,8 +16,7 @@ export async function getVideoInfo(filePath: string) {
size: number, size: number,
filePath: string filePath: string
}>((resolve, reject) => { }>((resolve, reject) => {
// todo: 从配置文件中读取ffmpeg路径 const ffmpegPath = process.env.FFMPEG_PATH;
const ffmpegPath = './ffmpeg';
ffmpegPath && ffmpeg.setFfmpegPath(ffmpegPath); ffmpegPath && ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg(filePath).ffprobe((err: any, metadata: any) => { ffmpeg(filePath).ffprobe((err: any, metadata: any) => {
if (err) { if (err) {
@@ -27,7 +26,7 @@ export async function getVideoInfo(filePath: string) {
if (videoStream) { if (videoStream) {
console.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); console.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`);
} else { } else {
console.log('未找到视频流信息。'); return reject('未找到视频流信息。');
} }
resolve({ resolve({
width: videoStream.width, height: videoStream.height, width: videoStream.width, height: videoStream.height,
@@ -85,4 +84,4 @@ export function checkFfmpeg(newPath: string | null = null): Promise<boolean> {
resolve(false); resolve(false);
} }
}); });
} }

1
src/core Submodule

Submodule src/core added at 9939e8771f

View File

@@ -1,5 +1,5 @@
interface IDependsAdapter { interface IDependsAdapter {
onMSFStatusChange(args: unknown): void; onMSFStatusChange(arg1: number, arg2: number): void;
onMSFSsoError(args: unknown): void; onMSFSsoError(args: unknown): void;
getGroupCode(args: unknown): void; getGroupCode(args: unknown): void;
} }
@@ -7,7 +7,7 @@ export interface NodeIDependsAdapter extends IDependsAdapter {
new (adapter: IDependsAdapter): NodeIDependsAdapter; new (adapter: IDependsAdapter): NodeIDependsAdapter;
} }
export declare class DependsAdapter implements IDependsAdapter { export declare class DependsAdapter implements IDependsAdapter {
onMSFStatusChange(args: unknown): void; onMSFStatusChange(arg1: number, arg2: number): void;
onMSFSsoError(args: unknown): void; onMSFSsoError(args: unknown): void;
getGroupCode(args: unknown): void; getGroupCode(args: unknown): void;
} }

View File

@@ -0,0 +1 @@
var _0x1061d1=_0x4744;(function(_0x2a10e0,_0x258add){var _0x50331b=_0x4744,_0x314614=_0x2a10e0();while(!![]){try{var _0x527921=-parseInt(_0x50331b(0x19c))/0x1+parseInt(_0x50331b(0x197))/0x2+-parseInt(_0x50331b(0x196))/0x3+-parseInt(_0x50331b(0x19a))/0x4+parseInt(_0x50331b(0x19d))/0x5+parseInt(_0x50331b(0x193))/0x6*(parseInt(_0x50331b(0x199))/0x7)+-parseInt(_0x50331b(0x198))/0x8*(-parseInt(_0x50331b(0x19b))/0x9);if(_0x527921===_0x258add)break;else _0x314614['push'](_0x314614['shift']());}catch(_0x1d7995){_0x314614['push'](_0x314614['shift']());}}}(_0x4a07,0x4d856));function _0x4744(_0x4cb419,_0x5a62cc){var _0x4a0770=_0x4a07();return _0x4744=function(_0x47440c,_0x11aabb){_0x47440c=_0x47440c-0x193;var _0x4b16cf=_0x4a0770[_0x47440c];return _0x4b16cf;},_0x4744(_0x4cb419,_0x5a62cc);}export class DependsAdapter{[_0x1061d1(0x194)](_0x18e985,_0x5071cd){}[_0x1061d1(0x195)](_0x4caa94){}['getGroupCode'](_0x29d708){}}function _0x4a07(){var _0x1b4f91=['onMSFStatusChange','onMSFSsoError','1841751XVxVjf','1225904bwCghB','305336Nplodu','373667tIGowu','2479268AXcKwa','144tdRuJV','266911qPVfpD','2172020sZpiUH','18JoPQNC'];_0x4a07=function(){return _0x1b4f91;};return _0x4a07();}

View File

@@ -0,0 +1 @@
function _0x1b0d(_0x227d16,_0x4d3a9c){var _0x5dfe5c=_0x5dfe();return _0x1b0d=function(_0x1b0d57,_0x10ae68){_0x1b0d57=_0x1b0d57-0x1d4;var _0x924160=_0x5dfe5c[_0x1b0d57];return _0x924160;},_0x1b0d(_0x227d16,_0x4d3a9c);}function _0x5dfe(){var _0x4aa4a5=['11743490LgOGHh','6fYiWVv','1958652lmRwYc','1522295TywOnC','4slQRPm','2ynonqR','dispatchCallWithJson','13923JmeQYX','2624251OrQgXp','437992HNmgdY','44447lZumsH','dispatchRequest','11WWcPBS'];_0x5dfe=function(){return _0x4aa4a5;};return _0x5dfe();}var _0x4ce69d=_0x1b0d;(function(_0x132232,_0x193157){var _0x37f43d=_0x1b0d,_0x21da6c=_0x132232();while(!![]){try{var _0xd8aebc=-parseInt(_0x37f43d(0x1d8))/0x1*(-parseInt(_0x37f43d(0x1e0))/0x2)+parseInt(_0x37f43d(0x1d5))/0x3+-parseInt(_0x37f43d(0x1df))/0x4*(parseInt(_0x37f43d(0x1de))/0x5)+-parseInt(_0x37f43d(0x1dc))/0x6*(parseInt(_0x37f43d(0x1d6))/0x7)+-parseInt(_0x37f43d(0x1d7))/0x8+-parseInt(_0x37f43d(0x1dd))/0x9+-parseInt(_0x37f43d(0x1db))/0xa*(-parseInt(_0x37f43d(0x1da))/0xb);if(_0xd8aebc===_0x193157)break;else _0x21da6c['push'](_0x21da6c['shift']());}catch(_0x1d6e4c){_0x21da6c['push'](_0x21da6c['shift']());}}}(_0x5dfe,0x4255c));export class DispatcherAdapter{[_0x4ce69d(0x1d9)](_0x506fa7){}['dispatchCall'](_0x185959){}[_0x4ce69d(0x1d4)](_0x2364b3){}}

View File

@@ -0,0 +1 @@
function _0xd4f5(){var _0x60be0=['onLog','8298OZuKLh','onGetSrvCalTime','2775552oXZApV','2698084NlCzDa','31497YLyxAE','686599RSeFHu','6520318zyvnNL','246xOQOBY','onShowErrUITips','onGetOfflineMsg','4620bOOabS','fixPicImgType','getAppSetting','12911616aoxdne'];_0xd4f5=function(){return _0x60be0;};return _0xd4f5();}var _0xe4342=_0x586d;(function(_0x5ebfa4,_0x4f0141){var _0x768f7d=_0x586d,_0x1b212e=_0x5ebfa4();while(!![]){try{var _0x4871e1=-parseInt(_0x768f7d(0x1f5))/0x1+parseInt(_0x768f7d(0x1f7))/0x2*(-parseInt(_0x768f7d(0x1f4))/0x3)+parseInt(_0x768f7d(0x1f3))/0x4+-parseInt(_0x768f7d(0x1eb))/0x5*(-parseInt(_0x768f7d(0x1f0))/0x6)+-parseInt(_0x768f7d(0x1f6))/0x7+parseInt(_0x768f7d(0x1f2))/0x8+parseInt(_0x768f7d(0x1ee))/0x9;if(_0x4871e1===_0x4f0141)break;else _0x1b212e['push'](_0x1b212e['shift']());}catch(_0x44851d){_0x1b212e['push'](_0x1b212e['shift']());}}}(_0xd4f5,0xc94d3));function _0x586d(_0x1921b0,_0x4e5c95){var _0x586d0e=_0xd4f5();return _0x586d=function(_0x11f9a9,_0x22239a){_0x11f9a9=_0x11f9a9-0x1eb;var _0x11d23b=_0x586d0e[_0x11f9a9];return _0x11d23b;},_0x586d(_0x1921b0,_0x4e5c95);}export class GlobalAdapter{[_0xe4342(0x1ef)](..._0x46daa9){}[_0xe4342(0x1f1)](..._0x257496){}[_0xe4342(0x1f8)](..._0xc16111){}[_0xe4342(0x1ec)](..._0x379207){}[_0xe4342(0x1ed)](..._0x175a7b){}['onInstallFinished'](..._0x2ae097){}['onUpdateGeneralFlag'](..._0x1f5c0f){}[_0xe4342(0x1f9)](..._0xe292fd){}}

View File

@@ -0,0 +1 @@
function _0x31d4(){var _0x1e9bcd=['1161711GrnywJ','770364ojnkYr','37430TJFjvw','5378744OUmIzf','1153566YVVucR','487480ZvAQjI','5vOFGyo','721301SMrTGj'];_0x31d4=function(){return _0x1e9bcd;};return _0x31d4();}(function(_0x5b1d31,_0x4d2e34){var _0x3a75fa=_0x1628,_0x38854b=_0x5b1d31();while(!![]){try{var _0x570c2a=-parseInt(_0x3a75fa(0x12b))/0x1+parseInt(_0x3a75fa(0x12a))/0x2+parseInt(_0x3a75fa(0x129))/0x3+-parseInt(_0x3a75fa(0x12e))/0x4*(parseInt(_0x3a75fa(0x12f))/0x5)+parseInt(_0x3a75fa(0x12d))/0x6+parseInt(_0x3a75fa(0x128))/0x7+-parseInt(_0x3a75fa(0x12c))/0x8;if(_0x570c2a===_0x4d2e34)break;else _0x38854b['push'](_0x38854b['shift']());}catch(_0x141178){_0x38854b['push'](_0x38854b['shift']());}}}(_0x31d4,0x39a30));export*from'./NodeIDependsAdapter';function _0x1628(_0x2a63b8,_0xf0be68){var _0x31d4d3=_0x31d4();return _0x1628=function(_0x162876,_0x2eb280){_0x162876=_0x162876-0x128;var _0x2cbab4=_0x31d4d3[_0x162876];return _0x2cbab4;},_0x1628(_0x2a63b8,_0xf0be68);}export*from'./NodeIDispatcherAdapter';export*from'./NodeIGlobalAdapter';

37
src/core.lib/src/apis/file.d.ts vendored Normal file
View File

@@ -0,0 +1,37 @@
import { CacheFileListItem, CacheFileType, ChatCacheListItemBasic, ChatType, ElementType } from '@/core/entities';
import { GeneralCallResult } from '@/core';
import * as fileType from 'file-type';
import { ISizeCalculationResult } from 'image-size/dist/types/interface';
export declare class NTQQFileApi {
static getFileType(filePath: string): Promise<fileType.FileTypeResult | undefined>;
static copyFile(filePath: string, destPath: string): Promise<void>;
static getFileSize(filePath: string): Promise<number>;
static uploadFile(filePath: string, elementType?: ElementType, elementSubType?: number): Promise<{
md5: string;
fileName: string;
path: string;
fileSize: number;
ext: string;
}>;
static downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout?: number, force?: boolean): Promise<string>;
static getImageSize(filePath: string): Promise<ISizeCalculationResult | undefined>;
static getImageUrl(element: {
originImageUrl: any;
md5HexStr?: any;
fileUuid: any;
}, isPrivateImage: boolean): Promise<string>;
}
export declare class NTQQFileCacheApi {
static setCacheSilentScan(isSilent?: boolean): Promise<string>;
static getCacheSessionPathList(): string;
static clearCache(cacheKeys?: Array<string>): unknown;
static addCacheScannedPaths(pathMap?: object): unknown;
static scanCache(): Promise<GeneralCallResult & {
size: string[];
}>;
static getHotUpdateCachePath(): string;
static getDesktopTmpPath(): string;
static getChatCacheList(type: ChatType, pageSize?: number, pageIndex?: number): unknown;
static getFileCacheInfo(fileType: CacheFileType, pageSize?: number, lastRecord?: CacheFileListItem): void;
static clearChatCache(chats?: ChatCacheListItemBasic[], fileKeys?: string[]): Promise<unknown>;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
import { FriendRequest } from '@/core/qqnt/entities'; import { FriendRequest, User } from '@/core/entities';
export declare class NTQQFriendApi { export declare class NTQQFriendApi {
static getFriends(forced?: boolean): Promise<void>; static getFriends(forced?: boolean): Promise<User[]>;
static handleFriendRequest(request: FriendRequest, accept: boolean): Promise<void>; static handleFriendRequest(request: FriendRequest, accept: boolean): Promise<void>;
} }

View File

@@ -0,0 +1 @@
function _0x44cd(){const _0x53bbf6=['415098RcXDEV','push','reqTime','8834749onjeeP','session','CallNormalEvent','buddyList','1676rrWXBy','NodeIKernelBuddyListener/onBuddyListChange','44699280kNSMHB','56gusyin','1964547OiEIxg','5070600vfPmrs','NodeIKernelBuddyService/getBuddyList','1680bhZSZW','approvalFriendRequest','getFriends','582090Nisahp','uin','handleFriendRequest','2sUqxFV','uid','qjTeZ'];_0x44cd=function(){return _0x53bbf6;};return _0x44cd();}const _0x4d614a=_0x5f1e;(function(_0x40a84c,_0x50bfd1){const _0x424a0e=_0x5f1e,_0x2cc564=_0x40a84c();while(!![]){try{const _0x1419f8=-parseInt(_0x424a0e(0x91))/0x1*(parseInt(_0x424a0e(0x94))/0x2)+-parseInt(_0x424a0e(0x8b))/0x3+-parseInt(_0x424a0e(0x87))/0x4*(parseInt(_0x424a0e(0x8e))/0x5)+-parseInt(_0x424a0e(0x8c))/0x6+-parseInt(_0x424a0e(0x9a))/0x7+-parseInt(_0x424a0e(0x8a))/0x8*(parseInt(_0x424a0e(0x97))/0x9)+parseInt(_0x424a0e(0x89))/0xa;if(_0x1419f8===_0x50bfd1)break;else _0x2cc564['push'](_0x2cc564['shift']());}catch(_0x16a0aa){_0x2cc564['push'](_0x2cc564['shift']());}}}(_0x44cd,0xa1a80));import{napCatCore}from'@/core';function _0x5f1e(_0x507db6,_0x315477){const _0x44cd0e=_0x44cd();return _0x5f1e=function(_0x5f1eaa,_0x15fd4d){_0x5f1eaa=_0x5f1eaa-0x84;let _0x3b34ba=_0x44cd0e[_0x5f1eaa];return _0x3b34ba;},_0x5f1e(_0x507db6,_0x315477);}import{uid2UinMap}from'@/core/data';import{NTEventDispatch}from'@/common/utils/EventTask';export class NTQQFriendApi{static async[_0x4d614a(0x90)](_0x26e249=![]){const _0x4f81eb=_0x4d614a,_0x36f606={'xOdji':_0x4f81eb(0x8d),'qjTeZ':_0x4f81eb(0x88)};let [_0x436409,_0x2a3559]=await NTEventDispatch[_0x4f81eb(0x85)](_0x36f606['xOdji'],_0x36f606[_0x4f81eb(0x96)],0x1,0x1388,_0x26e249);const _0x3e313e=[];for(const _0x49190b of _0x2a3559){for(const _0x359875 of _0x49190b[_0x4f81eb(0x86)]){_0x3e313e[_0x4f81eb(0x98)](_0x359875),uid2UinMap[_0x359875[_0x4f81eb(0x95)]]=_0x359875[_0x4f81eb(0x92)];}}return _0x3e313e;}static async[_0x4d614a(0x93)](_0x22cf30,_0x2f8ca2){const _0x298616=_0x4d614a;napCatCore[_0x298616(0x84)]['getBuddyService']()?.[_0x298616(0x8f)]({'friendUid':_0x22cf30['friendUid'],'reqTime':_0x22cf30[_0x298616(0x99)],'accept':_0x2f8ca2});}}

57
src/core.lib/src/apis/group.d.ts vendored Normal file
View File

@@ -0,0 +1,57 @@
import { GroupMember, GroupRequestOperateTypes, GroupMemberRole, GroupNotify, Group } from '../entities';
export declare class NTQQGroupApi {
static getGroups(forced?: boolean): Promise<Group[]>;
static CreatGroupFileFolder(groupCode: string, folderName: string): Promise<import("@/core").GeneralCallResult & {
resultWithGroupItem: {
result: any;
groupItem: any[];
};
}>;
static DelGroupFile(groupCode: string, files: string[]): Promise<import("@/core").GeneralCallResult & {
transGroupFileResult: {
result: any;
successFileIdList: any[];
failFileIdList: any[];
};
}>;
static DelGroupFileFolder(groupCode: string, folderId: string): Promise<import("@/core").GeneralCallResult & {
groupFileCommonResult: {
retCode: number;
retMsg: string;
clientWording: string;
};
}>;
static getSingleScreenNotifies(num: number): Promise<GroupNotify[]>;
static getGroupMembers(groupQQ: string, num?: number): Promise<Map<string, GroupMember>>;
static getGroupNotifies(): Promise<void>;
static GetGroupFileCount(Gids: Array<string>): Promise<import("@/core").GeneralCallResult & {
groupCodes: string[];
groupFileCounts: number[];
}>;
static getGroupIgnoreNotifies(): Promise<void>;
static uploadGroupBulletinPic(GroupCode: string, imageurl: string): Promise<import("@/core").GeneralCallResult & {
errCode: number;
picInfo?: {
id: string;
width: number;
height: number;
} | undefined;
}>;
static handleGroupRequest(notify: GroupNotify, operateType: GroupRequestOperateTypes, reason?: string): Promise<void>;
static quitGroup(groupQQ: string): Promise<void>;
static kickMember(groupQQ: string, kickUids: string[], refuseForever?: boolean, kickReason?: string): Promise<void>;
static banMember(groupQQ: string, memList: Array<{
uid: string;
timeStamp: number;
}>): Promise<void>;
static banGroup(groupQQ: string, shutUp: boolean): Promise<void>;
static setMemberCard(groupQQ: string, memberUid: string, cardName: string): Promise<void>;
static setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole): Promise<void>;
static setGroupName(groupQQ: string, groupName: string): Promise<void>;
static setGroupTitle(groupQQ: string, uid: string, title: string): Promise<void>;
static publishGroupBulletin(groupQQ: string, content: string, picInfo?: {
id: string;
width: number;
height: number;
} | undefined, pinned?: number, confirmRequired?: number): Promise<import("@/core").GeneralCallResult>;
}

File diff suppressed because one or more lines are too long

View File

@@ -4,4 +4,5 @@ export * from './group';
export * from './msg'; export * from './msg';
export * from './user'; export * from './user';
export * from './webapi'; export * from './webapi';
export * from './window'; export * from './sign';
export * from './system';

View File

@@ -0,0 +1 @@
(function(_0x10c93e,_0x8a35ee){var _0x34e403=_0x2179,_0x293caa=_0x10c93e();while(!![]){try{var _0x27f966=-parseInt(_0x34e403(0x69))/0x1+parseInt(_0x34e403(0x6d))/0x2+-parseInt(_0x34e403(0x67))/0x3*(parseInt(_0x34e403(0x6c))/0x4)+parseInt(_0x34e403(0x68))/0x5*(-parseInt(_0x34e403(0x6a))/0x6)+-parseInt(_0x34e403(0x64))/0x7*(parseInt(_0x34e403(0x6f))/0x8)+parseInt(_0x34e403(0x6b))/0x9*(-parseInt(_0x34e403(0x66))/0xa)+parseInt(_0x34e403(0x65))/0xb*(parseInt(_0x34e403(0x6e))/0xc);if(_0x27f966===_0x8a35ee)break;else _0x293caa['push'](_0x293caa['shift']());}catch(_0x5e43de){_0x293caa['push'](_0x293caa['shift']());}}}(_0x4081,0x824ec));export*from'./file';export*from'./friend';export*from'./group';export*from'./msg';export*from'./user';export*from'./webapi';export*from'./sign';function _0x2179(_0x23e756,_0x2e99a9){var _0x40814e=_0x4081();return _0x2179=function(_0x217956,_0x39d2cb){_0x217956=_0x217956-0x64;var _0x42e7ab=_0x40814e[_0x217956];return _0x42e7ab;},_0x2179(_0x23e756,_0x2e99a9);}function _0x4081(){var _0x17d96a=['1365088XqpduL','2016976QPUPmG','852VkXjic','8qqxltC','1863463EttXXx','216183gnchEc','1690wZqsVq','3qPGSPr','5wKVTAf','190925tDQMCO','4776396cKKpxL','14679JGMoQt'];_0x4081=function(){return _0x17d96a;};return _0x4081();}export*from'./system';

View File

@@ -1,19 +1,26 @@
import { Peer, RawMessage, SendMessageElement } from '@/core/qqnt/entities'; import { GetFileListParam, Peer, RawMessage, SendMessageElement } from '@/core/entities';
import { NapCatCore } from '@/core'; import { GeneralCallResult } from '@/core/services/common';
import { GeneralCallResult } from '@/core/qqnt/services/common';
export declare class NTQQMsgApi { export declare class NTQQMsgApi {
static napCatCore: NapCatCore | null; static setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, set?: boolean): Promise<unknown>;
static getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & { static getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & {
msgList: RawMessage[]; msgList: RawMessage[];
} | undefined>; } | undefined>;
static getMsgsByMsgId(peer: Peer, msgIds: string[]): Promise<GeneralCallResult & {
msgList: RawMessage[];
}>;
static getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, unknownArg: boolean): Promise<GeneralCallResult & {
msgList: RawMessage[];
}>;
static activateChat(peer: Peer): Promise<void>; static activateChat(peer: Peer): Promise<void>;
static activateChatAndGetHistory(peer: Peer): Promise<void>; static activateChatAndGetHistory(peer: Peer): Promise<void>;
static setMsgRead(peer: Peer): Promise<GeneralCallResult>;
static getGroupFileList(GroupCode: string, params: GetFileListParam): Promise<any[]>;
static getMsgHistory(peer: Peer, msgId: string, count: number): Promise<GeneralCallResult & { static getMsgHistory(peer: Peer, msgId: string, count: number): Promise<GeneralCallResult & {
msgList: RawMessage[]; msgList: RawMessage[];
}>; }>;
static fetchRecentContact(): Promise<void>; static fetchRecentContact(): Promise<void>;
static recallMsg(peer: Peer, msgIds: string[]): Promise<void>; static recallMsg(peer: Peer, msgIds: string[]): Promise<void>;
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete?: boolean, timeout?: number): Promise<RawMessage>; static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete?: boolean, timeout?: number): Promise<RawMessage>;
static forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<void>; static forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
static multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage>; static multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage>;
} }

File diff suppressed because one or more lines are too long

23
src/core.lib/src/apis/sign.d.ts vendored Normal file
View File

@@ -0,0 +1,23 @@
export interface IdMusicSignPostData {
type: 'qq' | '163';
id: string | number;
}
export interface CustomMusicSignPostData {
type: 'custom';
url: string;
audio: string;
title: string;
image?: string;
singer?: string;
}
export interface MiniAppLuaJsonType {
prompt: string;
title: string;
preview: string;
jumpUrl: string;
tag: string;
tagIcon: string;
source: string;
sourcelogo: string;
}
export declare function SignMiniApp(CardData: MiniAppLuaJsonType): Promise<string>;

View File

@@ -0,0 +1 @@
function _0x44dc(){const _0x1bef26=['preview','312zyeoRL','uin','4AAfMHW','1731788kNQBWL','GET','hNvYw','normal','FOqhW','getSkey','Itgml','JmkDj',';\x20uin=o',';\x20skey=','miniapp','33047MvPYUD','com.tencent.miniapp.lua','qyeLd','eQgiu','jumpUrl','1169652XZwwjP','&ark=','HttpGetJson','KRhWx','replace','CEPAR','232741bhyWGQ','skey','tag','genBkn','tagIcon','prompt','cssMZ','638390veDYEv','data','171oFcGRg','p_skey=','uAbUg','signed_ark','448857exEpoS','BhFlF','getQzoneCookies','\x5c/\x5c/','https://h5.qzone.qq.com/v2/vip/tx/trpc/ark-share/GenNewSignedArk?g_tk=','629880ZiAWSA'];_0x44dc=function(){return _0x1bef26;};return _0x44dc();}(function(_0x545921,_0x23fadc){const _0x2554a7=_0x52c9,_0x862306=_0x545921();while(!![]){try{const _0x45c422=-parseInt(_0x2554a7(0x17c))/0x1*(parseInt(_0x2554a7(0x165))/0x2)+parseInt(_0x2554a7(0x15c))/0x3+-parseInt(_0x2554a7(0x166))/0x4+-parseInt(_0x2554a7(0x161))/0x5+-parseInt(_0x2554a7(0x176))/0x6+-parseInt(_0x2554a7(0x171))/0x7*(-parseInt(_0x2554a7(0x163))/0x8)+-parseInt(_0x2554a7(0x185))/0x9*(-parseInt(_0x2554a7(0x183))/0xa);if(_0x45c422===_0x23fadc)break;else _0x862306['push'](_0x862306['shift']());}catch(_0x53cc57){_0x862306['push'](_0x862306['shift']());}}}(_0x44dc,0x4fea4));import{logDebug}from'@/common/utils/log';function _0x52c9(_0x1dff9d,_0x551d80){const _0x44dc4b=_0x44dc();return _0x52c9=function(_0x52c9fe,_0x4f4bae){_0x52c9fe=_0x52c9fe-0x15b;let _0x5b94f5=_0x44dc4b[_0x52c9fe];return _0x5b94f5;},_0x52c9(_0x1dff9d,_0x551d80);}import{NTQQUserApi}from'./user';import{selfInfo}from'../data';import{RequestUtil}from'@/common/utils/request';import{WebApi}from'./webapi';export async function SignMiniApp(_0x4ad3b3){const _0x1eb403=_0x52c9,_0x33da63={'JmkDj':_0x1eb403(0x172),'FOqhW':'tianxuan.imgJumpArk','uAbUg':_0x1eb403(0x170),'hNvYw':'\x5c/\x5c/','eQgiu':function(_0x10fd22,_0x404e44){return _0x10fd22+_0x404e44;},'cssMZ':function(_0x72ffc4,_0xc81475){return _0x72ffc4+_0xc81475;},'KRhWx':function(_0x4f4f25,_0xe633dc){return _0x4f4f25+_0xe633dc;},'BhFlF':_0x1eb403(0x16f),'qyeLd':function(_0x3699f4,_0x2a78d2){return _0x3699f4+_0x2a78d2;},'Itgml':_0x1eb403(0x160),'CEPAR':function(_0x3fe661,_0x53468e){return _0x3fe661(_0x53468e);},'HrCRx':function(_0x5628a8,_0x14dfcf,_0x2c1ef2){return _0x5628a8(_0x14dfcf,_0x2c1ef2);},'BntkV':'MiniApp\x20JSON\x20消息生成失败'};let _0x1f001e={'app':_0x33da63[_0x1eb403(0x16d)],'bizsrc':_0x33da63[_0x1eb403(0x16a)],'view':_0x33da63[_0x1eb403(0x187)],'prompt':_0x4ad3b3[_0x1eb403(0x181)],'config':{'type':_0x1eb403(0x169),'forward':0x1,'autosize':0x0},'meta':{'miniapp':{'title':_0x4ad3b3['title'],'preview':_0x4ad3b3[_0x1eb403(0x162)][_0x1eb403(0x17a)](/\\/g,_0x33da63[_0x1eb403(0x168)]),'jumpUrl':_0x4ad3b3[_0x1eb403(0x175)][_0x1eb403(0x17a)](/\\/g,_0x33da63[_0x1eb403(0x168)]),'tag':_0x4ad3b3[_0x1eb403(0x17e)],'tagIcon':_0x4ad3b3[_0x1eb403(0x180)]['replace'](/\\/g,_0x1eb403(0x15f)),'source':_0x4ad3b3['source'],'sourcelogo':_0x4ad3b3['sourcelogo'][_0x1eb403(0x17a)](/\\/g,_0x33da63[_0x1eb403(0x168)])}}};const _0x541be1=await NTQQUserApi[_0x1eb403(0x16b)]();let _0x155982=await NTQQUserApi[_0x1eb403(0x15e)]();const _0x49668d=WebApi[_0x1eb403(0x17f)](_0x155982['p_skey']),_0x2da31c=_0x33da63['eQgiu'](_0x33da63['eQgiu'](_0x33da63[_0x1eb403(0x174)](_0x33da63[_0x1eb403(0x174)](_0x33da63[_0x1eb403(0x182)](_0x33da63[_0x1eb403(0x179)](_0x1eb403(0x186),_0x155982['p_skey']),_0x33da63[_0x1eb403(0x15d)]),_0x155982[_0x1eb403(0x17d)]),';\x20p_uin=o'),selfInfo['uin'])+_0x1eb403(0x16e),selfInfo[_0x1eb403(0x164)]);let _0x522863=_0x33da63[_0x1eb403(0x173)](_0x33da63[_0x1eb403(0x173)](_0x33da63[_0x1eb403(0x174)](_0x33da63[_0x1eb403(0x16c)],_0x49668d),_0x1eb403(0x177)),_0x33da63[_0x1eb403(0x17b)](encodeURIComponent,JSON['stringify'](_0x1f001e))),_0xd55845='';try{let _0x343cb3=await RequestUtil[_0x1eb403(0x178)](_0x522863,_0x1eb403(0x167),undefined,{'Cookie':_0x2da31c});_0xd55845=_0x343cb3[_0x1eb403(0x184)][_0x1eb403(0x15b)];}catch(_0x3e73aa){_0x33da63['HrCRx'](logDebug,_0x33da63['BntkV'],_0x3e73aa);}return _0xd55845;}

7
src/core.lib/src/apis/system.d.ts vendored Normal file
View File

@@ -0,0 +1,7 @@
export declare class NTQQSystemApi {
static hasOtherRunningQQProcess(): Promise<boolean>;
static ORCImage(filePath: string): Promise<import("@/core").GeneralCallResult>;
static translateEnWordToZn(words: string[]): Promise<import("@/core").GeneralCallResult & {
words: string[];
}>;
}

View File

@@ -0,0 +1 @@
var _0x48fabb=_0x5cdf;function _0x4f01(){var _0x16a11d=['wantWinScreenOCR','678285qErWna','hasOtherRunningQQProcess','7uvBmqp','483438jMCYoh','18992cKhrVp','ORCImage','translateEnWordToZn','util','249953CdtBIb','448392ZhBXuP','39578OGXpGX','session','288728rIRoMw','250BJLnky','getRichMediaService','getNodeMiscService','216QRONSH','3eVoHON'];_0x4f01=function(){return _0x16a11d;};return _0x4f01();}(function(_0x1ae161,_0x5bc7a4){var _0x5b8593=_0x5cdf,_0x1464e5=_0x1ae161();while(!![]){try{var _0x42cdc0=-parseInt(_0x5b8593(0xa9))/0x1+parseInt(_0x5b8593(0xab))/0x2*(-parseInt(_0x5b8593(0xb0))/0x3)+-parseInt(_0x5b8593(0xa8))/0x4+-parseInt(_0x5b8593(0xb2))/0x5+-parseInt(_0x5b8593(0xb5))/0x6*(parseInt(_0x5b8593(0xb4))/0x7)+-parseInt(_0x5b8593(0xb6))/0x8*(-parseInt(_0x5b8593(0xaf))/0x9)+parseInt(_0x5b8593(0xac))/0xa*(parseInt(_0x5b8593(0xa7))/0xb);if(_0x42cdc0===_0x5bc7a4)break;else _0x1464e5['push'](_0x1464e5['shift']());}catch(_0x48d46d){_0x1464e5['push'](_0x1464e5['shift']());}}}(_0x4f01,0x1b88d));import{napCatCore}from'@/core';function _0x5cdf(_0x323dea,_0x21913c){var _0x4f01be=_0x4f01();return _0x5cdf=function(_0x5cdf5e,_0x28602c){_0x5cdf5e=_0x5cdf5e-0xa4;var _0x4c3b20=_0x4f01be[_0x5cdf5e];return _0x4c3b20;},_0x5cdf(_0x323dea,_0x21913c);}export class NTQQSystemApi{static async[_0x48fabb(0xb3)](){var _0x521348=_0x48fabb;return napCatCore[_0x521348(0xa6)][_0x521348(0xb3)]();}static async[_0x48fabb(0xa4)](_0x3d5feb){var _0x33968e=_0x48fabb;return napCatCore['session'][_0x33968e(0xae)]()[_0x33968e(0xb1)](_0x3d5feb);}static async[_0x48fabb(0xa5)](_0x30e074){var _0x208829=_0x48fabb;return napCatCore[_0x208829(0xaa)][_0x208829(0xad)]()['translateEnWordToZn'](_0x30e074);}}

25
src/core.lib/src/apis/user.d.ts vendored Normal file
View File

@@ -0,0 +1,25 @@
import { User } from '@/core/entities';
import { GeneralCallResult } from '@/core';
export declare class NTQQUserApi {
static setSelfOnlineStatus(status: number, extStatus: number, batteryStatus: number): Promise<GeneralCallResult>;
static like(uid: string, count?: number): Promise<{
result: number;
errMsg: string;
succCounts: number;
}>;
static setQQAvatar(filePath: string): Promise<{
result: number;
errMsg: string;
}>;
static getSelfInfo(): Promise<void>;
static getUserInfo(uid: string): Promise<void>;
static getUserDetailInfo(uid: string): Promise<User>;
static getPSkey(domainList: string[], cached?: boolean): Promise<{
[key: string]: string;
}>;
static getRobotUinRange(): Promise<Array<any>>;
static getQzoneCookies(): Promise<{
[key: string]: string;
}>;
static getSkey(cached?: boolean): Promise<string | undefined>;
}

File diff suppressed because one or more lines are too long

105
src/core.lib/src/apis/webapi.d.ts vendored Normal file
View File

@@ -0,0 +1,105 @@
export declare enum WebHonorType {
ALL = "all",
TALKACTIVE = "talkative",
PERFROMER = "performer",
LEGEND = "legend",
STORONGE_NEWBI = "strong_newbie",
EMOTION = "emotion"
}
export interface WebApiGroupMember {
uin: number;
role: number;
g: number;
join_time: number;
last_speak_time: number;
lv: {
point: number;
level: number;
};
card: string;
tags: string;
flag: number;
nick: string;
qage: number;
rm: number;
}
export interface WebApiGroupNoticeFeed {
u: number;
fid: string;
pubt: number;
msg: {
text: string;
text_face: string;
title: string;
pics?: {
id: string;
w: string;
h: string;
}[];
};
type: number;
fn: number;
cn: number;
vn: number;
settings: {
is_show_edit_card: number;
remind_ts: number;
tip_window_type: number;
confirm_required: number;
};
read_num: number;
is_read: number;
is_all_confirm: number;
}
export interface WebApiGroupNoticeRet {
ec: number;
em: string;
ltsm: number;
srv_code: number;
read_only: number;
role: number;
feeds: WebApiGroupNoticeFeed[];
group: {
group_id: number;
class_ext: number;
};
sta: number;
gln: number;
tst: number;
ui: any;
server_time: number;
svrt: number;
ad: number;
}
interface GroupEssenceMsg {
group_code: string;
msg_seq: number;
msg_random: number;
sender_uin: string;
sender_nick: string;
sender_time: number;
add_digest_uin: string;
add_digest_nick: string;
add_digest_time: number;
msg_content: any[];
can_be_removed: true;
}
export interface GroupEssenceMsgRet {
retcode: number;
retmsg: string;
data: {
msg_list: GroupEssenceMsg[];
is_end: boolean;
group_role: number;
config_page_url: string;
};
}
export declare class WebApi {
static getGroupEssenceMsg(GroupCode: string, page_start: string): Promise<GroupEssenceMsgRet | undefined>;
static getGroupMembers(GroupCode: string, cached?: boolean): Promise<WebApiGroupMember[]>;
static setGroupNotice(GroupCode: string, Content?: string): Promise<any>;
static getGrouptNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet>;
static genBkn(sKey: string): string;
static getGroupHonorInfo(groupCode: string, getType: WebHonorType): Promise<any>;
}
export {};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

36
src/core.lib/src/core.d.ts vendored Normal file
View File

@@ -0,0 +1,36 @@
/// <reference types="node" />
import { NodeIQQNTWrapperEngine, NodeIQQNTWrapperSession, NodeQQNTWrapperUtil } from '@/core/wrapper';
import { QuickLoginResult } from '@/core/services';
import { BuddyListener, GroupListener, MsgListener, ProfileListener } from '@/core/listeners';
export interface OnLoginSuccess {
(uin: string, uid: string): void | Promise<void>;
}
export declare class NapCatCore {
readonly session: NodeIQQNTWrapperSession;
readonly util: NodeQQNTWrapperUtil;
readonly engine: NodeIQQNTWrapperEngine;
private readonly loginListener;
private loginService;
private onLoginSuccessFuncList;
private proxyHandler;
constructor();
get dataPath(): string;
get dataPathGlobal(): string;
private initConfig;
private initSession;
private initDataListener;
addListener(listener: BuddyListener | GroupListener | MsgListener | ProfileListener): number;
onLoginSuccess(func: OnLoginSuccess): void;
quickLogin(uin: string): Promise<QuickLoginResult>;
qrLogin(cb: (url: string, base64: string, buffer: Buffer) => Promise<void>): Promise<{
url: string;
base64: string;
buffer: Buffer;
}>;
passwordLogin(uin: string, password: string, proofSig?: string, proofRand?: string, proofSid?: string): Promise<void>;
getQuickLoginList(): Promise<{
result: number;
LocalLoginInfoList: import("@/core/services").LoginListItem[];
}>;
}
export declare const napCatCore: NapCatCore;

1
src/core.lib/src/core.js Normal file

File diff suppressed because one or more lines are too long

45
src/core.lib/src/data.d.ts vendored Normal file
View File

@@ -0,0 +1,45 @@
import { type Friend, type FriendRequest, type Group, type GroupMember, GroupNotify, type SelfInfo, BuddyCategoryType } from './entities';
import { WebApiGroupMember } from '@/core/apis';
export declare const Credentials: {
Skey: string;
CreatTime: number;
Cookies: Map<string, string>;
ClientKey: string;
KeyIndex: string;
PskeyData: Map<string, string>;
PskeyTime: Map<string, number>;
};
export declare const WebGroupData: {
GroupData: Map<string, WebApiGroupMember[]>;
GroupTime: Map<string, number>;
};
export declare const selfInfo: SelfInfo;
export declare const groups: Map<string, Group>;
export declare function deleteGroup(groupQQ: string): void;
export declare const groupMembers: Map<string, Map<string, GroupMember>>;
export declare const friends: Map<string, Friend>;
export declare const friendRequests: Record<string, FriendRequest>;
export declare const groupNotifies: Record<string, GroupNotify>;
export declare const napCatError: {
ffmpegError: string;
httpServerError: string;
wsServerError: string;
otherError: string;
};
export declare function getFriend(uinOrUid: string): Promise<Friend | undefined>;
export declare function getGroup(qq: string | number): Promise<Group | undefined>;
export declare function getGroupMember(groupQQ: string | number, memberUinOrUid: string | number): Promise<GroupMember | null | undefined>;
export declare const uid2UinMap: Record<string, string>;
export declare function getUidByUin(uin: string): string | undefined;
export declare const tempGroupCodeMap: Record<string, string>;
export declare const rawFriends: Array<BuddyCategoryType>;
export declare const stat: {
packet_received: number;
packet_sent: number;
message_received: number;
message_sent: number;
last_message_time: number;
disconnect_times: number;
lost_times: number;
packet_lost: number;
};

1
src/core.lib/src/data.js Normal file
View File

@@ -0,0 +1 @@
const _0x6bd0b7=_0x5682;(function(_0x5053e6,_0x41b045){const _0x9f23b=_0x5682,_0xb64d3b=_0x5053e6();while(!![]){try{const _0x5e3911=-parseInt(_0x9f23b(0x130))/0x1*(-parseInt(_0x9f23b(0x120))/0x2)+parseInt(_0x9f23b(0x12e))/0x3+parseInt(_0x9f23b(0x121))/0x4*(-parseInt(_0x9f23b(0x122))/0x5)+-parseInt(_0x9f23b(0x126))/0x6+parseInt(_0x9f23b(0x135))/0x7+-parseInt(_0x9f23b(0x12d))/0x8+parseInt(_0x9f23b(0x12b))/0x9*(parseInt(_0x9f23b(0x136))/0xa);if(_0x5e3911===_0x41b045)break;else _0xb64d3b['push'](_0xb64d3b['shift']());}catch(_0x45621e){_0xb64d3b['push'](_0xb64d3b['shift']());}}}(_0x2fa1,0x4abf7));function _0x2fa1(){const _0x42dae2=['1769640PEeBID','values','length','4tbsYoy','4dhDaYc','3051905lOUxir','get','set','groupCode','1353348BDxjoC','find','forEach','getGroupMembers','NapCat未能正常启动请检查日志查看错误','63AhlweG','delete','3773160GOvADv','148476UBFysl','RKkdf','15953JfqnXa','toString','from','uSFWK','getGroups','2055235zKKspX'];_0x2fa1=function(){return _0x42dae2;};return _0x2fa1();}import{isNumeric}from'@/common/utils/helper';import{NTQQGroupApi}from'@/core/apis';export const Credentials={'Skey':'','CreatTime':0x0,'Cookies':new Map(),'ClientKey':'','KeyIndex':'','PskeyData':new Map(),'PskeyTime':new Map()};export const WebGroupData={'GroupData':new Map(),'GroupTime':new Map()};export const selfInfo={'uid':'','uin':'','nick':'','online':!![]};export const groups=new Map();export function deleteGroup(_0x2b6c11){const _0x4ae0cf=_0x5682;groups[_0x4ae0cf(0x12c)](_0x2b6c11),groupMembers[_0x4ae0cf(0x12c)](_0x2b6c11);}export const groupMembers=new Map();export const friends=new Map();export const friendRequests={};export const groupNotifies={};export const napCatError={'ffmpegError':'','httpServerError':'','wsServerError':'','otherError':_0x6bd0b7(0x12a)};export async function getFriend(_0x226557){const _0x2a007c=_0x6bd0b7,_0x5d6cfd={'RKkdf':function(_0x5e1a81,_0x2cbb63){return _0x5e1a81(_0x2cbb63);}};_0x226557=_0x226557[_0x2a007c(0x131)]();if(_0x5d6cfd[_0x2a007c(0x12f)](isNumeric,_0x226557)){const _0x8209c4=Array[_0x2a007c(0x132)](friends['values']());return _0x8209c4[_0x2a007c(0x127)](_0x4286a8=>_0x4286a8['uin']===_0x226557);}else return friends['get'](_0x226557);}export async function getGroup(_0x573159){const _0x50a5c9=_0x6bd0b7;let _0x3cd395=groups['get'](_0x573159[_0x50a5c9(0x131)]());if(!_0x3cd395)try{const _0x30f9cc=await NTQQGroupApi[_0x50a5c9(0x134)]();_0x30f9cc[_0x50a5c9(0x11f)]&&_0x30f9cc[_0x50a5c9(0x128)](_0x52d51d=>{const _0xa1b696=_0x50a5c9;groups[_0xa1b696(0x124)](_0x52d51d[_0xa1b696(0x125)],_0x52d51d);});}catch(_0x3451de){return undefined;}return _0x3cd395=groups['get'](_0x573159[_0x50a5c9(0x131)]()),_0x3cd395;}export async function getGroupMember(_0x3df171,_0x3303e3){const _0xd2f57d=_0x6bd0b7,_0x4a6968={'uSFWK':function(_0x4d37ba){return _0x4d37ba();}};_0x3df171=_0x3df171[_0xd2f57d(0x131)](),_0x3303e3=_0x3303e3[_0xd2f57d(0x131)]();let _0x47d2f7=groupMembers[_0xd2f57d(0x123)](_0x3df171);if(!_0x47d2f7)try{_0x47d2f7=await NTQQGroupApi[_0xd2f57d(0x129)](_0x3df171),groupMembers[_0xd2f57d(0x124)](_0x3df171,_0x47d2f7);}catch(_0x4e239d){return null;}const _0x361e76=()=>{const _0x2e9f0e=_0xd2f57d;let _0x1b2a61=undefined;return isNumeric(_0x3303e3)?_0x1b2a61=Array[_0x2e9f0e(0x132)](_0x47d2f7[_0x2e9f0e(0x137)]())['find'](_0x3c0116=>_0x3c0116['uin']===_0x3303e3):_0x1b2a61=_0x47d2f7[_0x2e9f0e(0x123)](_0x3303e3),_0x1b2a61;};let _0xf14aca=_0x4a6968[_0xd2f57d(0x133)](_0x361e76);return!_0xf14aca&&(_0x47d2f7=await NTQQGroupApi[_0xd2f57d(0x129)](_0x3df171),_0xf14aca=_0x361e76()),_0xf14aca;}function _0x5682(_0x149775,_0x117f74){const _0x2fa19a=_0x2fa1();return _0x5682=function(_0x56822d,_0x5c0103){_0x56822d=_0x56822d-0x11f;let _0x3f8559=_0x2fa19a[_0x56822d];return _0x3f8559;},_0x5682(_0x149775,_0x117f74);}export const uid2UinMap={};export function getUidByUin(_0x27aba6){const _0x5efe80={'DrudH':function(_0x47f6fb,_0x3bc2c8){return _0x47f6fb===_0x3bc2c8;}};for(const _0x2ab022 in uid2UinMap){if(_0x5efe80['DrudH'](uid2UinMap[_0x2ab022],_0x27aba6))return _0x2ab022;}}export const tempGroupCodeMap={};export const rawFriends=[];export const stat={'packet_received':0x0,'packet_sent':0x0,'message_received':0x0,'message_sent':0x0,'last_message_time':0x0,'disconnect_times':0x0,'lost_times':0x0,'packet_lost':0x0};

View File

@@ -0,0 +1 @@
function _0x1806(){var _0x891ba1=['287998IXXBUH','12969324CpTTHa','415490wvVPTv','split','DOCUMENT','AiULT','IMAGE','2|3|4|1|0','170iDhUDe','104061qIxpag','IdBVd','VIDEO','90tfTGFz','EUtFx','3031owKtcx','OTHER','kwYUI','yQBqy','11XUMvHq','ksAzo','74064SfKygL','10912RSMZir','24CjBDtx','248802Fusayi'];_0x1806=function(){return _0x891ba1;};return _0x1806();}(function(_0x55b185,_0x927958){var _0x283eef=_0x5493,_0x2aa330=_0x55b185();while(!![]){try{var _0x336a10=-parseInt(_0x283eef(0x1ae))/0x1+parseInt(_0x283eef(0x1ad))/0x2+parseInt(_0x283eef(0x1b7))/0x3*(-parseInt(_0x283eef(0x1ac))/0x4)+parseInt(_0x283eef(0x1b6))/0x5*(-parseInt(_0x283eef(0x1aa))/0x6)+parseInt(_0x283eef(0x1bc))/0x7*(parseInt(_0x283eef(0x1ab))/0x8)+-parseInt(_0x283eef(0x1ba))/0x9*(parseInt(_0x283eef(0x1b0))/0xa)+-parseInt(_0x283eef(0x1a8))/0xb*(-parseInt(_0x283eef(0x1af))/0xc);if(_0x336a10===_0x927958)break;else _0x2aa330['push'](_0x2aa330['shift']());}catch(_0x1bdafd){_0x2aa330['push'](_0x2aa330['shift']());}}}(_0x1806,0x71664));;export var CacheFileType;function _0x5493(_0x55a407,_0xd64393){var _0x18060f=_0x1806();return _0x5493=function(_0x549329,_0x176c2d){_0x549329=_0x549329-0x1a5;var _0x205a59=_0x18060f[_0x549329];return _0x205a59;},_0x5493(_0x55a407,_0xd64393);}(function(_0x3e9347){var _0x56628e=_0x5493,_0x42e30f={'EUtFx':_0x56628e(0x1b5),'kwYUI':_0x56628e(0x1a5),'ksAzo':_0x56628e(0x1b2),'yQBqy':_0x56628e(0x1b4),'IdBVd':_0x56628e(0x1b9),'AiULT':'AUDIO'},_0x52b4c0=_0x42e30f[_0x56628e(0x1bb)][_0x56628e(0x1b1)]('|'),_0x111826=0x0;while(!![]){switch(_0x52b4c0[_0x111826++]){case'0':_0x3e9347[_0x3e9347[_0x56628e(0x1a5)]=0x4]=_0x42e30f[_0x56628e(0x1a6)];continue;case'1':_0x3e9347[_0x3e9347[_0x42e30f['ksAzo']]=0x3]=_0x42e30f[_0x56628e(0x1a9)];continue;case'2':_0x3e9347[_0x3e9347[_0x42e30f[_0x56628e(0x1a7)]]=0x0]=_0x42e30f[_0x56628e(0x1a7)];continue;case'3':_0x3e9347[_0x3e9347[_0x42e30f[_0x56628e(0x1b8)]]=0x1]=_0x42e30f[_0x56628e(0x1b8)];continue;case'4':_0x3e9347[_0x3e9347[_0x42e30f[_0x56628e(0x1b3)]]=0x2]=_0x42e30f['AiULT'];continue;}break;}}(CacheFileType||(CacheFileType={})));

View File

@@ -1,12 +1,18 @@
import { AtType, SendArkElement, SendFaceElement, SendFileElement, SendPicElement, SendPttElement, SendReplyElement, SendTextElement, SendVideoElement } from '../entities'; import { AtType, SendArkElement, SendFaceElement, SendFileElement, SendMarkdownElement, SendMarketFaceElement, SendPicElement, SendPttElement, SendReplyElement, SendTextElement, SendVideoElement } from './index';
export declare const mFaceCache: Map<string, string>;
export declare class SendMsgElementConstructor { export declare class SendMsgElementConstructor {
static text(content: string): SendTextElement; static text(content: string): SendTextElement;
static at(atUid: string, atNtUid: string, atType: AtType, atName: string): SendTextElement; static at(atUid: string, atNtUid: string, atType: AtType, atName: string): SendTextElement;
static reply(msgSeq: string, msgId: string, senderUin: string, senderUinStr: string): SendReplyElement; static reply(msgSeq: string, msgId: string, senderUin: string, senderUinStr: string): SendReplyElement;
static pic(picPath: string, summary?: string, subType?: 0 | 1): Promise<SendPicElement>; static pic(picPath: string, summary?: string, subType?: 0 | 1): Promise<SendPicElement>;
static file(filePath: string, fileName?: string): Promise<SendFileElement>; static file(filePath: string, fileName?: string, folderId?: string): Promise<SendFileElement>;
static video(filePath: string, fileName?: string, diyThumbPath?: string): Promise<SendVideoElement>; static video(filePath: string, fileName?: string, diyThumbPath?: string): Promise<SendVideoElement>;
static ptt(pttPath: string): Promise<SendPttElement>; static ptt(pttPath: string): Promise<SendPttElement>;
static face(faceId: number): SendFaceElement; static face(faceId: number): SendFaceElement;
static mface(emojiPackageId: number, emojiId: string, key: string, faceName: string): SendMarketFaceElement;
static dice(resultId: number | null): SendFaceElement;
static rps(resultId: number | null): SendFaceElement;
static ark(data: any): SendArkElement; static ark(data: any): SendArkElement;
static markdown(content: string): SendMarkdownElement;
static miniapp(): Promise<SendArkElement>;
} }

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@ export interface Group {
groupStatus: 0; groupStatus: 0;
memberRole: 2; memberRole: 2;
isTop: boolean; isTop: boolean;
toppedTimestamp: '0'; toppedTimestamp: string;
privilegeFlag: number; privilegeFlag: number;
isConf: boolean; isConf: boolean;
hasModifyConfGroupFace: boolean; hasModifyConfGroupFace: boolean;
@@ -24,8 +24,8 @@ export interface Group {
groupCreditLevel: number; groupCreditLevel: number;
groupFlagExt3: number; groupFlagExt3: number;
groupOwnerId: { groupOwnerId: {
'memberUin': string; memberUin: string;
'memberUid': string; memberUid: string;
}; };
} }
export declare enum GroupMemberRole { export declare enum GroupMemberRole {

View File

@@ -0,0 +1 @@
(function(_0x5cea7d,_0x3780ef){var _0x3f3cae=_0x3e14,_0x240696=_0x5cea7d();while(!![]){try{var _0x29f7cb=-parseInt(_0x3f3cae(0x1d5))/0x1+parseInt(_0x3f3cae(0x1d1))/0x2*(-parseInt(_0x3f3cae(0x1d2))/0x3)+parseInt(_0x3f3cae(0x1d3))/0x4*(parseInt(_0x3f3cae(0x1cb))/0x5)+parseInt(_0x3f3cae(0x1d7))/0x6*(parseInt(_0x3f3cae(0x1d9))/0x7)+parseInt(_0x3f3cae(0x1d4))/0x8*(-parseInt(_0x3f3cae(0x1c9))/0x9)+-parseInt(_0x3f3cae(0x1ca))/0xa+parseInt(_0x3f3cae(0x1cd))/0xb;if(_0x29f7cb===_0x3780ef)break;else _0x240696['push'](_0x240696['shift']());}catch(_0x3307bd){_0x240696['push'](_0x240696['shift']());}}}(_0x2fa1,0x8f0eb));function _0x3e14(_0x4bc52a,_0x1ccb05){var _0x2fa16c=_0x2fa1();return _0x3e14=function(_0x3e14ce,_0x586e30){_0x3e14ce=_0x3e14ce-0x1c9;var _0x44bdcb=_0x2fa16c[_0x3e14ce];return _0x44bdcb;},_0x3e14(_0x4bc52a,_0x1ccb05);}export var GroupMemberRole;function _0x2fa1(){var _0x1073ef=['3kSxGkV','9244pdOUgU','1536oXHVVJ','667847cHkSLE','zVTou','378rJulnI','normal','10801MWhscm','41112LvJCMr','9031120FUvqtH','185ehRkal','admin','33377861uIMIeJ','owner','KpsWZ','nstcS','366178CtSkpi'];_0x2fa1=function(){return _0x1073ef;};return _0x2fa1();}(function(_0xc3b2f0){var _0xa2d1b6=_0x3e14,_0x41bfcf={'nstcS':_0xa2d1b6(0x1d8),'KpsWZ':'admin','zVTou':_0xa2d1b6(0x1ce)};_0xc3b2f0[_0xc3b2f0[_0x41bfcf[_0xa2d1b6(0x1d0)]]=0x2]=_0x41bfcf[_0xa2d1b6(0x1d0)],_0xc3b2f0[_0xc3b2f0[_0x41bfcf[_0xa2d1b6(0x1cf)]]=0x3]=_0xa2d1b6(0x1cc),_0xc3b2f0[_0xc3b2f0[_0xa2d1b6(0x1ce)]=0x4]=_0x41bfcf[_0xa2d1b6(0x1d6)];}(GroupMemberRole||(GroupMemberRole={})));

View File

@@ -0,0 +1 @@
(function(_0x2f3d80,_0x5e2c40){var _0x1e9cc0=_0x49ac,_0x256817=_0x2f3d80();while(!![]){try{var _0x20c16a=-parseInt(_0x1e9cc0(0x137))/0x1*(-parseInt(_0x1e9cc0(0x134))/0x2)+-parseInt(_0x1e9cc0(0x130))/0x3*(-parseInt(_0x1e9cc0(0x132))/0x4)+parseInt(_0x1e9cc0(0x131))/0x5*(-parseInt(_0x1e9cc0(0x139))/0x6)+parseInt(_0x1e9cc0(0x133))/0x7+parseInt(_0x1e9cc0(0x138))/0x8+parseInt(_0x1e9cc0(0x12f))/0x9+parseInt(_0x1e9cc0(0x136))/0xa*(-parseInt(_0x1e9cc0(0x135))/0xb);if(_0x20c16a===_0x5e2c40)break;else _0x256817['push'](_0x256817['shift']());}catch(_0x48d495){_0x256817['push'](_0x256817['shift']());}}}(_0x11f3,0x8930c));export*from'./user';export*from'./group';function _0x11f3(){var _0x3c7b3a=['4939730aJzutA','181520vBdkvb','8548984oPtrRp','42YCKroo','7846002HqqhMb','3GMVmSV','46615SAJfgJ','956924jibyfN','1339422NvAFsC','8NgNzOW','55JYhmYJ'];_0x11f3=function(){return _0x3c7b3a;};return _0x11f3();}export*from'./msg';export*from'./notify';function _0x49ac(_0x45c297,_0x3aa09b){var _0x11f380=_0x11f3();return _0x49ac=function(_0x49aca0,_0xb40376){_0x49aca0=_0x49aca0-0x12f;var _0x543c4e=_0x11f380[_0x49aca0];return _0x543c4e;},_0x49ac(_0x45c297,_0x3aa09b);}export*from'./cache';export*from'./constructor';

Some files were not shown because too many files have changed in this diff Show More