Compare commits

..

368 Commits

Author SHA1 Message Date
手瓜一十雪
717b246cb6 release: 1.8.5 2024-08-09 21:38:36 +08:00
手瓜一十雪
827df80ec8 fix: error 2024-08-09 20:34:31 +08:00
手瓜一十雪
7117fae2b2 chore: wait for v2 2024-08-09 19:41:40 +08:00
手瓜一十雪
15e9462140 LICENSE: MPL2 To BSD 2024-08-09 19:40:35 +08:00
手瓜一十雪
9203fa3df2 Merge pull request #230 from canxin121/main
Fix typo in eventType field name
2024-08-09 13:35:45 +08:00
canxin121
c771d75a00 Fix typo in eventType field name 2024-08-09 13:12:11 +08:00
手瓜一十雪
7b10d75aeb chore: 1.8.4 2024-08-09 10:48:13 +08:00
Wesley F. Young
b46459de5f docs: 给 v2 引流 2024-08-08 23:15:28 +08:00
Wesley F. Young
ac7f025223 docs: 进化的语言中枢 2024-08-08 23:13:21 +08:00
手瓜一十雪
05b77b5042 build: test 2024-08-08 11:11:38 +08:00
手瓜一十雪
d6cfe11d97 build: test 2024-08-08 10:59:49 +08:00
手瓜一十雪
dd4d59e4e7 build: test 2024-08-08 10:50:36 +08:00
手瓜一十雪
7cb8626e16 build:test 2024-08-08 10:29:53 +08:00
手瓜一十雪
89b5202adb Merge pull request #224 from NapNeko/newold
build: test
2024-08-08 10:28:19 +08:00
手瓜一十雪
40ae0c1449 build: test 2024-08-08 10:26:49 +08:00
手瓜一十雪
81a8115c56 release:1.8.3 2024-08-07 01:32:48 +08:00
手瓜一十雪
0ddd26bd51 release: 1.8.3 2024-08-07 01:28:22 +08:00
手瓜一十雪
69e2133a27 chore: BootWay05Script 2024-08-07 01:25:02 +08:00
手瓜一十雪
b04f85949b docs: todo 2024-08-06 23:42:21 +08:00
手瓜一十雪
667dba01ae build: OB11InputStatusEvent 2024-08-06 23:39:22 +08:00
手瓜一十雪
85a8cef628 chore: 移除部分无用内容 2024-08-06 21:14:11 +08:00
手瓜一十雪
3099acfd00 DOCS:TODO 2024-08-06 20:46:17 +08:00
手瓜一十雪
b00fe0b5f8 docs: 标记TODO和兜底接口 2024-08-06 20:38:49 +08:00
手瓜一十雪
9a64b8bdb6 release:1.8.2 2024-08-06 20:10:01 +08:00
手瓜一十雪
c01e493bd2 feat: 多层合并完成 2024-08-06 18:55:36 +08:00
手瓜一十雪
890236af23 chore: 去除风控延迟 2024-08-06 18:01:36 +08:00
手瓜一十雪
ea678d805d chore: 多层合并转发初步可用 2024-08-06 17:58:48 +08:00
手瓜一十雪
29699418ff fix: 对漏掉的部分加入 2024-08-06 17:02:26 +08:00
手瓜一十雪
87bb36c39f refactor: SendMessageContext 2024-08-06 17:00:27 +08:00
手瓜一十雪
7cb85ed73c fix: 再次优化nodeid 2024-08-06 16:43:06 +08:00
手瓜一十雪
c647771a6d fix: 合并转发Node节点异常问题 2024-08-06 16:27:06 +08:00
手瓜一十雪
6c3d737219 fix: 合并reply 2024-08-06 16:00:25 +08:00
手瓜一十雪
a1f38fed7a release: v1.8.1 2024-08-06 15:55:59 +08:00
手瓜一十雪
c36bb77286 feat: 合并消息初步解析完成 2024-08-06 14:48:20 +08:00
手瓜一十雪
1a1acdc3c9 feat: 转发着色 2024-08-06 11:40:36 +08:00
手瓜一十雪
ef8e60c405 build: 180test 2024-08-06 11:31:48 +08:00
手瓜一十雪
31c1cc47bf build: 180 2024-08-06 11:30:35 +08:00
手瓜一十雪
351fed7359 fix #102 2024-08-06 11:30:12 +08:00
手瓜一十雪
f49e7cbe57 chore: log 2024-08-06 11:15:44 +08:00
手瓜一十雪
7da8ea5e99 style:lint 2024-08-06 11:12:25 +08:00
手瓜一十雪
8fa6a12a7c build: 181test 2024-08-06 11:07:37 +08:00
手瓜一十雪
1070278eaf release: 1.8.0 2024-08-06 09:13:03 +08:00
手瓜一十雪
16b1a6b153 release: 1.7.9 2024-08-05 21:04:49 +08:00
手瓜一十雪
096a7534e0 build: 1.7.9-test 2024-08-05 20:36:08 +08:00
手瓜一十雪
b0897187d2 feat: fetch_emoji_like 2024-08-05 20:33:24 +08:00
手瓜一十雪
885d94882d remove: 😢意外加入的文件 2024-08-05 18:40:39 +08:00
手瓜一十雪
11a3341e13 feat: GetRecentContact 私有标准 2024-08-05 18:39:02 +08:00
手瓜一十雪
231890f78a refactor: msgRandom控制 2024-08-05 17:42:07 +08:00
手瓜一十雪
a272feda6a release: 1.7.8 2024-08-05 13:52:34 +08:00
手瓜一十雪
bc936a0ca7 build: 178发言时间与加入时间完全兜底 2024-08-05 13:45:07 +08:00
手瓜一十雪
28030c2d13 chore: test 2024-08-05 13:01:26 +08:00
手瓜一十雪
7fe9176286 feat: richmsg failed 2024-08-05 12:45:06 +08:00
手瓜一十雪
1105f9b8d6 docs: 补充 2024-08-05 01:11:11 +08:00
手瓜一十雪
e4653defa8 LICENSE: break 2024-08-05 00:48:41 +08:00
Alen
1c62a1e839 Merge pull request #208 from cnxysoft/main
BUG修复
2024-08-05 00:20:17 +08:00
Alen
3a3bbfe201 BUG修复
修复(群聊/私聊)转发合并消息错误的问题
2024-08-05 00:18:42 +08:00
手瓜一十雪
1c38833998 fix: 177 2024-08-04 23:26:51 +08:00
手瓜一十雪
38894177ee fix: get_stranger_info 2024-08-04 22:21:24 +08:00
手瓜一十雪
dce8416942 fix: 177 2024-08-04 21:40:44 +08:00
手瓜一十雪
14219e9b42 release: v1.7.7 2024-08-04 21:23:55 +08:00
手瓜一十雪
7b459e7502 refactor: get_group_member_list 2024-08-04 21:21:36 +08:00
手瓜一十雪
31824c0504 refactor: get_group_list 2024-08-04 20:56:49 +08:00
手瓜一十雪
e203abae85 refactor: /get_group_member_info 2024-08-04 20:53:23 +08:00
手瓜一十雪
faf83b680b 《NTQQ参数全解》 2024-08-04 20:19:34 +08:00
手瓜一十雪
67dcbcb842 refactor: 开始重构群成员信息获取 2024-08-04 20:10:21 +08:00
手瓜一十雪
6533a25404 chore: 移除调试代码 2024-08-04 19:12:18 +08:00
手瓜一十雪
4dc760b0e9 feat: shareDigest 2024-08-04 19:11:44 +08:00
手瓜一十雪
25933b9043 chore: 移除旧代码 2024-08-04 18:50:40 +08:00
手瓜一十雪
a53aaa456e fix: 一处很久很久的看错的的问题 2024-08-04 18:49:40 +08:00
手瓜一十雪
e8a7ea07a5 refactor: Id转换 2024-08-04 18:45:00 +08:00
手瓜一十雪
8817dc6b10 refactor: Uid/Uin转换V2版本 2024-08-04 18:01:31 +08:00
手瓜一十雪
491ec04b46 fix: 准备第二次重构uid/uin 2024-08-04 16:50:23 +08:00
手瓜一十雪
8a5d4a683b feat: getBuddyV2ExWithCate 2024-08-04 16:45:14 +08:00
手瓜一十雪
dfc7c7357a Refactor Api: GetFriendsWithCategory 2024-08-04 16:37:15 +08:00
手瓜一十雪
690a2f7d34 refctor: getBuddyV2 支持分类 2024-08-04 16:27:25 +08:00
手瓜一十雪
58f22b24e4 refactor: api getbuddyv2 2024-08-04 16:05:07 +08:00
手瓜一十雪
3cce9f528b build: 1.7.7 2024-08-04 15:16:45 +08:00
手瓜一十雪
20fd5ac8cb chore: Todo 2024-08-04 15:12:55 +08:00
手瓜一十雪
9e05e086eb fix: 初始化问题 2024-08-04 15:01:43 +08:00
手瓜一十雪
056e0adddf build: 1.7.7-refactor 2024-08-04 14:39:45 +08:00
手瓜一十雪
b36388200d Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-08-04 14:35:47 +08:00
手瓜一十雪
9793e5741a refactor: Appid的获取 2024-08-04 14:35:26 +08:00
手瓜一十雪
143380c012 Merge pull request #206 from pohgxz/main
修复webui快捷登录失败
2024-08-04 14:15:53 +08:00
手瓜一十雪
4b92254945 chore: 订正类型 2024-08-04 14:15:40 +08:00
手瓜一十雪
f9c1d8b4a6 build: 1.7.7 refactor 2024-08-04 14:06:30 +08:00
手瓜一十雪
c0c469339b refactor: versionGet 2024-08-04 14:03:28 +08:00
Nepenthe
0ca6343ed7 修复webui快捷登录失败 2024-08-04 13:04:31 +08:00
手瓜一十雪
3db74c3427 refactor: BuddyList 2024-08-04 12:26:55 +08:00
手瓜一十雪
48d5cb53bd release: 1.7.6 2024-08-03 22:45:36 +08:00
手瓜一十雪
fd7d2dbf53 release: 1.7.5 2024-08-03 20:48:13 +08:00
手瓜一十雪
6609697752 release: 1.7.5 2024-08-03 20:47:05 +08:00
手瓜一十雪
dcd6e1973e build:1.7.5For9.9.15 2024-08-03 16:23:55 +08:00
手瓜一十雪
3614a6e932 chore: 9.9.15 support 2024-08-03 16:08:23 +08:00
手瓜一十雪
931a0210e5 chore: 兼容9.915 信息获取 2024-08-03 15:36:56 +08:00
手瓜一十雪
f9e7de4b42 build: 1.7.5For9.9.15 2024-08-03 15:07:51 +08:00
手瓜一十雪
8e0b79594e style: lint 2024-08-03 15:06:02 +08:00
手瓜一十雪
17122c4360 feat: 精简历史获取 2024-08-03 15:03:41 +08:00
手瓜一十雪
154f7b6a30 chore: 清除老旧代码 2024-08-03 14:57:24 +08:00
手瓜一十雪
52e5543d0b chore: queryEmoticonMsgs 2024-08-03 14:44:48 +08:00
手瓜一十雪
3c304bd2ae feat: 补全类型 开始对9.9.15针对优化 2024-08-03 14:25:26 +08:00
手瓜一十雪
26609bb8fd chore: 9.9.15兼容sendmsg 2024-08-03 13:11:25 +08:00
手瓜一十雪
de3fa9aaa4 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-08-03 12:28:41 +08:00
手瓜一十雪
788665f84c chore: support win 9.9.15 2024-08-03 12:28:25 +08:00
手瓜一十雪
3943782971 Merge pull request #201 from idranme/main
feat: at segment add name
2024-08-03 07:08:25 +08:00
idranme
8f899c40f2 chore 2024-08-02 15:49:01 +00:00
idranme
a1f582399e feat: at segment add name 2024-08-02 15:45:37 +00:00
手瓜一十雪
440b63f662 release: v1.7.4 2024-08-01 23:35:35 +08:00
手瓜一十雪
7d2cc3b56b fix: 多次上报自身消息 2024-08-01 22:00:40 +08:00
手瓜一十雪
5fe3422469 #176 revert 2024-08-01 21:48:17 +08:00
手瓜一十雪
6c02cedb1e build: 1.7.4 2024-08-01 19:44:28 +08:00
手瓜一十雪
3cc2f1dcad fix #183 2024-08-01 19:43:29 +08:00
手瓜一十雪
773cdc5877 build: test 2024-08-01 17:14:15 +08:00
手瓜一十雪
361a7329d7 Revert "build(deps-dev): bump @typescript-eslint/eslint-plugin"
This reverts commit 2562a38fa1.
2024-08-01 17:13:54 +08:00
手瓜一十雪
29910f1236 build: test api 2024-08-01 17:12:56 +08:00
手瓜一十雪
4a164016f5 chore: test 2024-08-01 17:08:22 +08:00
手瓜一十雪
cebd3e62a4 Merge pull request #192 from NapNeko/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-8.0.0
build(deps-dev): bump @typescript-eslint/eslint-plugin from 7.18.0 to 8.0.0
2024-08-01 16:26:50 +08:00
dependabot[bot]
2562a38fa1 build(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.18.0 to 8.0.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.0.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-01 08:22:34 +00:00
手瓜一十雪
d46c922bbf Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-08-01 13:11:19 +08:00
手瓜一十雪
66b59982f7 补充类型 移除无用代码 2024-08-01 13:11:09 +08:00
手瓜一十雪
ad397ccf7f Merge pull request #188 from Fripine/feat/FriendAddNoticeEvent
feat: support FriendAddNoticeEvent
2024-08-01 08:46:50 +08:00
Fripine
bdef80ede7 feat: support FriendAddNoticeEvent 2024-08-01 01:03:33 +08:00
手瓜一十雪
385dcbc75a fix #186 2024-07-31 22:23:12 +08:00
手瓜一十雪
74cf501c8f release: 1.7.3 2024-07-31 22:21:23 +08:00
手瓜一十雪
0c200d6748 build: 1.7.2 beta0 2024-07-31 22:20:39 +08:00
手瓜一十雪
e65a36c517 chore: Ver2SendMsg 2024-07-31 22:19:35 +08:00
手瓜一十雪
126b54ad40 fix #186 2024-07-31 21:46:12 +08:00
手瓜一十雪
78637751af fix #187 2024-07-31 21:41:31 +08:00
手瓜一十雪
f96526ee3a fix #184 2024-07-31 21:36:13 +08:00
手瓜一十雪
b3c7a91f3d refactor: getfile 2024-07-31 16:40:34 +08:00
手瓜一十雪
b8daeef0c4 fix #173 2024-07-31 16:02:08 +08:00
手瓜一十雪
2b662944cf typo fix #178 2024-07-31 15:58:27 +08:00
手瓜一十雪
3d516df01e try fix #183 2024-07-31 15:52:28 +08:00
手瓜一十雪
26b4a9b15b chore: 兼容wt 2024-07-31 14:21:05 +08:00
手瓜一十雪
0f8af273ae release: 1.7.2 2024-07-31 10:51:12 +08:00
手瓜一十雪
fa29a31da9 release: 1.7.2 2024-07-31 10:46:23 +08:00
手瓜一十雪
9e0d2606d8 build: 1.7.2 no log 2024-07-31 10:35:53 +08:00
手瓜一十雪
338dedd6e0 build: 1.7.1 双消息队列 2024-07-31 10:33:38 +08:00
手瓜一十雪
1f893b1393 build: 1.7.2 消息队列重构 2024-07-31 10:25:46 +08:00
手瓜一十雪
b783d6f928 refatcor: sendmsg 2024-07-31 01:12:46 +08:00
手瓜一十雪
8ca0d40f05 fix: error 2024-07-30 23:34:29 +08:00
手瓜一十雪
2f40a80434 fix: error 2024-07-30 23:33:32 +08:00
手瓜一十雪
812d8eb5bb feat: 对msgId兜底 2024-07-30 23:31:42 +08:00
手瓜一十雪
bf5f548349 fix: msghash性能问题 2024-07-30 23:06:58 +08:00
手瓜一十雪
ebf90e72b9 Merge pull request #180 from cnxysoft/main
BW5启动脚本修改
2024-07-30 22:30:04 +08:00
Alen
31d7d42edf BW5启动脚本修复
修改脚本为 UTF-8 with BOM 格式,解决添加注释后执行报错的问题
2024-07-30 19:56:17 +08:00
Alen
833875b42f Merge remote-tracking branch 'upstream/main' 2024-07-30 17:56:48 +08:00
Alen
b901c10f3c 修改BW5启动脚本
支持脚本自动提权
自动覆盖dbghelp.dll
修改默认启用UTF8
修改不再从新窗口运行NC
2024-07-30 17:56:28 +08:00
手瓜一十雪
8ab678bd97 chore: remove log 2024-07-30 16:45:03 +08:00
手瓜一十雪
55d5072f46 fix: setMsg 2024-07-30 16:34:33 +08:00
手瓜一十雪
a379ffd0f2 Merge pull request #175 from pohgxz/main
修复Way05无法带参
2024-07-30 09:12:15 +08:00
Nepenthe
4501d73134 修复Way05无法带参 2024-07-29 23:32:34 +08:00
手瓜一十雪
5f15774ec7 fix: script 2024-07-29 20:58:27 +08:00
手瓜一十雪
c9e057599e fix: error 2024-07-29 20:49:35 +08:00
手瓜一十雪
66851f5625 fix 2024-07-29 20:39:01 +08:00
手瓜一十雪
b33c235b4d release: 1.7.1 2024-07-29 20:13:09 +08:00
手瓜一十雪
d6693b6114 Merge pull request #171 from NapNeko/dependabot/npm_and_yarn/types/node-22.0.0
build(deps-dev): bump @types/node from 20.14.13 to 22.0.0
2024-07-29 17:23:02 +08:00
dependabot[bot]
36b4d26c78 build(deps-dev): bump @types/node from 20.14.13 to 22.0.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.14.13 to 22.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-29 08:23:55 +00:00
手瓜一十雪
617592d90a fix: 多次post 2024-07-29 11:32:55 +08:00
手瓜一十雪
15a77b8070 fix: bug 2024-07-29 10:24:02 +08:00
手瓜一十雪
606eccd22b refactor: 精简逻辑 2024-07-29 10:12:41 +08:00
手瓜一十雪
5613450313 refactor: 回复 2024-07-29 10:07:59 +08:00
手瓜一十雪
c59b5564af release: 1.7.0 2024-07-29 09:24:17 +08:00
手瓜一十雪
330b086b8b fix #98 2024-07-29 09:10:52 +08:00
手瓜一十雪
9837ef4f36 fix #125 2024-07-29 08:59:26 +08:00
手瓜一十雪
add46b3251 chore: 落地标准化 2024-07-29 08:43:37 +08:00
手瓜一十雪
e169199107 feat: #162 2024-07-29 08:29:24 +08:00
手瓜一十雪
92fe654850 fix #157 2024-07-29 08:12:49 +08:00
手瓜一十雪
b257486404 fix #158 2024-07-29 08:02:18 +08:00
手瓜一十雪
bdf2e33f40 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-07-29 07:51:28 +08:00
手瓜一十雪
224d361923 fix #167 2024-07-29 07:51:18 +08:00
手瓜一十雪
3452fa56df build: 😭版本满天飞版本 2024-07-29 00:39:34 +08:00
手瓜一十雪
cd256235da refactor: selfMsgPost 2024-07-29 00:16:24 +08:00
手瓜一十雪
361a164f2a fix: typo 2024-07-28 23:54:50 +08:00
手瓜一十雪
0e60d4b198 fix: 延迟调整 2024-07-28 23:53:45 +08:00
手瓜一十雪
67b47e39b4 fix: typo 2024-07-28 23:49:04 +08:00
手瓜一十雪
8f54310f63 refactor: reply 2024-07-28 23:35:58 +08:00
手瓜一十雪
c7a7494d7e fix: 保证NC回复的消息一致性 2024-07-28 22:33:50 +08:00
手瓜一十雪
af88b3166d build: 169-test 2024-07-28 17:55:34 +08:00
手瓜一十雪
b7837b2a14 chore:test 2024-07-28 17:38:48 +08:00
手瓜一十雪
950ddc749e chore: 🥹LocalMsg不会写入数据库 2024-07-28 16:23:56 +08:00
手瓜一十雪
df081ef0cf chore: 移除调试代码 2024-07-28 15:40:44 +08:00
手瓜一十雪
7b24f90d9f rector: 离线文件重构初步完成 2024-07-28 15:37:34 +08:00
手瓜一十雪
f2e4579fd8 feat: 缓存文件 2024-07-28 15:34:08 +08:00
手瓜一十雪
97cb351827 fix: typo 2024-07-28 14:55:30 +08:00
手瓜一十雪
c1ec53fdbb refactor: fileget 2024-07-28 14:25:13 +08:00
手瓜一十雪
98214aa429 refactor: video element 2024-07-28 13:36:03 +08:00
手瓜一十雪
ce7deac2dd refactor: video element 2024-07-28 13:28:21 +08:00
手瓜一十雪
612092b867 build: 170 re 2024-07-28 13:15:14 +08:00
手瓜一十雪
92579d5949 Merge pull request #163 from cnxysoft/main
修复提交疏漏
2024-07-28 13:00:12 +08:00
手瓜一十雪
9ab07060ae fix: default 2024-07-28 12:59:20 +08:00
手瓜一十雪
0d45125d79 fix: uid && latestMsg 2024-07-28 09:56:00 +08:00
手瓜一十雪
9ced152778 fix: 修复uid转换异常问题 2024-07-28 09:24:03 +08:00
Alen
3685ab2e3e Merge remote-tracking branch 'upstream/main' 2024-07-27 15:01:23 +08:00
Alen
be605f11f2 修复提交疏漏
修改在查询群历史消息时,如未提供msg_seq,则返回最新消息
2024-07-27 15:01:08 +08:00
手瓜一十雪
8cca8df976 Merge pull request #159 from cnxysoft/main
bug修复和标准兼容
2024-07-27 06:46:25 +08:00
Alen
990a31e961 标准兼容
根据GOCQ标准将获取群历史消息中的msg_seq改为非必要参数,默认为0
2024-07-27 04:10:01 +08:00
Alen
5db201c342 BUG修复
修复创建reply消息体时向NTQQMsgApi.getMsgsByMsgId提交空值查询会导致QQ崩溃的BUG
2024-07-27 04:01:22 +08:00
手瓜一十雪
a625e30dd4 fix: search file 2024-07-26 17:37:04 +08:00
手瓜一十雪
b236cdd060 refactor: search file 2024-07-26 17:15:28 +08:00
手瓜一十雪
2db9899184 chore: type 2024-07-26 16:26:47 +08:00
手瓜一十雪
fe5d6db986 chore: wait release 1.7.0 2024-07-26 16:10:05 +08:00
手瓜一十雪
7c7bf8fecf chore: 类型+++++ 2024-07-26 16:08:28 +08:00
手瓜一十雪
76e3a46378 fix: type 2024-07-26 16:02:23 +08:00
手瓜一十雪
16f3897fec chore: 类型补全计划 2024-07-26 15:55:05 +08:00
手瓜一十雪
045e120854 refactor: type 2024-07-26 15:38:43 +08:00
Version
2b7fcce9b2 chore:version change 2024-07-26 05:25:49 +00:00
手瓜一十雪
9685931694 fix: uint 2024-07-26 13:25:19 +08:00
手瓜一十雪
1dc844435a Merge pull request #153 from Guation/main
feat: WebUI支持放置到二级目录中
2024-07-26 13:04:26 +08:00
手瓜一十雪
18892379de fix: search file 2024-07-26 12:27:02 +08:00
手瓜一十雪
620d61c8dc docs: v1.6.8 2024-07-26 11:59:18 +08:00
手瓜一十雪
9f91398875 build: 再次优化发送速度 2024-07-26 11:30:04 +08:00
挂神
a29b1154a9 feat: WebUI支持放置到二级目录中 2024-07-26 11:12:09 +08:00
手瓜一十雪
34d19a471a refactor: 回滚 2024-07-26 10:58:56 +08:00
手瓜一十雪
2ef6477d7c build: log info 2024-07-25 20:22:03 +08:00
手瓜一十雪
26e6800836 fix: 退群推送 2024-07-25 18:08:49 +08:00
手瓜一十雪
9dbbcf3872 build: 1.6.8 - parse appid 2024-07-25 17:57:39 +08:00
手瓜一十雪
6b3343e1e4 build: 1.6.8 beta6 2024-07-25 10:59:06 +08:00
手瓜一十雪
ef48f754a5 docs: 整理当前进度 2024-07-25 10:44:53 +08:00
手瓜一十雪
3be1ede847 refactor: sendtime/join time 2024-07-25 10:32:44 +08:00
手瓜一十雪
7bff1b61e8 refactor: SendTime 2024-07-25 10:02:16 +08:00
手瓜一十雪
6affd0eb68 feat: GetSendTime 2024-07-24 17:49:03 +08:00
手瓜一十雪
0a112d15e0 fix: typo 2024-07-24 15:37:23 +08:00
手瓜一十雪
4e03f582bb fix: richmeida name 2024-07-24 14:43:10 +08:00
手瓜一十雪
8f186c1c5e chore: action clean 2024-07-24 14:37:48 +08:00
手瓜一十雪
cd1bae9a1f fix: setGroupAvatar 2024-07-24 14:35:12 +08:00
手瓜一十雪
60796c26ca Merge pull request #147 from serfend/default-config
fix[config]support overwrite by user #145
2024-07-24 14:28:42 +08:00
汉广
28927f950d fix[config]support overwrite by user 2024-07-24 14:25:58 +08:00
手瓜一十雪
95f16ebc8c Merge pull request #144 from Guation/main
feat: http与ws允许监听同一端口,快速登录允许自动选择QQ号,允许禁用webUI
2024-07-24 14:09:19 +08:00
挂神
25bca8385d feat: http与ws共站支持热重载 2024-07-24 13:14:35 +08:00
手瓜一十雪
965c7f23b4 feat: 群头像设置 2024-07-24 11:37:12 +08:00
手瓜一十雪
33082af9cc feat: searchFile 2024-07-24 11:23:27 +08:00
手瓜一十雪
1f7f3565b0 build: 1.6.8 beta05 2024-07-24 10:45:11 +08:00
手瓜一十雪
f784363696 refactor: UUID 2024-07-24 10:44:55 +08:00
手瓜一十雪
37bd51e138 refactor: getUserInfo 2024-07-24 10:42:22 +08:00
手瓜一十雪
c367728c43 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-07-24 10:23:48 +08:00
手瓜一十雪
61f0f5d884 refactor: 改造接口调用 2024-07-24 10:23:41 +08:00
手瓜一十雪
5f2ebeead7 docs: update 2024-07-23 18:32:07 +08:00
手瓜一十雪
7646037fc7 docs: 砍掉 2024-07-23 18:21:19 +08:00
手瓜一十雪
eac6d285ff chore: debug 2024-07-23 17:39:00 +08:00
手瓜一十雪
b921d5e734 refactor: downloadMedia 2024-07-23 16:15:23 +08:00
手瓜一十雪
831d808e63 chore: remove 2024-07-23 16:03:06 +08:00
手瓜一十雪
451b88d7e3 refactor: video type 2024-07-23 15:51:57 +08:00
手瓜一十雪
f916682a71 build: 1.6.8 beta07 2024-07-23 15:38:41 +08:00
手瓜一十雪
2d76bcf0cf refactor: message id 2024-07-23 15:10:39 +08:00
手瓜一十雪
8db294efe6 refactor: 转发消息修复 2024-07-23 14:54:05 +08:00
手瓜一十雪
5cc5149aed fix: 合并转发 2024-07-23 14:19:26 +08:00
手瓜一十雪
7ecb01dc9f docs: 规划 2024-07-23 12:34:20 +08:00
手瓜一十雪
8bf1a545d9 chore: remove debug 2024-07-23 10:12:20 +08:00
手瓜一十雪
efb2be2f94 fix: timeout 2024-07-23 09:50:31 +08:00
手瓜一十雪
bd2edda494 refactor: sendMsg 2024-07-23 09:45:00 +08:00
手瓜一十雪
991172eae4 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-07-23 09:21:36 +08:00
手瓜一十雪
fc7631f9aa refactor: sendmsg 2024-07-23 09:21:22 +08:00
手瓜一十雪
a21efb7d2f Merge pull request #145 from serfend/default-config
fix[default-config]config name check #138
2024-07-22 21:36:54 +08:00
汉广
03bc844ad0 fix[default-config]config name check 2024-07-22 20:12:24 +08:00
挂神
f7bdc35ed6 feat: http与ws允许监听同一端口,快速登录允许自动选择QQ号,允许禁用webUI 2024-07-22 19:47:23 +08:00
手瓜一十雪
0efdffd857 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-07-22 18:49:36 +08:00
手瓜一十雪
6a16a42d0c feat: refactor send 2024-07-22 18:49:25 +08:00
手瓜一十雪
e9c00c72b1 Merge pull request #138 from serfend/main
feat[config]support use default-template
2024-07-22 18:22:49 +08:00
手瓜一十雪
ab22f36b8a refactor: NTEvent Checker 2024-07-22 18:21:29 +08:00
手瓜一十雪
c57497cd91 feat: remove debug 2024-07-22 18:17:33 +08:00
手瓜一十雪
ba123236e5 feat:msgid generate 2024-07-22 18:17:03 +08:00
手瓜一十雪
338b6e4607 fix: QRCode 2024-07-22 15:46:48 +08:00
手瓜一十雪
f88c717560 build: 1.6.8-beta03 2024-07-22 15:40:41 +08:00
手瓜一十雪
f8ffc92db5 feat: remove LineDev&&Protobuf 2024-07-22 15:40:23 +08:00
手瓜一十雪
98c23c172c build: 1.6.8-无数据库版本 2024-07-22 15:13:38 +08:00
手瓜一十雪
781c107d8c feat: 拉取重启消息 2024-07-22 15:12:25 +08:00
手瓜一十雪
186668c075 fix: Login 2024-07-22 14:18:04 +08:00
手瓜一十雪
cf9f785193 style: lint 2024-07-22 14:12:03 +08:00
手瓜一十雪
72d2d3f224 feat: 破坏file/db相关接口 2024-07-22 14:09:37 +08:00
手瓜一十雪
087c76b394 refactor: msgId stage-2 2024-07-22 11:34:18 +08:00
手瓜一十雪
4f9fb2c8c3 Merge pull request #141 from cnxysoft/main
修复提交疏漏
2024-07-22 11:15:28 +08:00
手瓜一十雪
334e43e764 refactor: MsgId 2024-07-22 11:15:01 +08:00
Alen
7843256402 修复提交疏漏
修复变量类型未断言的问题
2024-07-22 11:07:33 +08:00
手瓜一十雪
0522ba35fe refactor: jest test 2024-07-22 10:24:55 +08:00
手瓜一十雪
24d3b52e0b refactor: Message Unique 2024-07-22 09:56:08 +08:00
手瓜一十雪
3177110f0f feat: RecentContact 2024-07-22 09:24:16 +08:00
手瓜一十雪
e1b8243a67 Merge pull request #140 from cnxysoft/main
BUG修复
2024-07-22 08:40:21 +08:00
Alen
b1c6ce3885 BUG修复
1.尝试让所有人能收到group_admin事件
2.修复请求API: delete_msg(POST请求网址传参)将负数判定为文本导致无法调用的问题
2024-07-22 01:22:38 +08:00
手瓜一十雪
0b4b25a11e feat: LineDev for Develop-0 2024-07-21 19:31:13 +08:00
手瓜一十雪
1176fe984a add: RecentListener 2024-07-21 19:01:47 +08:00
汉广
6ca768c3ee feat[config]support use default-template 2024-07-20 23:43:32 +08:00
手瓜一十雪
3da1659c8d fix: buddylike 2024-07-20 20:16:45 +08:00
手瓜一十雪
9aa4cd319c release: 1.6.7 2024-07-20 19:52:39 +08:00
手瓜一十雪
5af866cdca fix: error 2024-07-20 19:31:59 +08:00
手瓜一十雪
2b421fa447 release: 1.6.7 2024-07-20 17:43:56 +08:00
手瓜一十雪
30ec964325 feat: new api 2024-07-20 17:33:26 +08:00
手瓜一十雪
714d7d72eb feat: raw api add 2024-07-20 17:09:38 +08:00
手瓜一十雪
687aa0f363 chore: remove debug 2024-07-20 16:37:16 +08:00
手瓜一十雪
8363ab07a7 feat: 支持精华消息 2024-07-20 16:17:02 +08:00
手瓜一十雪
c46a757339 fix: error 2024-07-20 16:14:02 +08:00
手瓜一十雪
557864395b feat: support essence 2024-07-20 16:09:44 +08:00
手瓜一十雪
3f7a85d80b feat: essence get_sender 2024-07-20 16:00:01 +08:00
手瓜一十雪
8d18d2ce1f refactor: 标准化 2024-07-20 15:55:26 +08:00
手瓜一十雪
7141ba1587 refactor: essence and together listener 2024-07-20 15:53:39 +08:00
手瓜一十雪
44d350a225 docs: todo 2024-07-20 15:37:57 +08:00
手瓜一十雪
239b8e72d9 Merge pull request #134 from serfend/main
fix[group]handle_request reason empty
2024-07-20 15:24:39 +08:00
手瓜一十雪
279bdb6fb1 Merge pull request #135 from pohgxz/main
群戳一戳增加原始信息
2024-07-20 15:24:27 +08:00
Nepenthe
a0cea819da 群戳一戳增加原始信息
群消息log增加视频解析
2024-07-20 14:51:50 +08:00
汉广
9ab7f60544 fix[group]handle_request reason empty 2024-07-20 14:16:07 +08:00
手瓜一十雪
aaf7191bf3 build: 1.6.7-beta03 2024-07-20 10:45:26 +08:00
手瓜一十雪
628c9be0c8 feat: 2401 for 群精华设置 2024-07-20 10:44:57 +08:00
手瓜一十雪
733052720c build: 1.6.6-build02 2024-07-20 10:28:47 +08:00
手瓜一十雪
a10f007194 build: 1.6.7-beta0 2024-07-20 10:21:16 +08:00
手瓜一十雪
6fa50c58d3 feat: 优化接口转换速度 避免频繁读写 2024-07-17 15:03:10 +08:00
手瓜一十雪
c54a58d6e4 release: v1.6.6 2024-07-16 15:55:25 +08:00
手瓜一十雪
34cb1ea3fd Merge pull request #126 from cnxysoft/main
修复戳一戳
2024-07-16 15:52:39 +08:00
Alen
f640b0ca91 修复戳一戳 2024-07-16 15:47:23 +08:00
手瓜一十雪
60e16da42e Merge pull request #121 from pohgxz/main
增加winQQ-9912一键启动脚本
2024-07-14 08:44:55 +08:00
Nepenthe
0cdceb95d6 增加winQQ-9912一键启动脚本 2024-07-13 16:09:14 +00:00
手瓜一十雪
70bd22d925 fix: typo 2024-07-13 20:27:18 +08:00
手瓜一十雪
82462dd647 docs: 规划 2024-07-13 20:21:48 +08:00
手瓜一十雪
c0466e943d build: test 2024-07-13 19:37:39 +08:00
手瓜一十雪
b187b4695d refactor: uin<->uid 2024-07-13 19:37:02 +08:00
手瓜一十雪
b1956d2a37 refactor: poke 2024-07-13 19:10:47 +08:00
手瓜一十雪
590b622e5f build: test 2024-07-13 18:58:52 +08:00
手瓜一十雪
3d8174396a feat: LinuxQQ版本25765 2024-07-13 18:58:29 +08:00
手瓜一十雪
b8dc6e9bd9 feat: 再次提升版本 25765 2024-07-13 18:56:42 +08:00
手瓜一十雪
8ee99109dc chore: 整理代码 2024-07-13 18:20:44 +08:00
手瓜一十雪
902041d4ee refactor: 新增启动脚本 2024-07-13 18:15:00 +08:00
手瓜一十雪
cc34aef47e style: code lint 2024-07-13 18:12:38 +08:00
手瓜一十雪
0afbbe7c7a refactor: 废弃部分代码 2024-07-13 18:10:41 +08:00
手瓜一十雪
8004553ba7 refactor: groupNotifies 2024-07-13 18:04:55 +08:00
手瓜一十雪
0023b2846a feat: 第二次大致整理 2024-07-13 17:23:05 +08:00
手瓜一十雪
34775c1816 fix: 整理常量 2024-07-12 18:08:45 +08:00
手瓜一十雪
e0759e704b feat:大部分消息元素 2024-07-12 18:01:48 +08:00
手瓜一十雪
0aa225ca78 fix: typo 2024-07-12 17:04:28 +08:00
手瓜一十雪
b43b4ee5c0 feat: test code 2024-07-12 16:59:08 +08:00
手瓜一十雪
0cdb8cecbf feat: 群精华 代码未测试 2024-07-12 11:02:10 +08:00
手瓜一十雪
fd6a306742 feat: 懒得写了 2024-07-12 10:54:01 +08:00
手瓜一十雪
7f3b3d2277 feat: 群精华 2024-07-12 10:46:57 +08:00
手瓜一十雪
8be5b977bf Merge pull request #117 from po-lan/main
对缓存进一步优化
2024-07-12 09:52:17 +08:00
po-lan
d7ddb15f9c 对缓存进一步优化
LRUCache 将所有被移除的缓存数据作为事件参数传递给事件处理程序。

在数据库操作部分,优化了读写流程,以确保每个群组至多执行三次数据库操作:

读取:先判断缓存中是否存在用户记录,若不存在则读取数据库。
创建:如果用户记录在数据库中不存在,则新增记录。
修改:如果用户记录在数据库中存在,则进行修改。
即使单个群组内有大量用户,每种操作也只会执行一次。
2024-07-12 00:46:03 +08:00
手瓜一十雪
9a6a1798d0 build: poke能用25493 2024-07-11 12:44:42 +08:00
手瓜一十雪
14196fd349 build: 移除调试代码 2024-07-11 12:31:00 +08:00
手瓜一十雪
941b89a523 feat: uin转换优化&poke支持重写 2024-07-11 12:28:11 +08:00
手瓜一十雪
a5f9e5f8c0 Merge pull request #113 from idranme/main
perf: audio
2024-07-11 09:49:56 +08:00
idranme
80c3356c8f perf: audio 2024-07-10 17:44:17 +00:00
手瓜一十雪
914136b750 refactor: 移除异常代码 2024-07-10 21:39:03 +08:00
手瓜一十雪
f9a60795f5 feat: uid转换优化 2024-07-10 21:33:31 +08:00
手瓜一十雪
19640927c7 Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-07-10 21:11:43 +08:00
手瓜一十雪
22faac7e36 fix: friend uid 异常 2024-07-10 21:11:28 +08:00
手瓜一十雪
30d260ab32 Merge pull request #111 from idranme/main
fix: error catch
2024-07-10 11:55:53 +08:00
idranme
115120d066 Update file.ts 2024-07-10 11:35:55 +08:00
idranme
1327844736 fix: error catch 2024-07-10 03:25:25 +00:00
手瓜一十雪
29904f3cb7 feat: 164 way03启动脚本补充 2024-07-06 13:23:31 +08:00
手瓜一十雪
50395594b7 Merge pull request #106 from jetjinser/fix-editorconfig
fix: `.editorconfig` wrong pair `end_of_line`
2024-07-05 22:43:23 +08:00
Jinser Kafka
9360af88b3 fix: .editorconfig 2024-07-05 19:36:32 +08:00
手瓜一十雪
376370336c release: 1.6.5 2024-07-05 16:50:57 +08:00
手瓜一十雪
70df6e3302 Merge pull request #105 from po-lan/main
对缓存小优化
2024-07-05 16:49:30 +08:00
手瓜一十雪
0a1fc2dc12 feat: 1.6.5 2024-07-05 16:49:16 +08:00
手瓜一十雪
9857f6e437 feat: 优化载入流程 2024-07-05 16:47:08 +08:00
手瓜一十雪
56d6ebe916 refactor: 迁移到新库 2024-07-05 15:48:03 +08:00
po-lan
81134ea2d4 Update LRUCache.ts 2024-07-05 12:13:24 +08:00
po-lan
a9f3e7fc54 Update db.ts
通过读取缓存修复刚说话缺无法获取发言时间的问题
2024-07-05 12:12:40 +08:00
po-lan
eb84e2f8c9 Update LRUCache.ts
Add a get function to the cache
2024-07-05 12:09:59 +08:00
手瓜一十雪
61cfa0e86d release: 1.6.4 2024-07-03 14:30:55 +08:00
手瓜一十雪
0a01b8ade9 Merge pull request #97 from cnxysoft/main
修改下载函数
2024-07-02 10:13:15 +08:00
Alen
1457efa9a4 修改下载函数
为默认Headers增加Host,解决一些网站无法下载文件的问题
2024-07-02 01:07:30 +08:00
手瓜一十雪
fa5c7add7a refactor: new core 2024-07-01 18:45:48 +08:00
手瓜一十雪
d644eba4d1 refactor: napcat 2024-07-01 18:24:36 +08:00
手瓜一十雪
9c422c1a8f Merge pull request #95 from ahjsrhj/main
feat: ws反代请求添加UA: OneBot/11
2024-07-01 13:20:47 +08:00
手瓜一十雪
b6db37202f feat: core code 2024-07-01 13:18:59 +08:00
手瓜一十雪
4ca3891089 refactor: core 2024-07-01 13:18:19 +08:00
ahjsrhj
4c7ed01776 feat: ws反代请求添加UA: OneBot/11 2024-07-01 11:19:15 +08:00
手瓜一十雪
45c922c377 release: 1.6.3 2024-06-28 14:00:15 +08:00
手瓜一十雪
f854c258bd fix: 清除旧的反向ws 2024-06-28 13:42:09 +08:00
手瓜一十雪
a643fac073 refactor: msg context 2024-06-28 13:38:03 +08:00
手瓜一十雪
861f105bea fix: uid->uin 临时修复方案
uid uin转换需要优化
2024-06-28 13:11:06 +08:00
346 changed files with 15821 additions and 8737 deletions

View File

@@ -1,21 +1,21 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf|crlf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
charset = utf-8
# 2 space indentation
[*.{cjs,mjs,js,jsx,ts,tsx,css,scss,sass,html,json}]
indent_style = space
indent_size = 2
# 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.
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
# Matches multiple files with brace expansion notation
# Set default charset
charset = utf-8
# 2 space indentation
[*.{cjs,mjs,js,jsx,ts,tsx,css,scss,sass,html,json}]
indent_style = space
indent_size = 2
# 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.

3
.gitignore vendored
View File

@@ -14,4 +14,5 @@ dist/
# Build
*.db
checkVersion.sh
checkVersion.sh
bun.lockb

4
.gitmodules vendored
View File

@@ -1,4 +0,0 @@
[submodule "src/core"]
path = src/core
url = https://github.com/NapNeko/core.git
branch = master

37
LICENSE
View File

@@ -1,21 +1,24 @@
MIT License
BSD 2-Clause License
Copyright (c) 2024 NapCatQQ
Copyright (c) 2024, NapNeko
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:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
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.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,13 @@
# v1.8.3
QQ Version: Windows 9.9.15-26702 / Linux 3.2.12-26702
## 启动的方式
Way03/Way05
## 新增与调整
1. 输入状态变更事件加入
2. Way05 支持Bat启动
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,13 @@
# v1.6.3
QQ Version: Windows 9.9.11-24815 / Linux 3.2.9-24815
## 修复与优化
* 修复带有groupid的私聊消息异常发送到群聊消息
* 尝试修复rws热重载失效问题
* 尝试修复进群事件无法正常获取uin
## 新增与调整
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,18 @@
# v1.6.4
QQ Version: Windows 9.9.12-26000 / Linux 3.2.9-26000
## 使用前警告
1. 在最近版本由于QQ本体大幅变动为了保证NapCat可用性NapCat近期启动与安装方式将将大幅变动请关注文档和社群获取。
2. 在Core上完全执行开源请不要用于违法用途如此可能造成NapCat完全停止更新。
3. 针对原启动方式的围堵NapCat研发了多种方式除此其余理论与扩展的分析和思路将部分展示于Docs以便各位参与开发与维护NapCat。
## 其余·备注
启动方式: WayBoot.03 Electron Main进程为Node 直接注入代码 同理项目: LiteLoader
## 修复与优化
1. 支持Win平台 9.9.12
2. 修复部分发送图片下载异常情况
## 新增与调整
没有哦
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,18 @@
# v1.6.5
QQ Version: Windows 9.9.12-26000 / Linux 3.2.9-26000
## 使用前警告
1. 在最近版本由于QQ本体大幅变动为了保证NapCat可用性NapCat近期启动与安装方式将将大幅变动请关注文档和社群获取。
2. 在Core上完全执行开源请不要用于违法用途如此可能造成NapCat完全停止更新。
3. 针对原启动方式的围堵NapCat研发了多种方式除此其余理论与扩展的分析和思路将部分展示于Docs以便各位参与开发与维护NapCat。
## 其余·备注
启动方式: WayBoot.03 Electron Main进程为Node 直接注入代码 同理项目: LiteLoader
## 修复与优化
1. 优化了WrapperNative载入代码
2. 优化缓存
## 新增与调整
没有哦
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -0,0 +1,17 @@
# v1.6.6
QQ Version: Windows 9.9.12-26000 / Linux 3.2.9-26000
## 使用前警告
1. 在最近版本由于QQ本体大幅变动为了保证NapCat可用性NapCat近期启动与安装方式将将大幅变动请关注文档和社群获取。
2. 在Core上完全执行开源请不要用于违法用途如此可能造成NapCat完全停止更新。
3. 针对原启动方式的围堵NapCat研发了多种方式除此其余理论与扩展的分析和思路将部分展示于Docs以便各位参与开发与维护NapCat。
## 其余·备注
启动方式: WayBoot.03 Electron Main进程为Node 直接注入代码 同理项目: LiteLoader
## 修复与优化
1. 修复了一些问题
## 新增与调整
没有哦
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)

View File

@@ -1,2 +0,0 @@
# 开始
jadx 跳转于 `com.tencent.qqnt.kernel.*`

View File

@@ -1,42 +0,0 @@
# Android
```java
GroupMemberExtReq groupMemberExtReq = new GroupMemberExtReq();
groupMemberExtReq.sourceType = MemberExtSourceType.TITLETYPE.ordinal();
groupMemberExtReq.groupCode = longOrNull.longValue();
groupMemberExtReq.beginUin = "0";
groupMemberExtReq.dataTime = "0";
Long[] lArr = new Long[1];
AppInterface a2 = dVar.a();
lArr[0] = Long.valueOf(a2 != null ? a2.getLongAccountUin() : 0L);
arrayListOf = CollectionsKt__CollectionsKt.arrayListOf(lArr);
groupMemberExtReq.uinList = arrayListOf;
MemberExtInfoFilter memberExtInfoFilter = new MemberExtInfoFilter();
memberExtInfoFilter.memberLevelInfoUin = 1;
memberExtInfoFilter.memberLevelInfoPoint = 1;
memberExtInfoFilter.memberLevelInfoActiveDay = 1;
memberExtInfoFilter.memberLevelInfoLevel = 1;
memberExtInfoFilter.levelName = 1;
memberExtInfoFilter.dataTime = 1;
memberExtInfoFilter.sysShowFlag = 1;
memberExtInfoFilter.userShowFlag = 1;
memberExtInfoFilter.userShowFlagNew = 1;
memberExtInfoFilter.levelNameNew = 1;
Unit unit = Unit.INSTANCE;
groupMemberExtReq.memberExtFilter = memberExtInfoFilter;
troopLevelFrequencyControl.f(troopUin, new TroopListRepo$fetchTroopLevelInfo$2(b2, groupMemberExtReq, troopUin, new com.tencent.qqnt.troopmemberlist.report.c("fetchTroopLevelInfo")));
```
# Win
参数解析位于 sub_181456A10(24108) -> wrapper.node(24108)+1456A10
IGroupService.GetMemberExt(param: object);
param展开如下
```
groupCode string
beginUin string
dataTime string
uinList Array<string>
uinNum string
groupType string
richCardNameVer string
sourceType number
memberExtFilter object// 参数解析位于 sub_18145A6D0(24108) -> wrapper.node(24108)+145A6D0
```

View File

@@ -1,3 +1,4 @@
public static final int C2C_PIC_DOWNLOAD = 1004;
public static final String C2C_PIC_DOWNLOAD_DOMAIN = "c2cpicdw.qpic.cn";
public static final String C2C_PIC_DOWNLOAD_QUIC_DOMAIN = "c2cpicdw.quic.qpic.cn";

View File

@@ -0,0 +1,16 @@
# 开发方向
方向一 NativeCall/Hook:
1. 崩溃检测机制的实现
2. Api_Caller 的Hook 可以拿到Event/Handler 进一步提升NC 即时的拦截与处理一些事件比如ReCall拦截
3. Node包装层 进一步分析拿到脱离自带Listener/Adapter可以拿到一些更加底层的数据变动 或许包括更多二进制数据
方向二 全新的无头启动 Way01
1. 基于Node启动原理借助导出符号获取函数地址 再次还原NodeMain
方向三 发包与收包
1. 参考 方向一/3 大概可以收包
2. 发包 (暂时没有计划)
方向四 版本控制
1. 根据不同版本进行逻辑控制
2. 某些参数的自动提取

View File

@@ -1,24 +0,0 @@
# 前排提示
由于Core未处于开源非组织人员无法参与Core开发此处为Core开发提示
# 准备工具
frida ida-pro jadx x64dbg ce 内部调试脚本
## ida-pro
1. 用于快速分析入参和返回类型
2. 通过静态QLog推测语义
3. 提取Listener与Service (常用)
## frida
1. 用于动态获取QLog推测语义
2. 捕捉Native函数 实际入参与数据 分析中间流程
## jadx
1. 通过其它平台实现 静态获取QLog推测语义
2. 提供部分未调用代码 参考
## x64dbg
1. 验证IDA的Hook点
## 内部脚本
1. 提取Listener与Service (不调用无类型 不推荐)
2. 获取NT调用流程

View File

@@ -1 +1,8 @@
# Api方向
## getMsgUniqueId √ 已应用
getMsgUniqueId 传入时间 产出一个唯一ID 发送消息作为一个参数
# Native方向
## magic_load
## api_caller
## NodeMain

View File

@@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "1.6.2",
"version": "1.8.5",
"scripts": {
"watch:dev": "vite --mode development",
"watch:prod": "vite --mode production",
@@ -19,10 +19,9 @@
},
"devDependencies": {
"@babel/core": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"vite-plugin-babel": "^1.2.0",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.24.7",
"@babel/preset-typescript": "^7.24.7",
"@log4js-node/log4js-api": "^1.0.2",
"@protobuf-ts/plugin": "^2.9.4",
"@rollup/plugin-node-resolve": "^15.2.3",
@@ -31,9 +30,9 @@
"@types/express": "^4.17.21",
"@types/figlet": "^1.5.8",
"@types/fluent-ffmpeg": "^2.1.24",
"@types/node": "^20.11.30",
"@types/jest": "^29.5.12",
"@types/node": "^22.0.0",
"@types/qrcode-terminal": "^0.12.2",
"@types/uuid": "^10.0.0",
"@types/ws": "^8.5.10",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"@typescript-eslint/parser": "^7.4.0",
@@ -47,6 +46,7 @@
"rollup-plugin-obfuscator": "^1.1.0",
"typescript": "^5.3.3",
"vite": "^5.2.6",
"vite-plugin-babel": "^1.2.0",
"vite-plugin-cp": "^4.0.8",
"vite-plugin-dts": "^3.8.2",
"vite-tsconfig-paths": "^4.3.2"
@@ -64,9 +64,7 @@
"json-schema-to-ts": "^3.1.0",
"log4js": "^6.9.1",
"qrcode-terminal": "^0.12.0",
"silk-wasm": "^3.3.4",
"sqlite3": "^5.1.7",
"uuid": "^10.0.0",
"silk-wasm": "^3.6.1",
"ws": "^8.16.0"
}
}

45
script/BootWay.03.ps1 Normal file
View File

@@ -0,0 +1,45 @@
# Dont Use This Script
# 2024.7.3
function Get-QQpath {
try {
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
$uninstallString = $key.UninstallString
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe"
}
catch {
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 " "
Try {
$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
$commandInfo = Get-Command $QQpath -ErrorAction Stop
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& chcp 65001;& '$($commandInfo.Path)' --enable-logging }"

90
script/BootWay05.bat Normal file
View File

@@ -0,0 +1,90 @@
@echo off
REM 检查当前会话是否具有管理员权限
openfiles >nul 2>&1
if %errorlevel% neq 0 (
REM 如果不是管理员,则重新启动脚本以管理员模式运行
echo 请求管理员权限...
powershell -Command "Start-Process cmd -ArgumentList '/c %~f0 %*' -Verb RunAs"
exit /b
)
REM 设置当前工作目录
cd /d %~dp0
REM 获取当前目录路径
set currentPath=%cd%
set currentPath=%currentPath:\=/%
REM 生成JavaScript代码
set "jsCode=(async () =^>await import('file:///%currentPath%/napcat.mjs'))();"
REM 将JavaScript代码保存到文件中
echo %jsCode% > loadScript.js
echo JavaScript code has been generated and saved to loadScript.js
REM 设置NAPCAT_PATH环境变量为 当前目录的loadScript.js地址
set NAPCAT_PATH=%cd%\loadScript.js
REM 获取QQ路径
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set RetString=%%b
goto :napcat_boot
)
:napcat_boot
for %%a in (%RetString%) do (
set "pathWithoutUninstall=%%~dpa"
)
SET QQPath=%pathWithoutUninstall%QQ.exe
REM 拿不到QQ路径则退出
if not exist "%QQpath%" (
echo provided QQ path is invalid: %QQpath%
pause
exit /b
)
REM 收集dbghelp.dll路径和HASH信息
set QQdir=%~dp0
set oldDllPath=%QQdir%dbghelp.dll
set newDllPath=%currentPath%\dbghelp.dll
for /f "tokens=*" %%A in ('certutil -hashfile "%oldDllPath%" MD5') do (
if not defined oldDllHash set oldDllHash=%%A
)
for /f "tokens=*" %%A in ('certutil -hashfile "%newDllPath%" MD5') do (
if not defined newDllHash set newDllHash=%%A
)
REM 如果文件一致则跳过
if "%oldDllHash%" neq "%newDllHash%" (
tasklist /fi "imagename eq QQ.exe" 2>nul | find /i "QQ.exe" >nul
if %errorlevel% equ 0 (
REM 文件占用则退出
echo dbghelp.dll is in use, cannot continue.
) else (
REM 文件未占用则尝试覆盖
copy /y "%newDllPath%" "%oldDllPath%"
if %errorlevel% neq 0 (
echo Failed to copy dbghelp.dll
pause
exit /b
) else (
echo dbghelp.dll has been copied to %QQdir%
)
)
)
REM 带参数启动QQ
REM 判断wt是否存在存在则通过wt启动不存在则通过cmd启动
REM %QQPath% --enable-logging %*
where wt >nul 2>nul
if %errorlevel% equ 0 (
wt "cmd" /c "%QQPath%" --enable-logging %*
) else (
"%QQPath%" --enable-logging %*
)

123
script/BootWay05.ps1 Normal file
View File

@@ -0,0 +1,123 @@
# 检查当前会话是否具有管理员权限
function Test-Administrator {
$user = [Security.Principal.WindowsIdentity]::GetCurrent()
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
if (-not (Test-Administrator)) {
# 如果不是管理员,则重新启动脚本以管理员模式运行
$scriptPath = $myInvocation.MyCommand.Path
if (-not $scriptPath) {
$scriptPath = $PSCommandPath
}
$newProcess = New-Object System.Diagnostics.ProcessStartInfo "powershell";
$newProcess.Arguments = "-File `"$scriptPath`" $args"
$newProcess.Verb = "runas";
[System.Diagnostics.Process]::Start($newProcess);
exit
}
function Get-QQpath {
try {
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
$uninstallString = $key.UninstallString
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe"
}
catch {
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
}
# 设置当前工作目录
$scriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Set-Location $scriptDirectory
# 获取当前目录路径
$currentPath = Get-Location
# 替换\为/
$currentPath = $currentPath -replace '\\', '/'
# 生成JavaScript代码
$jsCode = @"
(async () => {
await import('file:///$currentPath/napcat.mjs');
})();
"@
# 将JavaScript代码保存到文件中
$jsFilePath = Join-Path $currentPath "loadScript.js"
$jsCode | Out-File -FilePath $jsFilePath -Encoding UTF8
Write-Output "JavaScript code has been generated and saved to $jsFilePath"
# 设置NAPCAT_PATH环境变量为 当前目录的loadScript.js地址
$env:NAPCAT_PATH = $jsFilePath
$params = $args -join " "
Try {
$QQpath = Get-QQpath
}
Catch {
$QQpath = Select-QQPath
}
# 拿不到QQ路径则退出
if (!(Test-Path $QQpath)) {
Write-Output "provided QQ path is invalid: $QQpath"
Read-Host "Press any key to continue..."
exit
}
$commandInfo = Get-Command $QQpath -ErrorAction Stop
# 收集dbghelp.dll路径和HASH信息
$QQpath = Split-Path $QQpath
$oldDllPath = Join-Path $QQpath "dbghelp.dll"
$oldDllHash = Get-FileHash $oldDllPath -Algorithm MD5
$newDllPath = Join-Path $currentPath "dbghelp.dll"
$newDllHash = Get-FileHash $newDllPath -Algorithm MD5
# 如果文件一致则跳过
if ($oldDllHash.Hash -ne $newDllHash.Hash) {
$processes = Get-Process -Name QQ -ErrorAction SilentlyContinue
if ($processes) {
# 文件占用则退出
Write-Output "dbghelp.dll is in use by the following processes:"
$processes | ForEach-Object { Write-Output "$($_.Id) $($_.Name) $($_.Path)" }
Write-Output "dbghelp.dll is in use, cannot continue."
Read-Host "Press any key to continue..."
exit
} else {
# 文件未占用则尝试覆盖
try {
Copy-Item -Path "$newDllPath" -Destination "$oldDllPath" -Force
Write-Output "dbghelp.dll has been copied to $QQpath"
} catch {
Write-Output "Failed to copy dbghelp.dll: $_"
Read-Host "Press any key to continue..."
exit
}
}
}
# 带参数启动QQ
try {
Start-Process powershell -ArgumentList '-noexit', '-noprofile', "-command &{& chcp 65001;& '$($commandInfo.Path)' --enable-logging $params}" -NoNewWindow -ErrorAction Stop
} catch {
Write-Output "Failed to start process as administrator: $_"
Read-Host "Press any key to continue..."
}

93
script/BootWay05.utf8.bat Normal file
View File

@@ -0,0 +1,93 @@
@echo off
REM 检查当前会话是否具有管理员权限
openfiles >nul 2>&1
if %errorlevel% neq 0 (
REM 如果不是管理员,则重新启动脚本以管理员模式运行
echo 请求管理员权限...
where wt >nul 2>nul
if %errorlevel% equ 0 (
powershell -Command "Start-Process cmd -ArgumentList ' /c %~f0 %*' -Verb RunAs"
) else (
powershell -Command "Start-Process wt -ArgumentList 'cmd /c %~f0 %*' -Verb RunAs"
)
REM wt "cmd" /c "%~f0 %*"
exit /b
)
REM 设置当前工作目录
cd /d %~dp0
REM 获取当前目录路径
set currentPath=%cd%
set currentPath=%currentPath:\=/%
REM 生成JavaScript代码
set "jsCode=(async () =^>await import('file:///%currentPath%/napcat.mjs'))();"
REM 将JavaScript代码保存到文件中
echo %jsCode% > loadScript.js
echo JavaScript code has been generated and saved to loadScript.js
REM 设置NAPCAT_PATH环境变量为 当前目录的loadScript.js地址
set NAPCAT_PATH=%cd%\loadScript.js
REM 获取QQ路径
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set RetString=%%b
goto :napcat_boot
)
:napcat_boot
for %%a in (%RetString%) do (
set "pathWithoutUninstall=%%~dpa"
)
SET QQPath=%pathWithoutUninstall%QQ.exe
REM 拿不到QQ路径则退出
if not exist "%QQpath%" (
echo provided QQ path is invalid: %QQpath%
pause
exit /b
)
REM 收集dbghelp.dll路径和HASH信息
set QQdir=%~dp0
set oldDllPath=%QQdir%dbghelp.dll
set newDllPath=%currentPath%\dbghelp.dll
for /f "tokens=*" %%A in ('certutil -hashfile "%oldDllPath%" MD5') do (
if not defined oldDllHash set oldDllHash=%%A
)
for /f "tokens=*" %%A in ('certutil -hashfile "%newDllPath%" MD5') do (
if not defined newDllHash set newDllHash=%%A
)
REM 如果文件一致则跳过
if "%oldDllHash%" neq "%newDllHash%" (
tasklist /fi "imagename eq QQ.exe" 2>nul | find /i "QQ.exe" >nul
if %errorlevel% equ 0 (
REM 文件占用则退出
echo dbghelp.dll is in use, cannot continue.
) else (
REM 文件未占用则尝试覆盖
copy /y "%newDllPath%" "%oldDllPath%"
if %errorlevel% neq 0 (
echo Failed to copy dbghelp.dll
pause
exit /b
) else (
echo dbghelp.dll has been copied to %QQdir%
)
)
)
REM 带参数启动QQ
REM 判断wt是否存在存在则通过wt启动不存在则通过cmd启动
REM %QQPath% --enable-logging %*
chcp 65001
"%QQPath%" --enable-logging %*

28
script/NapCat.164.bat Normal file
View File

@@ -0,0 +1,28 @@
@echo off
chcp 65001
:: 检查是否有管理员权限
net session >nul 2>&1
if %errorlevel% neq 0 (
echo 请求管理员权限...
powershell -Command "Start-Process '%~f0' -Verb runAs"
exit /b
)
:: 如果有管理员权限,继续执行
setlocal enabledelayedexpansion
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%b"
goto :napcat_boot
)
:napcat_boot
for %%a in ("!RetString!") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=!pathWithoutUninstall!QQ.exe"
echo !QQPath!
"!QQPath!" --enable-logging %*
pause

3
script/NapCat.Way01.bat Normal file
View File

@@ -0,0 +1,3 @@
REM 全新启动脚本 基于 Hook Native 预计版本1.6.0左右发布
@echo off
pause

BIN
script/dbghelp.dll Normal file

Binary file not shown.

20
script/index.js Normal file
View File

@@ -0,0 +1,20 @@
// --------------------
// 2024.7.3 9.9.12 BootWay.03 其余方法暂不公开(此方案为临时方案 Win平台已验证
// 1.与非入侵式不同 现在破坏本体代码
// 2.重启代码与正常启动代码失效
// 3.Win需要补丁
// 4.更新后丢失内容 需要重写此文件
// 5.安装难度上升与周围基础设施失效
// --------------------
const path = require('path');
const CurrentPath = path.dirname(__filename)
const hasNapcatParam = process.argv.includes('--enable-logging');
if (hasNapcatParam) {
(async () => {
await import("file://" + path.join(CurrentPath, './napcat/napcat.mjs'));
})();
} else {
require('./launcher.node').load('external_index', module);
}

View File

@@ -0,0 +1,18 @@
@echo off
setlocal enabledelayedexpansion
chcp 65001
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%b"
goto :napcat_boot
)
:napcat_boot
for %%a in ("!RetString!") do (
set "pathWithoutUninstall=%%~dpa"
)
set "QQPath=!pathWithoutUninstall!"
cd /d !QQPath!
echo !QQPath!
QQ.exe --enable-logging %*

View File

@@ -0,0 +1,41 @@
function Get-QQpath {
try {
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
$uninstallString = $key.UninstallString
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\"
}
catch {
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 " "
Try {
$QQpath = Get-QQpath
}
Catch {
$QQpath = Select-QQPath
}
if (!(Test-Path $QQpath)) {
throw "provided QQ path is invalid: $QQpath"
}
Set-Location -Path $QQpath
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& chcp 65001;& ./QQ.exe --enable-logging $params}"

17
script/napcat-9912.bat Normal file
View File

@@ -0,0 +1,17 @@
@echo off
setlocal enabledelayedexpansion
:loop_read
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
set "RetString=%%b"
goto :napcat_boot
)
:napcat_boot
for %%a in ("!RetString!") do (
set "pathWithoutUninstall=%%~dpa"
)
set QQPath=!pathWithoutUninstall!
cd /d !QQPath!
echo !QQPath!
QQ.exe --enable-logging %*

41
script/napcat-9912.ps1 Normal file
View File

@@ -0,0 +1,41 @@
function Get-QQpath {
try {
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
$uninstallString = $key.UninstallString
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\"
}
catch {
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 " "
Try {
$QQpath = Get-QQpath
}
Catch {
$QQpath = Select-QQPath
}
if (!(Test-Path $QQpath)) {
throw "provided QQ path is invalid: $QQpath"
}
Set-Location -Path $QQpath
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& ./QQ.exe --enable-logging $params}"

View File

@@ -9,7 +9,15 @@ type RegisterHandler = (res: Response, payload: any) => Promise<any>
export abstract class HttpServerBase {
name: string = 'NapCatQQ';
private readonly expressAPP: Express;
private server: http.Server | null = null;
private _server: http.Server | null = null;
public get server(): http.Server | null {
return this._server;
}
private set server(value: http.Server | null) {
this._server = value;
}
constructor() {
this.expressAPP = express();
@@ -78,7 +86,7 @@ export abstract class HttpServerBase {
this.start(port, host);
}
abstract handleFailed(res: Response, payload: any, err: any): void
abstract handleFailed(res: Response, payload: any, err: Error): void
registerRouter(method: 'post' | 'get' | string, url: string, handler: RegisterHandler) {
if (!url.startsWith('/')) {
@@ -103,7 +111,7 @@ export abstract class HttpServerBase {
try {
res.send(await handler(res, payload));
} catch (e: any) {
this.handleFailed(res, payload, e.stack.toString());
this.handleFailed(res, payload, e);
}
});
}

View File

@@ -1,4 +1,5 @@
import { WebSocket, WebSocketServer } from 'ws';
import http from 'http';
import urlParse from 'url';
import { IncomingMessage } from 'node:http';
import { log } from '@/common/utils/log';
@@ -27,17 +28,36 @@ export class WebsocketServerBase {
constructor() {
}
start(port: number, host: string = '') {
try {
this.ws = new WebSocketServer({
port,
host: '',
maxPayload: 1024 * 1024 * 1024
}).on('error', () => {
});
log(`ws服务启动成功, ${host}:${port}`);
} catch (e: any) {
throw Error('ws服务启动失败, 请检查监听的ip和端口' + e.toString());
start(port: number | http.Server, host: string = '') {
if (port instanceof http.Server) {
try {
const wss = new WebSocketServer({
noServer: true,
maxPayload: 1024 * 1024 * 1024
}).on('error', () => {
});
this.ws = wss;
port.on('upgrade', function upgrade(request, socket, head) {
wss.handleUpgrade(request, socket, head, function done(ws) {
wss.emit('connection', ws, request);
});
});
log('ws服务启动成功, 绑定到HTTP服务');
} catch (e: any) {
throw Error('ws服务启动失败, 可能是绑定的HTTP服务异常' + e.toString());
}
} else {
try {
this.ws = new WebSocketServer({
port,
host: '',
maxPayload: 1024 * 1024 * 1024
}).on('error', () => {
});
log(`ws服务启动成功, ${host}:${port}`);
} catch (e: any) {
throw Error('ws服务启动失败, 请检查监听的ip和端口' + e.toString());
}
}
this.ws.on('connection', (wsClient, req) => {
const url: string = req.url!.split('?').shift() || '/';
@@ -50,10 +70,12 @@ export class WebsocketServerBase {
}
stop() {
this.ws && this.ws.close((err) => {
log('ws server close failed!', err);
});
this.ws = null;
if (this.ws) {
this.ws.close((err) => {
if (err) log('ws server close failed!', err);
});
this.ws = null;
}
}
restart(port: number) {

View File

@@ -1,36 +0,0 @@
import { sleep } from '@/common/utils/helper';
import { logError } from './log';
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);
logError(e);
}
this.tasks.shift();
await sleep(100);
}
}
}

View File

@@ -3,6 +3,7 @@ import fs from 'node:fs';
import { log, logDebug, logError } from '@/common/utils/log';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { selfInfo } from '@/core/data';
const __filename = fileURLToPath(import.meta.url);
@@ -12,8 +13,9 @@ const configDir = path.resolve(__dirname, 'config');
fs.mkdirSync(configDir, { recursive: true });
export class ConfigBase<T>{
export class ConfigBase<T> {
public name: string = 'default_config';
private pathName: string | null = null; // 本次读取的文件路径
constructor() {
}
@@ -22,19 +24,28 @@ export class ConfigBase<T>{
return null;
}
getConfigDir(){
getConfigDir() {
const configDir = path.resolve(__dirname, 'config');
fs.mkdirSync(configDir, { recursive: true });
return configDir;
}
getConfigPath(): string {
throw new Error('Method not implemented.');
getConfigPath(pathName: string | null): string {
const suffix = pathName ? `_${pathName}` : '';
const filename = `${this.name}${suffix}.json`;
return path.join(this.getConfigDir(), filename);
}
read() {
const configPath = this.getConfigPath();
// 尝试加载当前账号配置
if (this.read_from_file(selfInfo.uin, false)) return this;
// 尝试加载默认配置
return this.read_from_file('', true);
}
read_from_file(pathName: string, createIfNotExist: boolean) {
const configPath = this.getConfigPath(pathName);
if (!fs.existsSync(configPath)) {
try{
if (!createIfNotExist) return null;
this.pathName = pathName; // 记录有效的设置文件
try {
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`);
}
@@ -43,6 +54,7 @@ export class ConfigBase<T>{
}
return this;
}
try {
const data = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
logDebug(`配置文件${configPath}已加载`, data);
@@ -61,9 +73,13 @@ export class ConfigBase<T>{
}
}
save(config: T) {
save(config: T, overwrite: boolean = false) {
Object.assign(this, config);
const configPath = this.getConfigPath();
if (overwrite) {
// 用户要求强制写入,则变更当前文件为目标文件
this.pathName = `${selfInfo.uin}`;
}
const configPath = this.getConfigPath(this.pathName);
try {
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
} catch (e: any) {

View File

@@ -1,4 +1,3 @@
import { NodeIKernelMsgListener } from '@/core';
import { NodeIQQNTWrapperSession } from '@/core/wrapper';
import { randomUUID } from 'crypto';
@@ -6,6 +5,7 @@ interface Internal_MapKey {
timeout: number,
createtime: number,
func: (...arg: any[]) => any,
checker: ((...args: any[]) => boolean) | undefined,
}
export class ListenerClassBase {
@@ -84,17 +84,19 @@ export class NTEventWrapper {
}
//统一回调清理事件
async DispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) {
//console.log(ListenerMainName, this.EventTask.get(ListenerMainName), ListenerSubName, this.EventTask.get(ListenerMainName)?.get(ListenerSubName));
//console.log("[EventDispatcher]",ListenerMainName, ListenerSubName, ...args);
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);
if (task.checker && task.checker(...args)) {
task.func(...args);
}
});
}
async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any>,>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any> | any>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
return new Promise<Awaited<ReturnType<EventType>>>(async (resolve, reject) => {
const EventFunc = this.CreatEventFunction<EventType>(EventName);
let complete = false;
@@ -108,27 +110,71 @@ export class NTEventWrapper {
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>) {
async RegisterListen<ListenerType extends (...args: any[]) => void>(ListenerName = '', waitTimes = 1, timeout = 5000, checker: (...args: Parameters<ListenerType>) => boolean) {
return new Promise<Parameters<ListenerType>>((resolve, reject) => {
const ListenerNameList = ListenerName.split('/');
const ListenerMainName = ListenerNameList[0];
const ListenerSubName = ListenerNameList[1];
const id = randomUUID();
let complete = 0;
let retData: Parameters<ListenerType> | undefined = undefined;
const databack = () => {
if (complete == 0) {
reject(new Error(' ListenerName:' + ListenerName + ' timeout'));
} else {
resolve(retData!);
}
};
const Timeouter = setTimeout(databack, timeout);
const eventCallbak = {
timeout: timeout,
createtime: Date.now(),
checker: checker,
func: (...args: Parameters<ListenerType>) => {
complete++;
retData = args;
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);
});
}
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>
(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, checker: (...args: Parameters<ListenerType>) => boolean, ...args: Parameters<EventType>) {
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
const id = randomUUID();
let complete = 0;
let retData: Parameters<ListenerType> | undefined = undefined;
let retEvent: any = {};
const databack = () => {
if (complete < waitTimes) {
reject(new Error('NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' timeout'));
if (complete == 0) {
reject(new Error('Timeout: NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' EventRet:\n' + JSON.stringify(retEvent, null, 4) + '\n'));
} else {
resolve([retEvent as Awaited<ReturnType<EventType>>, ...retData!]);
}
};
const Timeouter = setTimeout(databack, timeout);
const ListenerNameList = ListenerName.split('/');
const ListenerMainName = ListenerNameList[0];
const ListenerSubName = ListenerNameList[1];
const Timeouter = setTimeout(databack, timeout);
const eventCallbak = {
timeout: timeout,
createtime: Date.now(),
checker: checker,
func: (...args: any[]) => {
complete++;
//console.log('func', ...args);
@@ -148,7 +194,6 @@ export class NTEventWrapper {
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak);
this.CreatListenerFunction(ListenerMainName);
const EventFunc = this.CreatEventFunction<EventType>(EventName);
//console.log("测试打点", args);
retEvent = await EventFunc!(...(args as any[]));
});
}

View File

@@ -1,145 +0,0 @@
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

@@ -1,20 +1,40 @@
import crypto from 'crypto';
import { Peer } from '@/core';
import crypto, { randomInt, randomUUID } from 'crypto';
import { logError } from './log';
class LimitedHashTable<K, V> {
export class LimitedHashTable<K, V> {
private keyToValue: Map<K, V> = new Map();
private valueToKey: Map<V, K> = new Map();
private maxSize: number;
private KeyQueneList: K[] = [];
private ValueQueneList: V[] = [];
constructor(maxSize: number) {
this.maxSize = maxSize;
}
resize(count: number) {
this.maxSize = count;
}
set(key: K, value: V): void {
// const isExist = this.keyToValue.get(key);
// if (isExist && isExist === value) {
// return;
// }
this.keyToValue.set(key, value);
this.valueToKey.set(value, key);
if (this.KeyQueneList.length >= this.maxSize || this.ValueQueneList.length >= this.maxSize) {
this.KeyQueneList.shift();
this.ValueQueneList.shift();
while (this.keyToValue.size !== this.valueToKey.size) {
console.log('keyToValue.size !== valueToKey.size Error Atom');
this.keyToValue.clear();
this.valueToKey.clear();
}
// console.log('---------------');
// console.log(this.keyToValue);
// console.log(this.valueToKey);
// console.log('---------------');
while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) {
//console.log(this.keyToValue.size > this.maxSize, this.valueToKey.size > this.maxSize);
const oldestKey = this.keyToValue.keys().next().value;
this.valueToKey.delete(this.keyToValue.get(oldestKey)!);
this.keyToValue.delete(oldestKey);
}
}
@@ -26,28 +46,99 @@ class LimitedHashTable<K, V> {
return this.valueToKey.get(value);
}
delete(key: K): void {
deleteByValue(value: V): void {
const key = this.valueToKey.get(value);
if (key !== undefined) {
this.keyToValue.delete(key);
this.valueToKey.delete(value);
}
}
deleteByKey(key: K): void {
const value = this.keyToValue.get(key);
if (value !== undefined) {
this.keyToValue.delete(key);
this.valueToKey.delete(value);
}
}
getKeyList(): K[] {
return Array.from(this.keyToValue.keys());
}
//获取最近刚写入的几个值
getHeads(size: number): { key: K; value: V }[] | undefined {
const keyList = this.getKeyList();
if (keyList.length === 0) {
return undefined;
}
const result: { key: K; value: V }[] = [];
const listSize = Math.min(size, keyList.length);
for (let i = 0; i < listSize; i++) {
const key = keyList[listSize - i];
result.push({ key, value: this.keyToValue.get(key)! });
}
return result;
}
}
class MessageUniqueWrapper {
private msgIdMap: LimitedHashTable<number, string> = new LimitedHashTable(1000);
createMsg(MsgId: string) {
const ShortId = parseInt(crypto.createHash('sha1').update('2345').digest('hex').slice(0, 8), 16);
this.msgIdMap.set(ShortId, MsgId);
return ShortId;
private msgDataMap: LimitedHashTable<string, number>;
private msgIdMap: LimitedHashTable<string, number>;
constructor(maxMap: number = 1000) {
this.msgIdMap = new LimitedHashTable<string, number>(maxMap);
this.msgDataMap = new LimitedHashTable<string, number>(maxMap);
}
getMsgIdByShortId(ShortId: number) {
return this.msgIdMap.getValue(ShortId);
getRecentMsgIds(Peer: Peer, size: number): string[] {
const heads = this.msgIdMap.getHeads(size);
if (!heads) {
return [];
}
const data = heads.map((t) => MessageUnique.getMsgIdAndPeerByShortId(t.value));
const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid);
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined);
}
getShortIdByMsgId(MsgId: string) {
return this.msgIdMap.getKey(MsgId);
createMsg(peer: Peer, msgId: string): number | undefined {
const key = `${msgId}|${peer.chatType}|${peer.peerUid}`;
const hash = crypto.createHash('md5').update(key).digest();
//设置第一个bit为0 保证shortId为正数
hash[0] &= 0x7f;
const shortId = hash.readInt32BE(0);
//减少性能损耗
// const isExist = this.msgIdMap.getKey(shortId);
// if (isExist && isExist === msgId) {
// return shortId;
// }
this.msgIdMap.set(msgId, shortId);
this.msgDataMap.set(key, shortId);
return shortId;
}
getMsgIdAndPeerByShortId(shortId: number): { MsgId: string; Peer: Peer } | undefined {
const data = this.msgDataMap.getKey(shortId);
if (data) {
const [msgId, chatTypeStr, peerUid] = data.split('|');
const peer: Peer = {
chatType: parseInt(chatTypeStr),
peerUid,
guildId: '',
};
return { MsgId: msgId, Peer: peer };
}
return undefined;
}
getShortIdByMsgId(msgId: string): number | undefined {
return this.msgIdMap.getValue(msgId);
}
getPeerByMsgId(msgId: string) {
const shortId = this.msgIdMap.getValue(msgId);
if (!shortId) return undefined;
return this.getMsgIdAndPeerByShortId(shortId);
}
resize(maxSize: number): void {
this.msgIdMap.resize(maxSize);
this.msgDataMap.resize(maxSize);
}
}
export const MessageUnique = new MessageUniqueWrapper();
export const MessageUnique: MessageUniqueWrapper = new MessageUniqueWrapper();

View File

@@ -1,77 +1,57 @@
import path from 'node:path';
import fs from 'node:fs';
import os from 'node:os';
import { systemPlatform } from '@/common/utils/system';
import { logError } from '@/common/utils/log';
import { getDefaultQQVersionConfigInfo, getQQVersionConfigPath } from './helper';
import AppidTable from '@/core/external/appid.json';
import { log } from './log';
export const exePath = process.execPath;
//基础目录获取
export const QQMainPath = process.execPath;
export const QQPackageInfoPath: string = path.join(path.dirname(QQMainPath), 'resources', 'app', 'package.json');
export const QQVersionConfigPath: string | undefined = getQQVersionConfigPath(QQMainPath);
export const pkgInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'package.json');
let configVersionInfoPath;
//基础信息获取 无快更则启用默认模板填充
export const isQuickUpdate: boolean = !!QQVersionConfigPath;
export const QQVersionConfig: QQVersionConfigType = isQuickUpdate ? JSON.parse(fs.readFileSync(QQVersionConfigPath!).toString()) : getDefaultQQVersionConfigInfo();
export const QQPackageInfo: QQPackageInfoType = JSON.parse(fs.readFileSync(QQPackageInfoPath).toString());
export const { appid: QQVersionAppid, qua: QQVersionQua } = getAppidV2();
if (os.platform() !== 'linux') {
configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json');
} else {
const userPath = os.homedir();
const appDataPath = path.resolve(userPath, './.config/QQ');
configVersionInfoPath = path.resolve(appDataPath, './versions/config.json');
//基础函数
export function getQQBuildStr() {
return isQuickUpdate ? QQVersionConfig.buildId : QQPackageInfo.buildVersion;
}
if (typeof configVersionInfoPath !== 'string') {
throw new Error('Something went wrong when load QQ info path');
export function getFullQQVesion() {
return isQuickUpdate ? QQVersionConfig.curVersion : QQPackageInfo.version;
}
export { configVersionInfoPath };
type QQPkgInfo = {
version: string;
buildVersion: string;
platform: string;
eleArch: string;
export function requireMinNTQQBuild(buildStr: string) {
return parseInt(getQQBuildStr()) >= parseInt(buildStr);
}
type QQVersionConfigInfo = {
baseVersion: string;
curVersion: string;
prevVersion: string;
onErrorVersions: Array<any>;
buildId: string;
//此方法不要直接使用
export function getQUAInternal() {
return systemPlatform === 'linux' ? `V1_LNX_NQ_${getFullQQVesion()}_${getQQBuildStr()}_GW_B` : `V1_WIN_NQ_${getFullQQVesion()}_${getQQBuildStr()}_GW_B`;
}
let _qqVersionConfigInfo: QQVersionConfigInfo = {
'baseVersion': '9.9.11-24568',
'curVersion': '9.9.11-24568',
'prevVersion': '',
'onErrorVersions': [],
'buildId': '24568'
};
if (fs.existsSync(configVersionInfoPath)) {
export function getAppidV2(): { appid: string, qua: string } {
const appidTbale = AppidTable as unknown as QQAppidTableType;
try {
const _ =JSON.parse(fs.readFileSync(configVersionInfoPath).toString());
_qqVersionConfigInfo = Object.assign(_qqVersionConfigInfo, _);
} catch (e) {
logError('Load QQ version config info failed, Use default version', e);
const data = appidTbale[getFullQQVesion()];
if (data) {
return data;
}
}
catch (e) {
log('[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常');
}
// 以下是兜底措施
log(`[QQ版本兼容性检测] ${getFullQQVesion()} 版本兼容性不佳,可能会导致一些功能无法正常使用`);
return { appid: systemPlatform === 'linux' ? '537237950' : '537237765', qua: getQUAInternal() };
}
export const qqVersionConfigInfo: QQVersionConfigInfo = _qqVersionConfigInfo;
//V1_WIN_NQ_9.9.11_24568_GW_B
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',
// app_version: '9.9.12-25765',
// qua: 'V1_WIN_NQ_9.9.12_25765_GW_B',
// appid: '537234702',
// platVer: '10.0.26100',
// clientVer: '9.9.9-23159',
// clientVer: '9.9.9-25765',
// Linux
// app_version: '3.2.9-24568',
// qua: 'V1_LNX_NQ_3.2.9_24568_GW_B',
let _appid: string = '537226369'; // 默认为 Windows 平台的 appid
if (systemPlatform === 'linux') {
_appid = '537226441';
}
// todo: mac 平台的 appid
export const appid = _appid;
// app_version: '3.2.9-25765',
// qua: 'V1_LNX_NQ_3.2.10_25765_GW_B',

View File

@@ -1,9 +1,9 @@
import fs from 'fs';
import { encode, getDuration, getWavFileInfo, isWav } from 'silk-wasm';
import { encode, getDuration, getWavFileInfo, isWav, isSilk } from 'silk-wasm';
import fsPromise from 'fs/promises';
import { log, logError } from './log';
import path from 'node:path';
import { v4 as uuidv4 } from 'uuid';
import { randomUUID } from 'crypto';
import { spawn } from 'node:child_process';
import { getTempDir } from '@/common/utils/file';
@@ -63,10 +63,11 @@ export async function encodeSilk(filePath: string) {
// }
try {
const pttPath = path.join(TEMP_DIR, uuidv4());
if (getFileHeader(filePath) !== '02232153494c4b') {
const file = await fsPromise.readFile(filePath);
const pttPath = path.join(TEMP_DIR, randomUUID());
if (!isSilk(file)) {
log(`语音文件${filePath}需要转换成silk`);
const _isWav = await isWavFile(filePath);
const _isWav = isWav(file);
const pcmPath = pttPath + '.pcm';
let sampleRate = 0;
const convert = () => {
@@ -96,7 +97,7 @@ export async function encodeSilk(filePath: string) {
if (!_isWav) {
input = await convert();
} else {
input = fs.readFileSync(filePath);
input = file;
const allowSampleRate = [8000, 12000, 16000, 24000, 32000, 44100, 48000];
const { fmt } = getWavFileInfo(input);
// log(`wav文件信息`, fmt)
@@ -113,7 +114,7 @@ export async function encodeSilk(filePath: string) {
duration: silk.duration / 1000
};
} else {
const silk = fs.readFileSync(filePath);
const silk = file;
let duration = 0;
try {
duration = getDuration(silk) / 1000;

View File

@@ -1,449 +0,0 @@
import { ElementType, FileElement, PicElement, PttElement, RawMessage, VideoElement } from '../../core/src/entities';
import sqlite3 from 'sqlite3';
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 = {
id: number,
shortId: number,
longId: string,
seq: number,
peerUid: string,
chatType: number,
}
type DBFile = {
name: string; // 文件名
path: string;
url: string;
size: number;
uuid: string;
msgId: string;
elementId: string;
element: PicElement | VideoElement | FileElement | PttElement;
elementType: ElementType.PIC | ElementType.VIDEO | ElementType.FILE | ElementType.PTT;
}
class DBUtilBase {
protected db: sqlite3.Database | undefined;
async init(dbPath: string) {
if (this.db) {
return;
}
return new Promise<void>((resolve, reject) => {
this.db = new sqlite3.Database(dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
if (err) {
logError('Could not connect to database', err);
reject(err);
return;
}
this.createTable();
resolve();
});
});
}
protected createTable() {
throw new Error('Method not implemented.');
}
close() {
this.db?.close();
}
}
class DBUtil extends DBUtilBase {
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() {
super();
const interval = 1000 * 60 * 10; // 10分钟清理一次缓存
setInterval(() => {
logDebug('清理消息缓存');
this.msgCache.forEach((msg, key) => {
if ((Date.now() - parseInt(msg.msgTime) * 1000) > interval) {
this.msgCache.delete(key);
}
});
}, 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() {
// 消息记录
const createTableSQL = `
CREATE TABLE IF NOT EXISTS msgs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
shortId INTEGER NOT NULL UNIQUE,
longId TEXT NOT NULL UNIQUE,
seq INTEGER NOT NULL,
peerUid TEXT NOT NULL,
chatType INTEGER NOT NULL
)`;
this.db!.run(createTableSQL, function (err) {
if (err) {
logError('Could not create table msgs', err.stack);
}
});
// 文件缓存
const createFileTableSQL = `
CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
path TEXT NOT NULL,
url TEXT,
size INTEGER NOT NULL,
uuid TEXT,
elementType INTEGER,
element TEXT NOT NULL,
elementId TEXT NOT NULL,
msgId TEXT NOT NULL
)`;
this.db!.run(createFileTableSQL, function (err) {
if (err) {
logError('Could not create table files', 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[]) {
const stmt = this.db!.prepare(query);
return new Promise<RawMessage | null>((resolve, reject) => {
stmt.get(...params, (err: any, row: DBMsg) => {
// log("getMsg", row, err);
if (err) {
logError('Could not get msg', err, query, params);
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> {
if (this.msgCache.has(shortId)) {
return this.msgCache.get(shortId)!;
}
const getStmt = 'SELECT * FROM msgs WHERE shortId = ?';
return this.getMsg(getStmt, [shortId]);
}
async getMsgByLongId(longId: string): Promise<RawMessage | null> {
if (this.msgCache.has(longId)) {
return this.msgCache.get(longId)!;
}
return this.getMsg('SELECT * FROM msgs WHERE longId = ?', [longId]);
}
async getMsgBySeq(peerUid: string, seq: string): Promise<RawMessage | null> {
const stmt = 'SELECT * FROM msgs WHERE peerUid = ? AND seq = ?';
return this.getMsg(stmt, [peerUid, seq]);
}
async addMsg(msg: RawMessage, update = true): Promise<number> {
const existMsg = await this.getMsgByLongId(msg.msgId);
if (existMsg) {
// logDebug('消息已存在,更新数据库', msg.msgId);
if (update) this.updateMsg(msg).then();
return existMsg.id!;
}
const stmt = this.db!.prepare('INSERT INTO msgs (shortId, longId, seq, peerUid, chatType) VALUES (?, ?, ?, ?, ?)');
// const runAsync = promisify(stmt.run.bind(stmt));
const shortId = ++this.globalMsgShortId;
msg.id = shortId;
//logDebug(`记录消息到数据库, 消息长id: ${msg.msgId}, 短id: ${msg.id}`);
this.msgCache.set(shortId, msg);
this.msgCache.set(msg.msgId, msg);
stmt.run(this.globalMsgShortId, msg.msgId, msg.msgSeq.toString(), msg.peerUid, msg.chatType, (err: any) => {
if (err) {
if (err.errno === 19) {
this.getMsgByLongId(msg.msgId).then((msg: RawMessage | null) => {
if (msg) {
this.msgCache.set(shortId, msg);
this.msgCache.set(msg.msgId, msg);
// logDebug('获取消息短id成功', msg.id);
} else {
logError('db could not get msg by long id', err);
}
}).catch(e => logError('db getMsgByLongId error', e));
} else {
logError('db could not add msg', err);
}
}
});
return shortId;
}
async updateMsg(msg: RawMessage) {
const existMsg = this.msgCache.get(msg.msgId);
if (existMsg) {
Object.assign(existMsg, msg);
}
//logDebug(`更新消息, shortId:${msg.id}, seq: ${msg.msgSeq}, msgId: ${msg.msgId}`);
const stmt = this.db!.prepare('UPDATE msgs SET seq=? WHERE longId=?');
stmt.run(msg.msgSeq, msg.msgId, (err: any) => {
if (err) {
logError('updateMsg db error', err);
}
});
}
async addFileCache(file: DBFile) {
const stmt = this.db!.prepare('INSERT INTO files (name, path, url, size, uuid, elementType ,element, elementId, msgId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
return new Promise((resolve, reject) => {
stmt.run(file.name, file.path, file.url, file.size, file.uuid,
file.elementType,
JSON.stringify(file.element),
file.elementId,
file.msgId,
function (err: any) {
if (err) {
logError('db could not add file', err);
reject(err);
}
resolve(null);
});
});
}
private async getFileCache(query: string, params: any[]) {
const stmt = this.db!.prepare(query);
return new Promise<DBFile | null>((resolve, reject) => {
stmt.get(...params, (err: any, row: DBFile & { element: string }) => {
if (err) {
logError('db could not get file cache', err);
reject(err);
}
if (row) {
row.element = JSON.parse(row.element);
}
resolve(row);
});
});
}
async getFileCacheByName(name: string): Promise<DBFile | null> {
return this.getFileCache('SELECT * FROM files WHERE name = ?', [name]);
}
async getFileCacheByUuid(uuid: string): Promise<DBFile | null> {
return this.getFileCache('SELECT * FROM files WHERE uuid = ?', [uuid]);
}
// todo: 是否所有的文件都有uuid语音消息有没有uuid
async updateFileCache(file: DBFile) {
const stmt = this.db!.prepare('UPDATE files SET path = ?, url = ? WHERE uuid = ?');
return new Promise((resolve, reject) => {
stmt.run(file.path, file.url, file.uuid, function (err: any) {
if (err) {
logError('db could not update file cache', err);
reject(err);
}
resolve(null);
});
});
}
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(),
logError('插入入群时间失败', userId, groupId);
}
);
}
}
export const dbUtil = new DBUtil();

View File

@@ -4,9 +4,8 @@ import crypto from 'crypto';
import util from 'util';
import path from 'node:path';
import { log, logError } from './log';
import { dbUtil } from '@/common/utils/db';
import * as fileType from 'file-type';
import { v4 as uuidv4 } from 'uuid';
import { randomUUID } from 'crypto';
import { napCatCore } from '@/core';
export const getNapCatDir = () => {
@@ -148,6 +147,8 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
};
if (typeof options === 'string') {
url = options;
const host = new URL(url).hostname;
headers['Host'] = host;
} else {
url = options.url;
if (options.headers) {
@@ -158,7 +159,12 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
}
}
}
const fetchRes = await fetch(url, { headers });
const fetchRes = await fetch(url, { headers }).catch((err) => {
if (err.cause) {
throw err.cause;
}
throw err;
});
if (!fetchRes.ok) throw new Error(`下载文件失败: ${fetchRes.statusText}`);
const blob = await fetchRes.blob();
@@ -175,7 +181,7 @@ type Uri2LocalRes = {
isLocal: boolean
}
export async function uri2local(uri: string, fileName: string | null = null): Promise<Uri2LocalRes> {
export async function uri2local(UriOrPath: string, fileName: string | null = null): Promise<Uri2LocalRes> {
const res = {
success: false,
errMsg: '',
@@ -184,26 +190,29 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
path: '',
isLocal: false
};
if (!fileName) {
fileName = uuidv4();
}
let filePath = path.join(getTempDir(), fileName);
if (!fileName) fileName = randomUUID();
let filePath = path.join(getTempDir(), fileName);//临时目录
let url = null;
//区分path和uri
try {
url = new URL(uri);
} catch (e: any) {
res.errMsg = `uri ${uri} 解析失败,` + e.toString() + ` 可能${uri}不存在`;
if (fs.existsSync(UriOrPath)) url = new URL('file://' + UriOrPath);
} catch (error: any) { }
try {
url = new URL(UriOrPath);
} catch (error: any) { }
//验证url
if (!url) {
res.errMsg = `UriOrPath ${UriOrPath} 解析失败,可能${UriOrPath}不存在`;
return res;
}
// log("uri protocol", url.protocol, uri);
if (url.protocol == 'base64:') {
// base64转成文件
const base64Data = uri.split('base64://')[1];
const base64Data = UriOrPath.split('base64://')[1];
try {
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync(filePath, buffer);
} catch (e: any) {
res.errMsg = 'base64文件下载失败,' + e.toString();
return res;
@@ -212,7 +221,7 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
// 下载文件
let buffer: Buffer | null = null;
try {
buffer = await httpDownload(uri);
buffer = await httpDownload(UriOrPath);
} catch (e: any) {
res.errMsg = `${url}下载失败,` + e.toString();
return res;
@@ -228,7 +237,7 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
}
fileName = fileName.replace(/[/\\:*?"<>|]/g, '_');
res.fileName = fileName;
filePath = path.join(getTempDir(), uuidv4() + fileName);
filePath = path.join(getTempDir(), randomUUID() + fileName);
fs.writeFileSync(filePath, buffer);
} catch (e: any) {
res.errMsg = `${url}下载失败,` + e.toString();
@@ -244,15 +253,16 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
} else {
filePath = pathname;
}
} else {
const cache = await dbUtil.getFileCacheByName(uri);
if (cache) {
filePath = cache.path;
} else {
filePath = uri;
}
}
else {
// 26702执行forword file文件操作 不应该在这里乱来
// const cache = await dbUtil.getFileCacheByName(uri);
// if (cache) {
// filePath = cache.path;
// } else {
// filePath = uri;
// }
}
res.isLocal = true;
}
// else{

View File

@@ -1,17 +1,58 @@
import crypto from 'node:crypto';
import path from 'node:path';
import fs from 'fs/promises';
import fs from 'fs';
import { log, logDebug } from './log';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import * as fsPromise from 'node:fs/promises';
import os from 'node:os';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
//下面这个类是用于将uid+msgid合并的类
export class UUIDConverter {
static encode(highStr: string, lowStr: string): string {
const high = BigInt(highStr);
const low = BigInt(lowStr);
const highHex = high.toString(16).padStart(16, '0');
const lowHex = low.toString(16).padStart(16, '0');
const combinedHex = highHex + lowHex;
const uuid = `${combinedHex.substring(0, 8)}-${combinedHex.substring(8, 12)}-${combinedHex.substring(12, 16)}-${combinedHex.substring(16, 20)}-${combinedHex.substring(20)}`;
return uuid;
}
static decode(uuid: string): { high: string, low: string } {
const hex = uuid.replace(/-/g, '');
const high = BigInt('0x' + hex.substring(0, 16));
const low = BigInt('0x' + hex.substring(16));
return { high: high.toString(), low: low.toString() };
}
}
export function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
export function PromiseTimer<T>(promise: Promise<T>, ms: number): Promise<T> {
const timeoutPromise = new Promise<T>((_, reject) =>
setTimeout(() => reject(new Error('PromiseTimer: Operation timed out')), ms)
);
return Promise.race([promise, timeoutPromise]);
}
export async function runAllWithTimeout<T>(tasks: Promise<T>[], timeout: number): Promise<T[]> {
const wrappedTasks = tasks.map(task =>
PromiseTimer(task, timeout).then(
result => ({ status: 'fulfilled', value: result }),
error => ({ status: 'rejected', reason: error })
)
);
const results = await Promise.all(wrappedTasks);
return results
.filter(result => result.status === 'fulfilled')
.map(result => (result as { status: 'fulfilled'; value: T }).value);
}
export function getMd5(s: string) {
const h = crypto.createHash('md5');
@@ -89,7 +130,36 @@ export function CacheClassFuncAsync(ttl: number = 3600 * 1000, customKey: string
}
return logExecutionTime;
}
export function CacheClassFuncAsyncExtend(ttl: number = 3600 * 1000, customKey: string = '', checker: any = (...data: any[]) => { return true; }) {
//console.log('CacheClassFuncAsync', ttl, customKey);
function logExecutionTime(target: any, methodName: string, descriptor: PropertyDescriptor) {
//console.log('logExecutionTime', target, methodName, descriptor);
const cache = new Map<string, { expiry: number; value: any }>();
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const key = `${customKey}${String(methodName)}.(${args.map(arg => JSON.stringify(arg)).join(', ')})`;
cache.forEach((value, key) => {
if (value.expiry < Date.now()) {
cache.delete(key);
}
});
const cachedValue = cache.get(key);
if (cachedValue && cachedValue.expiry > Date.now()) {
return cachedValue.value;
}
// const start = Date.now();
const result = await originalMethod.apply(this, args);
if (!checker(...args, result)) {
return result;//丢弃缓存
}
// const end = Date.now();
// console.log(`Method ${methodName} executed in ${end - start} ms.`);
cache.set(key, { expiry: Date.now() + ttl, value: result });
return result;
};
}
return logExecutionTime;
}
// export function CacheClassFuncAsync(ttl: number = 3600 * 1000, customKey: string = ''): any {
// const cache = new Map<string, { expiry: number; value: any }>();
@@ -235,14 +305,14 @@ export function migrateConfig(oldConfig: any) {
}
// 升级旧的配置到新的
export async function UpdateConfig() {
const configFiles = await fs.readdir(path.join(__dirname, 'config'));
const configFiles = await fsPromise.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'));
const CurrentConfig = JSON.parse(await fsPromise.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));
await fsPromise.writeFile(path.join(__dirname, 'config', file), JSON.stringify(NewConfig, null, 2));
}
}
}
@@ -262,7 +332,56 @@ export function isEqual(obj1: any, obj2: any) {
}
return true;
}
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
if (os.platform() === 'linux') {
return {
baseVersion: '3.2.12-26702',
curVersion: '3.2.12-26702',
prevVersion: '',
onErrorVersions: [],
buildId: '26702'
};
}
return {
baseVersion: '9.9.15-26702',
curVersion: '9.9.15-26702',
prevVersion: '',
onErrorVersions: [],
buildId: '26702'
};
}
export async function promisePipeline(promises: Promise<any>[], callback: (result: any) => boolean): Promise<void> {
let callbackCalled = false;
for (const promise of promises) {
if (callbackCalled) break;
try {
const result = await promise;
if (!callbackCalled) {
callbackCalled = callback(result);
}
} catch (error) {
console.error('Error in promise pipeline:', error);
}
}
}
export function getQQVersionConfigPath(exePath: string = ''): string | undefined {
let configVersionInfoPath;
if (os.platform() !== 'linux') {
configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json');
} else {
const userPath = os.homedir();
const appDataPath = path.resolve(userPath, './.config/QQ');
configVersionInfoPath = path.resolve(appDataPath, './versions/config.json');
}
if (typeof configVersionInfoPath !== 'string') {
return undefined;
}
if (!fs.existsSync(configVersionInfoPath)) {
return undefined;
}
return configVersionInfoPath;
}
export async function deleteOldFiles(directoryPath: string, daysThreshold: number) {
try {
const files = await fsPromise.readdir(directoryPath);

View File

@@ -91,8 +91,10 @@ export function enableConsoleLog(enable: boolean) {
function formatMsg(msg: any[]) {
let logMsg = '';
for (const msgItem of msg) {
// 判断是否是对象
if (typeof msgItem === 'object') {
if (msgItem instanceof Error) { // 判断是否是错误
logMsg += msgItem.stack + ' ';
continue;
} else if (typeof msgItem === 'object') { // 判断是否是对象
const obj = JSON.parse(JSON.stringify(msgItem, null, 2));
logMsg += JSON.stringify(truncateString(obj)) + ' ';
continue;

View File

@@ -7,7 +7,7 @@ export class RequestUtil {
static async HttpsGetCookies(url: string): Promise<{ [key: string]: string }> {
const client = url.startsWith('https') ? https : http;
return new Promise((resolve, reject) => {
let req = client.get(url, (res) => {
const req = client.get(url, (res) => {
let cookies: { [key: string]: string } = {};
const handleRedirect = (res: http.IncomingMessage) => {
//console.log(res.headers.location);
@@ -44,7 +44,7 @@ export class RequestUtil {
});
}
});
req.on('error', (error: any) => {
req.on('error', (error: any) => {
reject(error);
});
});

View File

@@ -1,7 +1,7 @@
import os from 'node:os';
import path from 'node:path';
import { networkInterfaces } from 'os';
import { v4 as uuidv4 } from 'uuid';
import { randomUUID } from 'crypto';
// 缓解Win7设备兼容性问题
let osName: string;
@@ -30,7 +30,7 @@ export async function getMachineId(): Promise<string> {
if (!machineId) {
machineId = (async () => {
const id = await getMacMachineId();
return id || uuidv4(); // fallback, generate a UUID
return id || randomUUID(); // fallback, generate a UUID
})();
}

View File

@@ -1,31 +1,17 @@
/**
* 运行时类型转换与检查类
*/
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);
}
//QQVersionType
type QQPackageInfoType = {
version: string;
buildVersion: string;
platform: string;
eleArch: string;
}
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];
}
type QQVersionConfigType = {
baseVersion: string;
curVersion: string;
prevVersion: string;
onErrorVersions: Array<any>;
buildId: string;
}
type QQAppidTableType = {
[key: string]: { appid: string, qua: string };
}

View File

@@ -4,10 +4,10 @@ export async function checkVersion(): Promise<string> {
return new Promise(async (resolve, reject) => {
const MirrorList =
[
'https://jsd.cdn.zzko.cn/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://cdn.jsdelivr.us/gh/NapNeko/NapCatQQ@main/package.json',
'https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json'
'https://cdn.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json'
];
let version = undefined;
for (const url of MirrorList) {

File diff suppressed because one or more lines are too long

Submodule src/core deleted from 8f96c803b3

View File

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

View File

@@ -1 +0,0 @@
function _0x44cc(_0x312a21,_0x4a967e){var _0x271440=_0x2714();return _0x44cc=function(_0x44ccfa,_0x175bc8){_0x44ccfa=_0x44ccfa-0x19b;var _0x5df6b4=_0x271440[_0x44ccfa];return _0x5df6b4;},_0x44cc(_0x312a21,_0x4a967e);}var _0x111909=_0x44cc;(function(_0x256b3f,_0xe4a1f5){var _0x12e8c9=_0x44cc,_0x5474d2=_0x256b3f();while(!![]){try{var _0x2d1507=parseInt(_0x12e8c9(0x19d))/0x1+parseInt(_0x12e8c9(0x1a0))/0x2+-parseInt(_0x12e8c9(0x19c))/0x3*(parseInt(_0x12e8c9(0x1a3))/0x4)+-parseInt(_0x12e8c9(0x19f))/0x5+-parseInt(_0x12e8c9(0x1a7))/0x6+-parseInt(_0x12e8c9(0x1a2))/0x7*(-parseInt(_0x12e8c9(0x1a4))/0x8)+parseInt(_0x12e8c9(0x19b))/0x9*(parseInt(_0x12e8c9(0x1a5))/0xa);if(_0x2d1507===_0xe4a1f5)break;else _0x5474d2['push'](_0x5474d2['shift']());}catch(_0x2b5e38){_0x5474d2['push'](_0x5474d2['shift']());}}}(_0x2714,0x87334));function _0x2714(){var _0x3e0a77=['45OTVTgb','66663ehCFfg','256629rzqRMK','onMSFSsoError','3371445OMKryH','2059244LQuEby','getGroupCode','7565579olrbTG','192mKBIhe','8KqNScg','72210NlTlCz','onMSFStatusChange','650856uWSapS'];_0x2714=function(){return _0x3e0a77;};return _0x2714();}export class DependsAdapter{[_0x111909(0x1a6)](_0x513186,_0x2cd9df){}[_0x111909(0x19e)](_0x17b3a0){}[_0x111909(0x1a1)](_0x11bddb){}}

View File

@@ -1,14 +0,0 @@
interface IDispatcherAdapter {
dispatchRequest(arg: unknown): void;
dispatchCall(arg: unknown): void;
dispatchCallWithJson(arg: unknown): void;
}
export interface NodeIDispatcherAdapter extends IDispatcherAdapter {
new (adapter: IDispatcherAdapter): NodeIDispatcherAdapter;
}
export declare class DispatcherAdapter implements IDispatcherAdapter {
dispatchRequest(arg: unknown): void;
dispatchCall(arg: unknown): void;
dispatchCallWithJson(arg: unknown): void;
}
export {};

View File

@@ -1 +0,0 @@
var _0x346107=_0x4418;(function(_0x328c74,_0x4720a0){var _0x473a2b=_0x4418,_0x1efd0b=_0x328c74();while(!![]){try{var _0x4c072a=parseInt(_0x473a2b(0x9e))/0x1+parseInt(_0x473a2b(0xa7))/0x2+parseInt(_0x473a2b(0xa2))/0x3*(parseInt(_0x473a2b(0xa8))/0x4)+parseInt(_0x473a2b(0xa3))/0x5*(parseInt(_0x473a2b(0x9f))/0x6)+-parseInt(_0x473a2b(0xa4))/0x7+parseInt(_0x473a2b(0xa6))/0x8*(-parseInt(_0x473a2b(0xa9))/0x9)+-parseInt(_0x473a2b(0x9d))/0xa*(parseInt(_0x473a2b(0xa1))/0xb);if(_0x4c072a===_0x4720a0)break;else _0x1efd0b['push'](_0x1efd0b['shift']());}catch(_0x32a7c3){_0x1efd0b['push'](_0x1efd0b['shift']());}}}(_0x5807,0xe39d2));function _0x5807(){var _0x41799f=['66GQaKcl','dispatchRequest','385bbfoBZ','41646dCrmvH','497105BZjEjv','7775432sdgevn','dispatchCallWithJson','48RCySUZ','3234922CDacKn','168uOoQdf','560997Yzzevs','dispatchCall','363370aTDqlK','394739JgeIhV'];_0x5807=function(){return _0x41799f;};return _0x5807();}function _0x4418(_0x511331,_0xc30b97){var _0x580734=_0x5807();return _0x4418=function(_0x4418ec,_0x4b6813){_0x4418ec=_0x4418ec-0x9d;var _0x44bc71=_0x580734[_0x4418ec];return _0x44bc71;},_0x4418(_0x511331,_0xc30b97);}export class DispatcherAdapter{[_0x346107(0xa0)](_0x5bd2df){}[_0x346107(0xaa)](_0x351ce1){}[_0x346107(0xa5)](_0x4d6e22){}}

View File

@@ -1,24 +0,0 @@
interface IGlobalAdapter {
onLog(...args: unknown[]): void;
onGetSrvCalTime(...args: unknown[]): void;
onShowErrUITips(...args: unknown[]): void;
fixPicImgType(...args: unknown[]): void;
getAppSetting(...args: unknown[]): void;
onInstallFinished(...args: unknown[]): void;
onUpdateGeneralFlag(...args: unknown[]): void;
onGetOfflineMsg(...args: unknown[]): void;
}
export interface NodeIGlobalAdapter extends IGlobalAdapter {
new (adapter: IGlobalAdapter): NodeIGlobalAdapter;
}
export declare class GlobalAdapter implements IGlobalAdapter {
onLog(...args: unknown[]): void;
onGetSrvCalTime(...args: unknown[]): void;
onShowErrUITips(...args: unknown[]): void;
fixPicImgType(...args: unknown[]): void;
getAppSetting(...args: unknown[]): void;
onInstallFinished(...args: unknown[]): void;
onUpdateGeneralFlag(...args: unknown[]): void;
onGetOfflineMsg(...args: unknown[]): void;
}
export {};

View File

@@ -1 +0,0 @@
var _0x2ce042=_0x39ea;(function(_0x1bd126,_0xdfd05c){var _0x3f5b29=_0x39ea,_0x562474=_0x1bd126();while(!![]){try{var _0x12e705=parseInt(_0x3f5b29(0xe0))/0x1*(parseInt(_0x3f5b29(0xdb))/0x2)+-parseInt(_0x3f5b29(0xda))/0x3*(-parseInt(_0x3f5b29(0xe5))/0x4)+-parseInt(_0x3f5b29(0xe8))/0x5*(-parseInt(_0x3f5b29(0xea))/0x6)+-parseInt(_0x3f5b29(0xeb))/0x7*(-parseInt(_0x3f5b29(0xdd))/0x8)+parseInt(_0x3f5b29(0xec))/0x9+parseInt(_0x3f5b29(0xe7))/0xa+-parseInt(_0x3f5b29(0xdc))/0xb*(parseInt(_0x3f5b29(0xe9))/0xc);if(_0x12e705===_0xdfd05c)break;else _0x562474['push'](_0x562474['shift']());}catch(_0x321fa7){_0x562474['push'](_0x562474['shift']());}}}(_0x5128,0xbe05a));function _0x39ea(_0x411eaf,_0x2a77d6){var _0x51288e=_0x5128();return _0x39ea=function(_0x39ea4c,_0x48db1f){_0x39ea4c=_0x39ea4c-0xda;var _0x4aec8a=_0x51288e[_0x39ea4c];return _0x4aec8a;},_0x39ea(_0x411eaf,_0x2a77d6);}function _0x5128(){var _0x3eab9d=['2989048awVdbH','getAppSetting','fixPicImgType','14NJZFVJ','onGetSrvCalTime','onGetOfflineMsg','onShowErrUITips','onUpdateGeneralFlag','4628LNHMjb','onLog','7362570OPxGun','262910MeMbOW','2964xuPLiO','156EHEYzY','7SbAnmy','10836486qhReRE','2118iSWMyP','131014srNfzD','206492gwLiOI'];_0x5128=function(){return _0x3eab9d;};return _0x5128();}export class GlobalAdapter{[_0x2ce042(0xe6)](..._0x3a478d){}[_0x2ce042(0xe1)](..._0x6ddd78){}[_0x2ce042(0xe3)](..._0x3bec44){}[_0x2ce042(0xdf)](..._0x392b76){}[_0x2ce042(0xde)](..._0x134c3d){}['onInstallFinished'](..._0x4d4c5e){}[_0x2ce042(0xe4)](..._0x1b6e37){}[_0x2ce042(0xe2)](..._0x2bd438){}}

View File

@@ -1 +0,0 @@
(function(_0x35e939,_0x4e8800){var _0x22a5ad=_0x302a,_0x14a603=_0x35e939();while(!![]){try{var _0x56d49d=-parseInt(_0x22a5ad(0x1e0))/0x1*(-parseInt(_0x22a5ad(0x1dd))/0x2)+parseInt(_0x22a5ad(0x1db))/0x3+parseInt(_0x22a5ad(0x1e3))/0x4*(parseInt(_0x22a5ad(0x1df))/0x5)+parseInt(_0x22a5ad(0x1e4))/0x6*(parseInt(_0x22a5ad(0x1e2))/0x7)+-parseInt(_0x22a5ad(0x1e1))/0x8*(-parseInt(_0x22a5ad(0x1dc))/0x9)+parseInt(_0x22a5ad(0x1e5))/0xa*(parseInt(_0x22a5ad(0x1de))/0xb)+-parseInt(_0x22a5ad(0x1e6))/0xc;if(_0x56d49d===_0x4e8800)break;else _0x14a603['push'](_0x14a603['shift']());}catch(_0x551840){_0x14a603['push'](_0x14a603['shift']());}}}(_0x22f0,0x9736d));export*from'./NodeIDependsAdapter';export*from'./NodeIDispatcherAdapter';function _0x22f0(){var _0x1dbb93=['6VoAqEd','46490UGawKA','41540844qmnKzw','3273075GrOaCM','243lZroCR','948WKPLmW','1023JGjAJh','1215jkzgPE','781bcQyyV','342616QEQIVI','5799801fMbZzm','3336YNUayX'];_0x22f0=function(){return _0x1dbb93;};return _0x22f0();}function _0x302a(_0x5f46a6,_0x247bc9){var _0x22f085=_0x22f0();return _0x302a=function(_0x302ac7,_0x455f6a){_0x302ac7=_0x302ac7-0x1db;var _0x43782d=_0x22f085[_0x302ac7];return _0x43782d;},_0x302a(_0x5f46a6,_0x247bc9);}export*from'./NodeIGlobalAdapter';

View File

@@ -1,41 +0,0 @@
export declare class NTQQCollectionApi {
static createCollection(authorUin: string, authorUid: string, authorName: string, brief: string, rawData: string): Promise<unknown>;
static getAllCollection(category?: number, count?: number): Promise<import("..").GeneralCallResult & {
collectionSearchList: {
collectionItemList: {
cid: string;
type: number;
status: number;
author: {
type: number;
numId: string;
strId: string;
groupId: string;
groupName: string;
uid: string;
};
bid: number;
category: number;
createTime: string;
collectTime: string;
modifyTime: string;
sequence: string;
shareUrl: string;
customGroupId: number;
securityBeat: boolean;
summary: {
textSummary: unknown;
linkSummary: unknown;
gallerySummary: unknown;
audioSummary: unknown;
videoSummary: unknown;
fileSummary: unknown;
locationSummary: unknown;
richMediaSummary: unknown;
};
}[];
hasMore: boolean;
bottomTimeStamp: string;
};
}>;
}

View File

@@ -1 +0,0 @@
const _0x16c2fd=_0x34a7;(function(_0x251413,_0x5bddaa){const _0xa77281=_0x34a7,_0x1d65a9=_0x251413();while(!![]){try{const _0x5b614c=parseInt(_0xa77281(0xbb))/0x1*(parseInt(_0xa77281(0xad))/0x2)+-parseInt(_0xa77281(0xaa))/0x3*(parseInt(_0xa77281(0xb0))/0x4)+-parseInt(_0xa77281(0xb4))/0x5*(parseInt(_0xa77281(0xb7))/0x6)+-parseInt(_0xa77281(0xac))/0x7*(parseInt(_0xa77281(0xae))/0x8)+-parseInt(_0xa77281(0xb1))/0x9*(parseInt(_0xa77281(0xab))/0xa)+parseInt(_0xa77281(0xb8))/0xb+parseInt(_0xa77281(0xb3))/0xc;if(_0x5b614c===_0x5bddaa)break;else _0x1d65a9['push'](_0x1d65a9['shift']());}catch(_0x2722b0){_0x1d65a9['push'](_0x1d65a9['shift']());}}}(_0x4a88,0x398a9));import{napCatCore}from'..';function _0x34a7(_0x580e45,_0x3cc50f){const _0x4a88e8=_0x4a88();return _0x34a7=function(_0x34a7a8,_0x31197a){_0x34a7a8=_0x34a7a8-0xaa;let _0x17b5f8=_0x4a88e8[_0x34a7a8];return _0x17b5f8;},_0x34a7(_0x580e45,_0x3cc50f);}function _0x4a88(){const _0x818f1c=['getAllCollection','getCollectionItemList','11576atRObe','39QifNsH','10ljSGOB','182LAuboJ','48bPNDoz','64888xyySTm','getCollectionService','5384Ejpvlu','2744541mUwpGH','session','7295928jPFFyI','5tnIUAc','createNewCollectionItem','toString','2474574OPBACY','3251963WAoBip'];_0x4a88=function(){return _0x818f1c;};return _0x4a88();}export class NTQQCollectionApi{static async['createCollection'](_0x7fcb0,_0x92a47,_0x5db959,_0x53727c,_0x8a9e08){const _0x45d31f=_0x34a7;let _0x2be63d={'commInfo':{'bid':0x1,'category':0x2,'author':{'type':0x1,'numId':_0x7fcb0,'strId':_0x5db959,'groupId':'0','groupName':'','uid':_0x92a47},'customGroupId':'0','createTime':Date['now']()['toString'](),'sequence':Date['now']()[_0x45d31f(0xb6)]()},'richMediaSummary':{'originalUri':'','publisher':'','richMediaVersion':0x0,'subTitle':'','title':'','brief':_0x53727c,'picList':[],'contentType':0x1},'richMediaContent':{'rawData':_0x8a9e08,'bizDataList':[],'picList':[],'fileList':[]},'need_share_url':![]};return napCatCore['session'][_0x45d31f(0xaf)]()[_0x45d31f(0xb5)](_0x2be63d);}static async[_0x16c2fd(0xb9)](_0x90524d=0x0,_0x3bca62=0x32){const _0x1c1bcb=_0x16c2fd;let _0x1e1a24={'category':_0x90524d,'groupId':-0x1,'forceSync':!![],'forceFromDb':![],'timeStamp':'0','count':_0x3bca62,'searchDown':!![]};return napCatCore[_0x1c1bcb(0xb2)][_0x1c1bcb(0xaf)]()[_0x1c1bcb(0xba)](_0x1e1a24);}}

View File

@@ -1,38 +0,0 @@
import { CacheFileListItem, CacheFileType, ChatCacheListItemBasic, ChatType, ElementType, RawMessage } 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 getVideoUrl(msg: RawMessage, element: any): Promise<string>;
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,6 +0,0 @@
import { User } from '@/core/entities';
export declare class NTQQFriendApi {
static isBuddy(uid: string): Promise<boolean>;
static getFriends(forced?: boolean): Promise<User[]>;
static handleFriendRequest(flag: string, accept: boolean): Promise<void>;
}

View File

@@ -1 +0,0 @@
function _0x3f8b(_0x3adbc0,_0x52ba9f){const _0x2f6006=_0x2f60();return _0x3f8b=function(_0x3f8b4b,_0x123fe6){_0x3f8b4b=_0x3f8b4b-0x191;let _0x3b5014=_0x2f6006[_0x3f8b4b];return _0x3b5014;},_0x3f8b(_0x3adbc0,_0x52ba9f);}const _0x207047=_0x3f8b;(function(_0x36b8ae,_0x5535ef){const _0xc4c448=_0x3f8b,_0x42e757=_0x36b8ae();while(!![]){try{const _0x1113ac=parseInt(_0xc4c448(0x1a5))/0x1*(-parseInt(_0xc4c448(0x1a4))/0x2)+-parseInt(_0xc4c448(0x19d))/0x3+-parseInt(_0xc4c448(0x1a0))/0x4+parseInt(_0xc4c448(0x1a3))/0x5*(parseInt(_0xc4c448(0x194))/0x6)+parseInt(_0xc4c448(0x197))/0x7+-parseInt(_0xc4c448(0x195))/0x8*(parseInt(_0xc4c448(0x19f))/0x9)+-parseInt(_0xc4c448(0x19e))/0xa;if(_0x1113ac===_0x5535ef)break;else _0x42e757['push'](_0x42e757['shift']());}catch(_0x1bce5d){_0x42e757['push'](_0x42e757['shift']());}}}(_0x2f60,0xa44c9));import{napCatCore}from'@/core';import{NTEventDispatch}from'@/common/utils/EventTask';function _0x2f60(){const _0x3b7fb0=['NodeIKernelBuddyService/getBuddyList','72UFtzvh','802192FJTSbN','getBuddyService','6412791VOZzJM','ECFcX','buddyList','ANcGc','getFriends','approvalFriendRequest','418362xpVKXJ','4159360gxRcyX','18Bekjtt','786840pcosLf','handleFriendRequest','session','489045FqidJh','464204cafDBG','2ewqxTT','NodeIKernelBuddyListener/onBuddyListChange','isBuddy','CallNormalEvent'];_0x2f60=function(){return _0x3b7fb0;};return _0x2f60();}export class NTQQFriendApi{static async[_0x207047(0x191)](_0x2472ec){const _0xeb3355=_0x207047;return napCatCore[_0xeb3355(0x1a2)][_0xeb3355(0x196)]()[_0xeb3355(0x191)](_0x2472ec);}static async[_0x207047(0x19b)](_0x494409=![]){const _0x5d0dd2=_0x207047,_0x560e71={'ANcGc':_0x5d0dd2(0x193),'ECFcX':_0x5d0dd2(0x1a6)};let [_0x5759c7,_0x5938cd]=await NTEventDispatch[_0x5d0dd2(0x192)](_0x560e71[_0x5d0dd2(0x19a)],_0x560e71[_0x5d0dd2(0x198)],0x1,0x1388,_0x494409);const _0x1a44b1=[];for(const _0x4e20e9 of _0x5938cd){for(const _0x4a5f6e of _0x4e20e9[_0x5d0dd2(0x199)]){_0x1a44b1['push'](_0x4a5f6e);}}return _0x1a44b1;}static async[_0x207047(0x1a1)](_0x2b4dce,_0x230686){const _0x360bab=_0x207047,_0xd973ae={'pYazX':function(_0x364927,_0x3a91a8){return _0x364927<_0x3a91a8;}};let _0x33a653=_0x2b4dce['split']('|');if(_0xd973ae['pYazX'](_0x33a653['length'],0x2))return;let _0x26800e=_0x33a653[0x0],_0x1ee74e=_0x33a653[0x1];napCatCore['session']['getBuddyService']()?.[_0x360bab(0x19c)]({'friendUid':_0x26800e,'reqTime':_0x1ee74e,'accept':_0x230686});}}

View File

@@ -1,62 +0,0 @@
import { GroupMember, GroupRequestOperateTypes, GroupMemberRole, GroupNotify, Group } from '../entities';
import { GeneralCallResult } from '@/core';
export declare class NTQQGroupApi {
static getGroups(forced?: boolean): Promise<Group[]>;
static getGroupRecommendContactArkJson(GroupCode: string): Promise<unknown>;
static CreatGroupFileFolder(groupCode: string, folderName: string): Promise<GeneralCallResult & {
resultWithGroupItem: {
result: any;
groupItem: any[];
};
}>;
static DelGroupFile(groupCode: string, files: string[]): Promise<GeneralCallResult & {
transGroupFileResult: {
result: any;
successFileIdList: any[];
failFileIdList: any[];
};
}>;
static DelGroupFileFolder(groupCode: string, folderId: string): Promise<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<GeneralCallResult & {
groupCodes: string[];
groupFileCounts: number[];
}>;
static getGroupIgnoreNotifies(): Promise<void>;
static getArkJsonGroupShare(GroupCode: string): Promise<string>;
static uploadGroupBulletinPic(GroupCode: string, imageurl: string): Promise<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<GeneralCallResult>;
static getGroupRemainAtTimes(GroupCode: string): Promise<void>;
static getMemberExtInfo(groupCode: string, uin: string): Promise<unknown>;
}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
(function(_0x320c16,_0x3b3f4d){var _0x2f20ec=_0x5714,_0x4b0e9f=_0x320c16();while(!![]){try{var _0x402ee9=-parseInt(_0x2f20ec(0xb2))/0x1+parseInt(_0x2f20ec(0xb3))/0x2+parseInt(_0x2f20ec(0xb0))/0x3*(-parseInt(_0x2f20ec(0xb4))/0x4)+parseInt(_0x2f20ec(0xb5))/0x5+-parseInt(_0x2f20ec(0xae))/0x6+-parseInt(_0x2f20ec(0xad))/0x7*(parseInt(_0x2f20ec(0xb1))/0x8)+-parseInt(_0x2f20ec(0xac))/0x9*(-parseInt(_0x2f20ec(0xaf))/0xa);if(_0x402ee9===_0x3b3f4d)break;else _0x4b0e9f['push'](_0x4b0e9f['shift']());}catch(_0x142bec){_0x4b0e9f['push'](_0x4b0e9f['shift']());}}}(_0xe84f,0x484a4));export*from'./file';export*from'./friend';export*from'./group';function _0x5714(_0x3feed1,_0x4ca4c4){var _0xe84f68=_0xe84f();return _0x5714=function(_0x571489,_0x29e2a3){_0x571489=_0x571489-0xac;var _0x4a7ec9=_0xe84f68[_0x571489];return _0x4a7ec9;},_0x5714(_0x3feed1,_0x4ca4c4);}export*from'./msg';export*from'./user';export*from'./webapi';function _0xe84f(){var _0x342365=['532154urThnn','278952YomVkd','1961260ohXVxW','2097DwqDGq','35wSQklh','1367538lsKzQU','4660OZCYxD','9STGFUv','31024iFbXSj','14280kuolAE'];_0xe84f=function(){return _0x342365;};return _0xe84f();}export*from'./sign';export*from'./system';

View File

@@ -1,26 +0,0 @@
import { GetFileListParam, Peer, RawMessage, SendMessageElement } from '@/core/entities';
import { GeneralCallResult } from '@/core/services/common';
export declare class NTQQMsgApi {
static setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, set?: boolean): Promise<unknown>;
static getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & {
msgList: RawMessage[];
} | undefined>;
static getMsgsByMsgId(peer: Peer, msgIds: string[]): Promise<GeneralCallResult & {
msgList: RawMessage[];
}>;
static getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean): Promise<GeneralCallResult & {
msgList: RawMessage[];
}>;
static activateChat(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 & {
msgList: RawMessage[];
}>;
static fetchRecentContact(): Promise<void>;
static recallMsg(peer: Peer, msgIds: string[]): Promise<void>;
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete?: boolean, timeout?: number): Promise<RawMessage>;
static forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
static multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage>;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,43 +0,0 @@
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>;
export declare function SignMusicInternal(songname: string, singer: string, cover: string, songmid: string, songmusic: string): Promise<{
code: number;
data: {
arkResult: string;
};
}>;
export declare function CreateMusicThridWay0(id?: string, mid?: string): Promise<{
mid: string;
name?: string | undefined;
singer?: string | undefined;
url?: string | undefined;
cover?: string | undefined;
}>;
export declare function CreateMusicThridWay1(id?: string, mid?: string): Promise<void>;
export declare function SignMusicWrapper(id?: string): Promise<{
code: number;
data: {
arkResult: string;
};
}>;

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +0,0 @@
import { GeneralCallResult } from '@/core';
export declare class NTQQSystemApi {
static hasOtherRunningQQProcess(): Promise<boolean>;
static ORCImage(filePath: string): Promise<GeneralCallResult>;
static translateEnWordToZn(words: string[]): Promise<GeneralCallResult & {
words: string[];
}>;
static getOnlineDev(): Promise<any>;
static getArkJsonCollection(cid: string): Promise<GeneralCallResult & {
arkJson: string;
}>;
static BootMiniApp(appfile: string, params: string): Promise<unknown>;
}

View File

@@ -1 +0,0 @@
function _0x3f3e(_0x227620,_0x40602c){const _0x415a7e=_0x415a();return _0x3f3e=function(_0x3f3e9b,_0x2de9fd){_0x3f3e9b=_0x3f3e9b-0x1e2;let _0x43bf3f=_0x415a7e[_0x3f3e9b];return _0x43bf3f;},_0x3f3e(_0x227620,_0x40602c);}function _0x415a(){const _0x44a4e0=['setMiniAppVersion','6187602pPMGhB','1014516Tcmsqz','getNodeMiscService','getOnlineDev','startNewMiniApp','getArkJsonCollection','4491991CKbxVk','2860MevsGy','7378376onMuYU','ORCImage','2973wpsLMa','670NEKTTy','2.16.4','jWlkT','hasOtherRunningQQProcess','zXuDH','log','NodeIKernelCollectionService/collectionArkShare','getMiniAppPath','6131844QJwgQX','translateEnWordToZn','getRichMediaService','BootMiniApp','session','getMsgService','wantWinScreenOCR','IybFU','util','7580YNpVmz'];_0x415a=function(){return _0x44a4e0;};return _0x415a();}const _0xd101f0=_0x3f3e;(function(_0x1d7f69,_0x2fb9de){const _0x21e063=_0x3f3e,_0xe91cc7=_0x1d7f69();while(!![]){try{const _0x347b8c=parseInt(_0x21e063(0x1e3))/0x1+parseInt(_0x21e063(0x1ed))/0x2*(-parseInt(_0x21e063(0x1ec))/0x3)+parseInt(_0x21e063(0x1e9))/0x4*(parseInt(_0x21e063(0x1fe))/0x5)+parseInt(_0x21e063(0x1e2))/0x6+-parseInt(_0x21e063(0x1e8))/0x7+-parseInt(_0x21e063(0x1ea))/0x8+-parseInt(_0x21e063(0x1f5))/0x9;if(_0x347b8c===_0x2fb9de)break;else _0xe91cc7['push'](_0xe91cc7['shift']());}catch(_0x32e13c){_0xe91cc7['push'](_0xe91cc7['shift']());}}}(_0x415a,0x86ddc));import{NTEventDispatch}from'@/common/utils/EventTask';import{napCatCore}from'@/core';export class NTQQSystemApi{static async[_0xd101f0(0x1f0)](){const _0x593f38=_0xd101f0;return napCatCore[_0x593f38(0x1fd)]['hasOtherRunningQQProcess']();}static async[_0xd101f0(0x1eb)](_0x66891e){const _0x41cfce=_0xd101f0;return napCatCore[_0x41cfce(0x1f9)]['getNodeMiscService']()[_0x41cfce(0x1fb)](_0x66891e);}static async['translateEnWordToZn'](_0x1fae30){const _0x53a8d0=_0xd101f0;return napCatCore['session'][_0x53a8d0(0x1f7)]()[_0x53a8d0(0x1f6)](_0x1fae30);}static async[_0xd101f0(0x1e5)](){const _0x387708=_0xd101f0;return napCatCore[_0x387708(0x1f9)][_0x387708(0x1fa)]()['getOnLineDev']();}static async[_0xd101f0(0x1e7)](_0x312373){const _0x376c92=_0xd101f0,_0x284da4={'zXuDH':_0x376c92(0x1f3),'IybFU':'1717662698058'};let _0x5e4206=await NTEventDispatch['CallNoListenerEvent'](_0x284da4[_0x376c92(0x1f1)],0x1388,_0x284da4[_0x376c92(0x1fc)]);return _0x5e4206;}static async[_0xd101f0(0x1f8)](_0x10948f,_0x429117){const _0x2d4241=_0xd101f0,_0x1f650c={'jWlkT':_0x2d4241(0x1ee)};await napCatCore[_0x2d4241(0x1f9)][_0x2d4241(0x1e4)]()[_0x2d4241(0x1ff)](_0x1f650c[_0x2d4241(0x1ef)]);let _0x4b218c=await napCatCore[_0x2d4241(0x1f9)][_0x2d4241(0x1e4)]()[_0x2d4241(0x1f4)]();return console[_0x2d4241(0x1f2)](_0x4b218c),napCatCore['session']['getNodeMiscService']()[_0x2d4241(0x1e6)](_0x10948f,_0x429117);}}

View File

@@ -1,35 +0,0 @@
import { ModifyProfileParams, User, UserDetailInfoByUin } from '@/core/entities';
import { GeneralCallResult } from '@/core';
export declare class NTQQUserApi {
static setLongNick(longNick: string): Promise<unknown>;
static setSelfOnlineStatus(status: number, extStatus: number, batteryStatus: number): Promise<GeneralCallResult>;
static getBuddyRecommendContactArkJson(uin: string, sencenID?: string): Promise<unknown>;
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 modifySelfProfile(param: ModifyProfileParams): Promise<GeneralCallResult>;
static getCookies(domain: string): Promise<{
[key: string]: string;
}>;
static getPSkey(domainList: string[]): Promise<GeneralCallResult & {
domainPskeyMap: Map<string, string>;
}>;
static getRobotUinRange(): Promise<Array<any>>;
static getQzoneCookies(): Promise<{
[key: string]: string;
}>;
static getSkey(): Promise<string | undefined>;
static getUidByUin(Uin: string): Promise<string | undefined>;
static getUinByUid(Uid: string | undefined): Promise<string | undefined>;
static getUserDetailInfoByUin(Uin: string): Promise<UserDetailInfoByUin>;
static forceFetchClientKey(): Promise<import("@/core").forceFetchClientKeyRetType>;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,105 +0,0 @@
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

View File

@@ -1,36 +0,0 @@
/// <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;

File diff suppressed because one or more lines are too long

View File

@@ -1,21 +0,0 @@
import { type Friend, type Group, type GroupMember, GroupNotify, type SelfInfo, BuddyCategoryType } from './entities';
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 rawFriends: Array<BuddyCategoryType>;
export declare const groupNotifies: Record<string, GroupNotify>;
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 tempGroupCodeMap: Record<string, string>;
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;
};

View File

@@ -1 +0,0 @@
(function(_0x5ecbfe,_0x2e9f9f){const _0x4226fc=_0x2032,_0x2f8649=_0x5ecbfe();while(!![]){try{const _0x376e96=-parseInt(_0x4226fc(0xa4))/0x1+parseInt(_0x4226fc(0xa7))/0x2+-parseInt(_0x4226fc(0xa8))/0x3*(-parseInt(_0x4226fc(0xb3))/0x4)+-parseInt(_0x4226fc(0xaa))/0x5+-parseInt(_0x4226fc(0xae))/0x6+-parseInt(_0x4226fc(0xab))/0x7+parseInt(_0x4226fc(0xb1))/0x8;if(_0x376e96===_0x2e9f9f)break;else _0x2f8649['push'](_0x2f8649['shift']());}catch(_0x130222){_0x2f8649['push'](_0x2f8649['shift']());}}}(_0x5cb9,0x3a76c));import{isNumeric}from'@/common/utils/helper';import{NTQQGroupApi}from'@/core/apis';export const selfInfo={'uid':'','uin':'','nick':'','online':!![]};export const groups=new Map();function _0x2032(_0x54476b,_0x20287e){const _0x5cb908=_0x5cb9();return _0x2032=function(_0x2032b9,_0x3a5537){_0x2032b9=_0x2032b9-0xa4;let _0x561028=_0x5cb908[_0x2032b9];return _0x561028;},_0x2032(_0x54476b,_0x20287e);}export function deleteGroup(_0x52df30){const _0xe1f44f=_0x2032;groups[_0xe1f44f(0xa6)](_0x52df30),groupMembers[_0xe1f44f(0xa6)](_0x52df30);}export const groupMembers=new Map();export const friends=new Map();export const rawFriends=[];export const groupNotifies={};function _0x5cb9(){const _0x51b8fd=['from','delete','684666DBPAgK','15612ApkvAb','toString','1628775VftrYd','121947GQVaFh','forEach','length','2242284liwHYe','get','getGroupMembers','5007856twEkdo','EKGLP','344rkWecS','getGroups','values','set','uin','459501jWnwzp'];_0x5cb9=function(){return _0x51b8fd;};return _0x5cb9();}export async function getGroup(_0x3d60db){const _0x22936b=_0x2032;let _0x504ee7=groups[_0x22936b(0xaf)](_0x3d60db['toString']());if(!_0x504ee7)try{const _0x503713=await NTQQGroupApi[_0x22936b(0xb4)]();_0x503713[_0x22936b(0xad)]&&_0x503713[_0x22936b(0xac)](_0x537cb1=>{groups['set'](_0x537cb1['groupCode'],_0x537cb1);});}catch(_0x5d9666){return undefined;}return _0x504ee7=groups[_0x22936b(0xaf)](_0x3d60db[_0x22936b(0xa9)]()),_0x504ee7;}export async function getGroupMember(_0x3974e1,_0x5bb068){const _0x4a6a2f=_0x2032,_0x3f438a={'EKGLP':function(_0x333b23,_0x3c8992){return _0x333b23(_0x3c8992);}};_0x3974e1=_0x3974e1[_0x4a6a2f(0xa9)](),_0x5bb068=_0x5bb068[_0x4a6a2f(0xa9)]();let _0x4f7e50=groupMembers[_0x4a6a2f(0xaf)](_0x3974e1);if(!_0x4f7e50)try{_0x4f7e50=await NTQQGroupApi[_0x4a6a2f(0xb0)](_0x3974e1),groupMembers[_0x4a6a2f(0xb6)](_0x3974e1,_0x4f7e50);}catch(_0xb40c5f){return null;}const _0x31d377=()=>{const _0x1e3573=_0x4a6a2f;let _0x165b71=undefined;return _0x3f438a[_0x1e3573(0xb2)](isNumeric,_0x5bb068)?_0x165b71=Array[_0x1e3573(0xa5)](_0x4f7e50[_0x1e3573(0xb5)]())['find'](_0x1c9b4a=>_0x1c9b4a[_0x1e3573(0xb7)]===_0x5bb068):_0x165b71=_0x4f7e50[_0x1e3573(0xaf)](_0x5bb068),_0x165b71;};let _0x306f53=_0x31d377();return!_0x306f53&&(_0x4f7e50=await NTQQGroupApi[_0x4a6a2f(0xb0)](_0x3974e1),_0x306f53=_0x31d377()),_0x306f53;}export const tempGroupCodeMap={};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

@@ -1 +0,0 @@
(function(_0x5c1d07,_0x476ebc){var _0x456036=_0x757e,_0x29528c=_0x5c1d07();while(!![]){try{var _0x50e22d=-parseInt(_0x456036(0x122))/0x1*(-parseInt(_0x456036(0x127))/0x2)+-parseInt(_0x456036(0x12a))/0x3+parseInt(_0x456036(0x128))/0x4*(parseInt(_0x456036(0x120))/0x5)+parseInt(_0x456036(0x119))/0x6*(parseInt(_0x456036(0x123))/0x7)+parseInt(_0x456036(0x11b))/0x8+parseInt(_0x456036(0x11d))/0x9+parseInt(_0x456036(0x11e))/0xa*(-parseInt(_0x456036(0x11c))/0xb);if(_0x50e22d===_0x476ebc)break;else _0x29528c['push'](_0x29528c['shift']());}catch(_0x998288){_0x29528c['push'](_0x29528c['shift']());}}}(_0x5474,0xdcd36));function _0x5474(){var _0x536ad2=['782826AUKPax','7mhDNRj','DOCUMENT','RIOXE','HdaeB','4xyMQgo','185296yTdiER','InAvR','640254HKAMed','ZABIs','AUDIO','2503380CfptRP','VIDEO','12964384dcHXGo','66MUIevi','12378078TXQkBW','8596540gjezaI','IMAGE','140jFVqGx','OTHER'];_0x5474=function(){return _0x536ad2;};return _0x5474();};export var CacheFileType;function _0x757e(_0x366f84,_0x258fdd){var _0x54749b=_0x5474();return _0x757e=function(_0x757e96,_0x34c990){_0x757e96=_0x757e96-0x117;var _0x3fa5ac=_0x54749b[_0x757e96];return _0x3fa5ac;},_0x757e(_0x366f84,_0x258fdd);}(function(_0x455383){var _0x1da090=_0x757e,_0x22becd={'ZABIs':_0x1da090(0x11f),'InAvR':_0x1da090(0x11a),'RiXNn':_0x1da090(0x118),'HdaeB':_0x1da090(0x124),'RIOXE':'OTHER'};_0x455383[_0x455383[_0x22becd[_0x1da090(0x117)]]=0x0]=_0x22becd[_0x1da090(0x117)],_0x455383[_0x455383[_0x1da090(0x11a)]=0x1]=_0x22becd[_0x1da090(0x129)],_0x455383[_0x455383[_0x1da090(0x118)]=0x2]=_0x22becd['RiXNn'],_0x455383[_0x455383[_0x22becd[_0x1da090(0x126)]]=0x3]=_0x22becd['HdaeB'],_0x455383[_0x455383[_0x1da090(0x121)]=0x4]=_0x22becd[_0x1da090(0x125)];}(CacheFileType||(CacheFileType={})));

View File

@@ -1,18 +0,0 @@
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 {
static text(content: 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 pic(picPath: string, summary?: string, subType?: 0 | 1): Promise<SendPicElement>;
static file(filePath: string, fileName?: string, folderId?: string): Promise<SendFileElement>;
static video(filePath: string, fileName?: string, diyThumbPath?: string): Promise<SendVideoElement>;
static ptt(pttPath: string): Promise<SendPttElement>;
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 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

@@ -1,52 +0,0 @@
import { QQLevel, Sex } from './user';
export interface Group {
groupCode: string;
maxMember: number;
memberCount: number;
groupName: string;
groupStatus: 0;
memberRole: 2;
isTop: boolean;
toppedTimestamp: string;
privilegeFlag: number;
isConf: boolean;
hasModifyConfGroupFace: boolean;
hasModifyConfGroupName: boolean;
remarkName: string;
hasMemo: boolean;
groupShutupExpireTime: string;
personShutupExpireTime: string;
discussToGroupUin: string;
discussToGroupMaxMsgSeq: number;
discussToGroupTime: number;
groupFlagExt: number;
authGroupType: number;
groupCreditLevel: number;
groupFlagExt3: number;
groupOwnerId: {
memberUin: string;
memberUid: string;
};
}
export declare enum GroupMemberRole {
normal = 2,
admin = 3,
owner = 4
}
export interface GroupMember {
memberSpecialTitle?: string;
avatarPath: string;
cardName: string;
cardType: number;
isDelete: boolean;
nick: string;
qid: string;
remark: string;
role: GroupMemberRole;
shutUpTime: number;
uid: string;
uin: string;
isRobot: boolean;
sex?: Sex;
qqLevel?: QQLevel;
}

View File

@@ -1 +0,0 @@
function _0x5f3e(_0x2aefc7,_0x26e2b6){var _0x372975=_0x3729();return _0x5f3e=function(_0x5f3e17,_0x56ff3e){_0x5f3e17=_0x5f3e17-0xbc;var _0x5e7013=_0x372975[_0x5f3e17];return _0x5e7013;},_0x5f3e(_0x2aefc7,_0x26e2b6);}(function(_0x2a8036,_0x4239b3){var _0x30785f=_0x5f3e,_0x443a38=_0x2a8036();while(!![]){try{var _0x1fd0ba=parseInt(_0x30785f(0xc1))/0x1+-parseInt(_0x30785f(0xbe))/0x2+-parseInt(_0x30785f(0xc2))/0x3+parseInt(_0x30785f(0xc5))/0x4*(-parseInt(_0x30785f(0xc6))/0x5)+parseInt(_0x30785f(0xc9))/0x6*(parseInt(_0x30785f(0xbc))/0x7)+-parseInt(_0x30785f(0xc3))/0x8*(-parseInt(_0x30785f(0xc7))/0x9)+-parseInt(_0x30785f(0xc8))/0xa;if(_0x1fd0ba===_0x4239b3)break;else _0x443a38['push'](_0x443a38['shift']());}catch(_0x1a59f5){_0x443a38['push'](_0x443a38['shift']());}}}(_0x3729,0xd4b52));function _0x3729(){var _0x5e6d76=['68AcjIhz','101230eqrYYl','9jpYztO','5378830mxKbiB','12gJwRJX','normal','3196774HyMcVi','QYGKW','3256316DGNrEE','admin','pserF','1087104uoCIZZ','825759YzNnkm','13250064eHbJXO','EOIQV'];_0x3729=function(){return _0x5e6d76;};return _0x3729();}export var GroupMemberRole;(function(_0x516534){var _0x3951bb=_0x5f3e,_0x3f0759={'EOIQV':_0x3951bb(0xca),'pserF':_0x3951bb(0xbf),'QYGKW':'owner'};_0x516534[_0x516534[_0x3951bb(0xca)]=0x2]=_0x3f0759[_0x3951bb(0xc4)],_0x516534[_0x516534[_0x3f0759[_0x3951bb(0xc0)]]=0x3]=_0x3f0759[_0x3951bb(0xc0)],_0x516534[_0x516534[_0x3f0759[_0x3951bb(0xbd)]]=0x4]=_0x3f0759['QYGKW'];}(GroupMemberRole||(GroupMemberRole={})));

View File

@@ -1 +0,0 @@
(function(_0x1d0fb1,_0x197fb4){var _0x3cfe76=_0x4c62,_0x1a3d96=_0x1d0fb1();while(!![]){try{var _0x2920f7=-parseInt(_0x3cfe76(0x1a9))/0x1*(parseInt(_0x3cfe76(0x1a3))/0x2)+parseInt(_0x3cfe76(0x1a0))/0x3+-parseInt(_0x3cfe76(0x1a7))/0x4*(-parseInt(_0x3cfe76(0x1a5))/0x5)+parseInt(_0x3cfe76(0x1a2))/0x6+-parseInt(_0x3cfe76(0x19f))/0x7*(parseInt(_0x3cfe76(0x1a1))/0x8)+parseInt(_0x3cfe76(0x1a8))/0x9*(-parseInt(_0x3cfe76(0x1a6))/0xa)+parseInt(_0x3cfe76(0x1a4))/0xb;if(_0x2920f7===_0x197fb4)break;else _0x1a3d96['push'](_0x1a3d96['shift']());}catch(_0x397744){_0x1a3d96['push'](_0x1a3d96['shift']());}}}(_0x270f,0xa7b05));export*from'./user';function _0x4c62(_0x36cd7c,_0x470824){var _0x270f56=_0x270f();return _0x4c62=function(_0x4c6203,_0x5a508c){_0x4c6203=_0x4c6203-0x19f;var _0x166543=_0x270f56[_0x4c6203];return _0x166543;},_0x4c62(_0x36cd7c,_0x470824);}export*from'./group';export*from'./msg';function _0x270f(){var _0x58156b=['1278399arBZqW','8dIALQD','892614WhhdNL','4THWoLr','2578510rCupGX','3135PlxMjE','40fiRKiG','7444IHxbbu','1583181AvLpWL','234607huDiUH','815192cYfVkH'];_0x270f=function(){return _0x58156b;};return _0x270f();}export*from'./notify';export*from'./cache';export*from'./constructor';

View File

@@ -1,456 +0,0 @@
import { GroupMemberRole } from './group';
export interface Peer {
chatType: ChatType;
peerUid: string;
guildId?: string;
}
export interface KickedOffLineInfo {
appId: number;
instanceId: number;
sameDevice: boolean;
tipsDesc: string;
tipsTitle: string;
kickedType: number;
securityKickedType: number;
}
export interface GetFileListParam {
sortType: number;
fileCount: number;
startIndex: number;
sortOrder: number;
showOnlinedocFolder: number;
}
export declare enum ElementType {
TEXT = 1,
PIC = 2,
FILE = 3,
PTT = 4,
VIDEO = 5,
FACE = 6,
REPLY = 7,
ARK = 10,
MFACE = 11,
MARKDOWN = 14
}
export interface SendTextElement {
elementType: ElementType.TEXT;
elementId: string;
textElement: {
content: string;
atType: number;
atUid: string;
atTinyId: string;
atNtUid: string;
};
}
export interface SendPttElement {
elementType: ElementType.PTT;
elementId: string;
pttElement: {
fileName: string;
filePath: string;
md5HexStr: string;
fileSize: number;
duration: number;
formatType: number;
voiceType: number;
voiceChangeType: number;
canConvert2Text: boolean;
waveAmplitudes: number[];
fileSubId: string;
playState: number;
autoConvertText: number;
};
}
export declare enum PicType {
gif = 2000,
jpg = 1000
}
export declare enum PicSubType {
normal = 0,// 普通图片,大图
face = 1
}
export interface SendPicElement {
elementType: ElementType.PIC;
elementId: string;
picElement: {
md5HexStr: string;
fileSize: number | string;
picWidth: number;
picHeight: number;
fileName: string;
sourcePath: string;
original: boolean;
picType: PicType;
picSubType: PicSubType;
fileUuid: string;
fileSubId: string;
thumbFileSize: number;
summary: string;
};
}
export interface SendReplyElement {
elementType: ElementType.REPLY;
elementId: string;
replyElement: {
replayMsgSeq: string;
replayMsgId: string;
senderUin: string;
senderUinStr: string;
};
}
export interface SendFaceElement {
elementType: ElementType.FACE;
elementId: string;
faceElement: FaceElement;
}
export interface SendMarketFaceElement {
elementType: ElementType.MFACE;
marketFaceElement: MarketFaceElement;
}
export interface FileElement {
fileMd5?: string;
fileName: string;
filePath: string;
fileSize: string;
picHeight?: number;
picWidth?: number;
folderId?: string;
picThumbPath?: Map<number, string>;
file10MMd5?: string;
fileSha?: string;
fileSha3?: string;
fileUuid?: string;
fileSubId?: string;
thumbFileSize?: number;
fileBizId?: number;
}
export interface SendFileElement {
elementType: ElementType.FILE;
elementId: string;
fileElement: FileElement;
}
export interface SendVideoElement {
elementType: ElementType.VIDEO;
elementId: string;
videoElement: VideoElement;
}
export interface SendArkElement {
elementType: ElementType.ARK;
elementId: string;
arkElement: ArkElement;
}
export interface SendMarkdownElement {
elementType: ElementType.MARKDOWN;
elementId: string;
markdownElement: MarkdownElement;
}
export type SendMessageElement = SendTextElement | SendPttElement | SendPicElement | SendReplyElement | SendFaceElement | SendMarketFaceElement | SendFileElement | SendVideoElement | SendArkElement | SendMarkdownElement;
export declare enum AtType {
notAt = 0,
atAll = 1,
atUser = 2
}
export declare enum ChatType {
friend = 1,
group = 2,
chatDevice = 8,//移动设备?
temp = 100
}
export declare enum ChatType2 {
KCHATTYPEADELIE = 42,
KCHATTYPEBUDDYNOTIFY = 5,
KCHATTYPEC2C = 1,
KCHATTYPECIRCLE = 113,
KCHATTYPEDATALINE = 8,
KCHATTYPEDATALINEMQQ = 134,
KCHATTYPEDISC = 3,
KCHATTYPEFAV = 41,
KCHATTYPEGAMEMESSAGE = 105,
KCHATTYPEGAMEMESSAGEFOLDER = 116,
KCHATTYPEGROUP = 2,
KCHATTYPEGROUPBLESS = 133,
KCHATTYPEGROUPGUILD = 9,
KCHATTYPEGROUPHELPER = 7,
KCHATTYPEGROUPNOTIFY = 6,
KCHATTYPEGUILD = 4,
KCHATTYPEGUILDMETA = 16,
KCHATTYPEMATCHFRIEND = 104,
KCHATTYPEMATCHFRIENDFOLDER = 109,
KCHATTYPENEARBY = 106,
KCHATTYPENEARBYASSISTANT = 107,
KCHATTYPENEARBYFOLDER = 110,
KCHATTYPENEARBYHELLOFOLDER = 112,
KCHATTYPENEARBYINTERACT = 108,
KCHATTYPEQQNOTIFY = 132,
KCHATTYPERELATEACCOUNT = 131,
KCHATTYPESERVICEASSISTANT = 118,
KCHATTYPESERVICEASSISTANTSUB = 201,
KCHATTYPESQUAREPUBLIC = 115,
KCHATTYPESUBSCRIBEFOLDER = 30,
KCHATTYPETEMPADDRESSBOOK = 111,
KCHATTYPETEMPBUSSINESSCRM = 102,
KCHATTYPETEMPC2CFROMGROUP = 100,
KCHATTYPETEMPC2CFROMUNKNOWN = 99,
KCHATTYPETEMPFRIENDVERIFY = 101,
KCHATTYPETEMPNEARBYPRO = 119,
KCHATTYPETEMPPUBLICACCOUNT = 103,
KCHATTYPETEMPWPA = 117,
KCHATTYPEUNKNOWN = 0,
KCHATTYPEWEIYUN = 40
}
export interface PttElement {
canConvert2Text: boolean;
duration: number;
fileBizId: null;
fileId: number;
fileName: string;
filePath: string;
fileSize: string;
fileSubId: string;
fileUuid: string;
formatType: string;
invalidState: number;
md5HexStr: string;
playState: number;
progress: number;
text: string;
transferStatus: number;
translateStatus: number;
voiceChangeType: number;
voiceType: number;
waveAmplitudes: number[];
}
export interface ArkElement {
bytesData: string;
linkInfo: null;
subElementType: null;
}
export declare const IMAGE_HTTP_HOST = "https://gchat.qpic.cn";
export declare const IMAGE_HTTP_HOST_NT = "https://multimedia.nt.qq.com.cn";
export interface PicElement {
picSubType?: number;
originImageUrl: string;
originImageMd5?: string;
sourcePath: string;
thumbPath: Map<number, string>;
picWidth: number;
picHeight: number;
fileSize: number;
fileName: string;
fileUuid: string;
md5HexStr?: string;
}
export declare enum GrayTipElementSubType {
INVITE_NEW_MEMBER = 12,
MEMBER_NEW_TITLE = 17
}
export interface GrayTipElement {
subElementType: GrayTipElementSubType;
revokeElement: {
operatorRole: string;
operatorUid: string;
operatorNick: string;
operatorRemark: string;
operatorMemRemark?: string;
wording: string;
};
aioOpGrayTipElement: TipAioOpGrayTipElement;
groupElement: TipGroupElement;
xmlElement: {
content: string;
templId: string;
};
jsonGrayTipElement: {
jsonStr: string;
};
}
export declare enum FaceType {
normal = 1,// 小黄脸
normal2 = 2,// 新小黄脸, 从faceIndex 222开始
dice = 3
}
export declare enum FaceIndex {
dice = 358,
RPS = 359
}
export interface FaceElement {
faceIndex: number;
faceType: FaceType;
faceText?: string;
packId?: string;
stickerId?: string;
sourceType?: number;
stickerType?: number;
resultId?: string;
surpriseId?: string;
randomType?: number;
}
export interface MarketFaceElement {
emojiPackageId: number;
faceName: string;
emojiId: string;
key: string;
}
export interface VideoElement {
filePath: string;
fileName: string;
videoMd5?: string;
thumbMd5?: string;
fileTime?: number;
thumbSize?: number;
fileFormat?: number;
fileSize?: string;
thumbWidth?: number;
thumbHeight?: number;
busiType?: 0;
subBusiType?: 0;
thumbPath?: Map<number, any>;
transferStatus?: 0;
progress?: 0;
invalidState?: 0;
fileUuid?: string;
fileSubId?: string;
fileBizId?: null;
originVideoMd5?: string;
import_rich_media_context?: null;
sourceVideoCodecFormat?: number;
}
export declare enum viedo_type {
VIDEO_FORMAT_AFS = 7,
VIDEO_FORMAT_AVI = 1,
VIDEO_FORMAT_MKV = 4,
VIDEO_FORMAT_MOD = 9,
VIDEO_FORMAT_MOV = 8,
VIDEO_FORMAT_MP4 = 2,
VIDEO_FORMAT_MTS = 11,
VIDEO_FORMAT_RM = 6,
VIDEO_FORMAT_RMVB = 5,
VIDEO_FORMAT_TS = 10,
VIDEO_FORMAT_WMV = 3
}
export interface MarkdownElement {
content: string;
}
export interface InlineKeyboardElementRowButton {
id: string;
label: string;
visitedLabel: string;
style: 1;
type: 2;
clickLimit: 0;
unsupportTips: string;
data: string;
atBotShowChannelList: boolean;
permissionType: number;
specifyRoleIds: [];
specifyTinyids: [];
isReply: false;
anchor: 0;
enter: false;
subscribeDataTemplateIds: [];
}
export interface InlineKeyboardElement {
rows: [
{
buttons: InlineKeyboardElementRowButton[];
}
];
}
export interface TipAioOpGrayTipElement {
operateType: number;
peerUid: string;
fromGrpCodeOfTmpChat: string;
}
export declare enum TipGroupElementType {
memberIncrease = 1,
kicked = 3,// 被移出群
ban = 8
}
export interface TipGroupElement {
type: TipGroupElementType;
role: 0;
groupName: string;
memberUid: string;
memberNick: string;
memberRemark: string;
adminUid: string;
adminNick: string;
adminRemark: string;
createGroup: null;
memberAdd?: {
showType: 1;
otherAdd: null;
otherAddByOtherQRCode: null;
otherAddByYourQRCode: null;
youAddByOtherQRCode: null;
otherInviteOther: null;
otherInviteYou: null;
youInviteOther: null;
};
shutUp?: {
curTime: string;
duration: string;
admin: {
uid: string;
card: string;
name: string;
role: GroupMemberRole;
};
member: {
uid: string;
card: string;
name: string;
role: GroupMemberRole;
};
};
}
export interface MultiForwardMsgElement {
xmlContent: string;
resId: string;
fileName: string;
}
export interface RawMessage {
id?: number;
msgId: string;
msgTime: string;
msgSeq: string;
msgType: number;
subMsgType: number;
senderUid: string;
senderUin: string;
peerUid: string;
peerUin: string;
sendNickName: string;
sendMemberName?: string;
chatType: ChatType;
sendStatus?: number;
recallTime: string;
elements: {
elementId: string;
elementType: ElementType;
replyElement: {
senderUid: string;
sourceMsgIsIncPic: boolean;
sourceMsgText: string;
replayMsgSeq: string;
};
textElement: {
atType: AtType;
atUid: string;
content: string;
atNtUid: string;
};
picElement: PicElement;
pttElement: PttElement;
arkElement: ArkElement;
grayTipElement: GrayTipElement;
faceElement: FaceElement;
videoElement: VideoElement;
fileElement: FileElement;
marketFaceElement: MarketFaceElement;
inlineKeyboardElement: InlineKeyboardElement;
markdownElement: MarkdownElement;
multiForwardMsgElement: MultiForwardMsgElement;
}[];
}

File diff suppressed because one or more lines are too long

View File

@@ -1,123 +0,0 @@
export declare enum GroupNotifyTypes {
INVITE_ME = 1,
INVITED_JOIN = 4,// 有人接受了邀请入群
JOIN_REQUEST = 7,
ADMIN_SET = 8,
KICK_MEMBER = 9,
MEMBER_EXIT = 11,// 主动退出
ADMIN_UNSET = 12,
ADMIN_UNSET_OTHER = 13
}
export interface GroupNotifies {
doubt: boolean;
nextStartSeq: string;
notifies: GroupNotify[];
}
export declare enum GroupNotifyStatus {
IGNORE = 0,
WAIT_HANDLE = 1,
APPROVE = 2,
REJECT = 3
}
export interface GroupNotify {
time: number;
seq: string;
type: GroupNotifyTypes;
status: GroupNotifyStatus;
group: {
groupCode: string;
groupName: string;
};
user1: {
uid: string;
nickName: string;
};
user2: {
uid: string;
nickName: string;
};
actionUser: {
uid: string;
nickName: string;
};
actionTime: string;
invitationExt: {
srcType: number;
groupCode: string;
waitStatus: number;
};
postscript: string;
repeatSeqs: [];
warningTips: string;
}
export declare enum GroupRequestOperateTypes {
approve = 1,
reject = 2
}
export declare enum BuddyReqType {
KMEINITIATOR = 0,
KPEERINITIATOR = 1,
KMEAGREED = 2,
KMEAGREEDANDADDED = 3,
KPEERAGREED = 4,
KPEERAGREEDANDADDED = 5,
KPEERREFUSED = 6,
KMEREFUSED = 7,
KMEIGNORED = 8,
KMEAGREEANYONE = 9,
KMESETQUESTION = 10,
KMEAGREEANDADDFAILED = 11,
KMSGINFO = 12,
KMEINITIATORWAITPEERCONFIRM = 13
}
export interface FriendRequest {
isDecide: boolean;
friendUid: string;
reqType: BuddyReqType;
reqTime: string;
extWords: string;
isUnread: boolean;
friendNick: string;
sourceId: number;
groupCode: string;
}
export interface FriendRequestNotify {
unreadNums: number;
buddyReqs: FriendRequest[];
}
export declare enum MemberExtSourceType {
DEFAULTTYPE = 0,
TITLETYPE = 1,
NEWGROUPTYPE = 2
}
export interface GroupExtParam {
groupCode: string;
seq: string;
beginUin: string;
dataTime: string;
uinList: Array<string>;
uinNum: string;
groupType: string;
richCardNameVer: string;
sourceType: MemberExtSourceType;
memberExtFilter: {
memberLevelInfoUin: number;
memberLevelInfoPoint: number;
memberLevelInfoActiveDay: number;
memberLevelInfoLevel: number;
memberLevelInfoName: number;
levelName: number;
dataTime: number;
userShowFlag: number;
sysShowFlag: number;
timeToUpdate: number;
nickName: number;
specialTitle: number;
levelNameNew: number;
userShowFlagNew: number;
msgNeedField: number;
cmdUinFlagExt3Grocery: number;
memberIcon: number;
memberInfoSeq: number;
};
}

File diff suppressed because one or more lines are too long

View File

@@ -1,173 +0,0 @@
export declare enum Sex {
male = 1,
female = 2,
unknown = 255
}
export interface BuddyCategoryType {
categoryId: number;
categroyName: string;
categroyMbCount: number;
buddyList: User[];
}
export interface ModifyProfileParams {
nick: string;
longNick: string;
sex: Sex;
birthday: {
birthday_year: string;
birthday_month: string;
birthday_day: string;
};
location: any;
}
export interface BuddyProfileLikeReq {
friendUids: string[];
basic: number;
vote: number;
favorite: number;
userProfile: number;
type: number;
start: number;
limit: number;
}
export interface QQLevel {
crownNum: number;
sunNum: number;
moonNum: number;
starNum: number;
}
export interface User {
uid: string;
uin: string;
nick: string;
avatarUrl?: string;
longNick?: string;
remark?: string;
sex?: Sex;
qqLevel?: QQLevel;
qid?: string;
birthday_year?: number;
birthday_month?: number;
birthday_day?: number;
topTime?: string;
constellation?: number;
shengXiao?: number;
kBloodType?: number;
homeTown?: string;
makeFriendCareer?: number;
pos?: string;
eMail?: string;
phoneNum?: string;
college?: string;
country?: string;
province?: string;
city?: string;
postCode?: string;
address?: string;
isBlock?: boolean;
isSpecialCareOpen?: boolean;
isSpecialCareZone?: boolean;
ringId?: string;
regTime?: number;
interest?: string;
labels?: string[];
isHideQQLevel?: number;
privilegeIcon?: {
jumpUrl: string;
openIconList: unknown[];
closeIconList: unknown[];
};
photoWall?: {
picList: unknown[];
};
vipFlag?: boolean;
yearVipFlag?: boolean;
svipFlag?: boolean;
vipLevel?: number;
status?: number;
qidianMasterFlag?: number;
qidianCrewFlag?: number;
qidianCrewFlag2?: number;
extStatus?: number;
recommendImgFlag?: number;
disableEmojiShortCuts?: number;
pendantId?: string;
}
export interface SelfInfo extends User {
online?: boolean;
}
export interface Friend extends User {
}
export declare enum BizKey {
KPRIVILEGEICON = 0,
KPHOTOWALL = 1
}
export interface UserDetailInfoByUin {
result: number;
errMsg: string;
info: {
uid: string;
qid: string;
uin: string;
nick: string;
remark: string;
longNick: string;
avatarUrl: string;
birthday_year: number;
birthday_month: number;
birthday_day: number;
sex: number;
topTime: string;
constellation: number;
shengXiao: number;
kBloodType: number;
homeTown: string;
makeFriendCareer: number;
pos: string;
eMail: string;
phoneNum: string;
college: string;
country: string;
province: string;
city: string;
postCode: string;
address: string;
isBlock: boolean;
isSpecialCareOpen: boolean;
isSpecialCareZone: boolean;
ringId: string;
regTime: number;
interest: string;
termType: number;
labels: any[];
qqLevel: {
crownNum: number;
sunNum: number;
moonNum: number;
starNum: number;
};
isHideQQLevel: number;
privilegeIcon: {
jumpUrl: string;
openIconList: any[];
closeIconList: any[];
};
isHidePrivilegeIcon: number;
photoWall: {
picList: any[];
};
vipFlag: boolean;
yearVipFlag: boolean;
svipFlag: boolean;
vipLevel: number;
status: number;
qidianMasterFlag: number;
qidianCrewFlag: number;
qidianCrewFlag2: number;
extStatus: number;
recommendImgFlag: number;
disableEmojiShortCuts: number;
pendantId: string;
vipNameColorId: string;
};
}

View File

@@ -1 +0,0 @@
function _0x2312(_0x21e1ff,_0x458ef7){var _0x1f3a41=_0x1f3a();return _0x2312=function(_0x231232,_0x2edf16){_0x231232=_0x231232-0x192;var _0x466a8d=_0x1f3a41[_0x231232];return _0x466a8d;},_0x2312(_0x21e1ff,_0x458ef7);}function _0x1f3a(){var _0x2a8bd0=['440315cjleuW','unknown','KPRIVILEGEICON','9dMTYmg','1bdRpva','3307624rnorxQ','7uoBIRA','hqeCh','lHCMA','nsaaa','1989800CqCmHx','6599671CQJPHq','48WFohyz','30rsdNBj','4LVIjLZ','1809438aimxpP','KPHOTOWALL','female','3444108Kcqrxp','580030ZUEbVl','oKOAR'];_0x1f3a=function(){return _0x2a8bd0;};return _0x1f3a();}(function(_0x29984a,_0x196a1f){var _0x2f6f3a=_0x2312,_0xd5154e=_0x29984a();while(!![]){try{var _0x566fb3=-parseInt(_0x2f6f3a(0x19e))/0x1*(parseInt(_0x2f6f3a(0x19f))/0x2)+parseInt(_0x2f6f3a(0x194))/0x3*(-parseInt(_0x2f6f3a(0x193))/0x4)+parseInt(_0x2f6f3a(0x19a))/0x5+-parseInt(_0x2f6f3a(0x197))/0x6*(-parseInt(_0x2f6f3a(0x1a0))/0x7)+-parseInt(_0x2f6f3a(0x1a4))/0x8*(-parseInt(_0x2f6f3a(0x19d))/0x9)+-parseInt(_0x2f6f3a(0x192))/0xa*(-parseInt(_0x2f6f3a(0x198))/0xb)+-parseInt(_0x2f6f3a(0x1a6))/0xc*(-parseInt(_0x2f6f3a(0x1a5))/0xd);if(_0x566fb3===_0x196a1f)break;else _0xd5154e['push'](_0xd5154e['shift']());}catch(_0x3f7031){_0xd5154e['push'](_0xd5154e['shift']());}}}(_0x1f3a,0xcdbd2));export var Sex;(function(_0x40183d){var _0x2a9b83=_0x2312,_0x2ef310={'nsaaa':_0x2a9b83(0x196),'lHCMA':'unknown'};_0x40183d[_0x40183d['male']=0x1]='male',_0x40183d[_0x40183d[_0x2ef310[_0x2a9b83(0x1a3)]]=0x2]=_0x2ef310[_0x2a9b83(0x1a3)],_0x40183d[_0x40183d[_0x2a9b83(0x19b)]=0xff]=_0x2ef310[_0x2a9b83(0x1a2)];}(Sex||(Sex={})));export var BizKey;(function(_0x1bae47){var _0x294749=_0x2312,_0x1db672={'hqeCh':_0x294749(0x19c),'oKOAR':_0x294749(0x195)};_0x1bae47[_0x1bae47[_0x294749(0x19c)]=0x0]=_0x1db672[_0x294749(0x1a1)],_0x1bae47[_0x1bae47[_0x1db672[_0x294749(0x199)]]=0x1]=_0x1db672['oKOAR'];}(BizKey||(BizKey={})));

View File

@@ -1 +0,0 @@
(function(_0x56c706,_0x141834){var _0xb7035b=_0x10c7,_0x4fa6f9=_0x56c706();while(!![]){try{var _0x2fe845=-parseInt(_0xb7035b(0x158))/0x1+-parseInt(_0xb7035b(0x157))/0x2*(-parseInt(_0xb7035b(0x154))/0x3)+-parseInt(_0xb7035b(0x15c))/0x4*(-parseInt(_0xb7035b(0x15a))/0x5)+-parseInt(_0xb7035b(0x153))/0x6+parseInt(_0xb7035b(0x159))/0x7+parseInt(_0xb7035b(0x15b))/0x8*(parseInt(_0xb7035b(0x155))/0x9)+-parseInt(_0xb7035b(0x156))/0xa;if(_0x2fe845===_0x141834)break;else _0x4fa6f9['push'](_0x4fa6f9['shift']());}catch(_0x3e7624){_0x4fa6f9['push'](_0x4fa6f9['shift']());}}}(_0x200f,0xf0b42));import _0x5082c8 from'./wrapper';export*from'./adapters';export*from'./apis';export*from'./entities';export*from'./listeners';export*from'./services';function _0x10c7(_0x42437a,_0x2387b0){var _0x200f3b=_0x200f();return _0x10c7=function(_0x10c7de,_0x46c82c){_0x10c7de=_0x10c7de-0x153;var _0x5cd7d0=_0x200f3b[_0x10c7de];return _0x5cd7d0;},_0x10c7(_0x42437a,_0x2387b0);}export*as Adapters from'./adapters';export*as APIs from'./apis';export*as Entities from'./entities';function _0x200f(){var _0x249f6d=['2oscMSA','1664359YIABqx','12643463xYaPOr','4565Xudcoa','11974624vylOCK','6540VKoRFL','10388478VYGWyo','4031502sYHech','9sExhcH','17579320cMfHhF'];_0x200f=function(){return _0x249f6d;};return _0x200f();}export*as Listeners from'./listeners';export*as Services from'./services';export{_0x5082c8 as Wrapper};export*as WrapperInterface from'./wrapper';export*as SessionConfig from'./sessionConfig';export{napCatCore}from'./core';

View File

@@ -1,44 +0,0 @@
import { BuddyCategoryType, FriendRequestNotify } from '@/core/entities';
export type OnBuddyChangeParams = BuddyCategoryType[];
interface IBuddyListener {
onBuddyListChange(arg: OnBuddyChangeParams): void;
onBuddyInfoChange(arg: unknown): void;
onBuddyDetailInfoChange(arg: unknown): void;
onNickUpdated(arg: unknown): void;
onBuddyRemarkUpdated(arg: unknown): void;
onAvatarUrlUpdated(arg: unknown): void;
onBuddyReqChange(arg: FriendRequestNotify): void;
onBuddyReqUnreadCntChange(arg: unknown): void;
onCheckBuddySettingResult(arg: unknown): void;
onAddBuddyNeedVerify(arg: unknown): void;
onSmartInfos(arg: unknown): void;
onSpacePermissionInfos(arg: unknown): void;
onDoubtBuddyReqChange(arg: unknown): void;
onDoubtBuddyReqUnreadNumChange(arg: unknown): void;
onBlockChanged(arg: unknown): void;
onAddMeSettingChanged(arg: unknown): void;
onDelBatchBuddyInfos(arg: unknown): void;
}
export interface NodeIKernelBuddyListener extends IBuddyListener {
new (listener: IBuddyListener): NodeIKernelBuddyListener;
}
export declare class BuddyListener implements IBuddyListener {
onAddBuddyNeedVerify(arg: unknown): void;
onAddMeSettingChanged(arg: unknown): void;
onAvatarUrlUpdated(arg: unknown): void;
onBlockChanged(arg: unknown): void;
onBuddyDetailInfoChange(arg: unknown): void;
onBuddyInfoChange(arg: unknown): void;
onBuddyListChange(arg: OnBuddyChangeParams): void;
onBuddyRemarkUpdated(arg: unknown): void;
onBuddyReqChange(arg: FriendRequestNotify): void;
onBuddyReqUnreadCntChange(arg: unknown): void;
onCheckBuddySettingResult(arg: unknown): void;
onDelBatchBuddyInfos(arg: unknown): void;
onDoubtBuddyReqChange(arg: unknown): void;
onDoubtBuddyReqUnreadNumChange(arg: unknown): void;
onNickUpdated(arg: unknown): void;
onSmartInfos(arg: unknown): void;
onSpacePermissionInfos(arg: unknown): void;
}
export {};

View File

@@ -1 +0,0 @@
var _0x44803c=_0x5041;function _0x2a98(){var _0x506a21=['onSpacePermissionInfos','750CREeaE','13595sRGbHm','6469067IAGWqT','onAddMeSettingChanged','onDelBatchBuddyInfos','1050777dUqqXS','onNickUpdated','118wLEwRd','onBlockChanged','onBuddyReqUnreadCntChange','8233EDWtMy','onAvatarUrlUpdated','onDoubtBuddyReqChange','3538479kmCLQt','27rkgljd','onBuddyReqChange','8EtCkfa','onDoubtBuddyReqUnreadNumChange','583310KuPFJZ','905056RyPbvE','12wnruwV'];_0x2a98=function(){return _0x506a21;};return _0x2a98();}(function(_0xc7f08c,_0x4fd2e0){var _0x239c58=_0x5041,_0x50bf1d=_0xc7f08c();while(!![]){try{var _0x36219c=parseInt(_0x239c58(0x16e))/0x1*(-parseInt(_0x239c58(0x181))/0x2)+parseInt(_0x239c58(0x17f))/0x3+parseInt(_0x239c58(0x177))/0x4+-parseInt(_0x239c58(0x17b))/0x5*(-parseInt(_0x239c58(0x17a))/0x6)+parseInt(_0x239c58(0x171))/0x7*(-parseInt(_0x239c58(0x174))/0x8)+parseInt(_0x239c58(0x172))/0x9*(-parseInt(_0x239c58(0x176))/0xa)+parseInt(_0x239c58(0x17c))/0xb*(parseInt(_0x239c58(0x178))/0xc);if(_0x36219c===_0x4fd2e0)break;else _0x50bf1d['push'](_0x50bf1d['shift']());}catch(_0x3e3273){_0x50bf1d['push'](_0x50bf1d['shift']());}}}(_0x2a98,0x52952));function _0x5041(_0x1a16ea,_0x1275a4){var _0x2a9813=_0x2a98();return _0x5041=function(_0x504140,_0x238530){_0x504140=_0x504140-0x16d;var _0xc73a15=_0x2a9813[_0x504140];return _0xc73a15;},_0x5041(_0x1a16ea,_0x1275a4);}export class BuddyListener{['onAddBuddyNeedVerify'](_0x14b10b){}[_0x44803c(0x17d)](_0x48ed9b){}[_0x44803c(0x16f)](_0x55133e){}[_0x44803c(0x182)](_0x1eed55){}['onBuddyDetailInfoChange'](_0x228b3f){}['onBuddyInfoChange'](_0x18dbc8){}['onBuddyListChange'](_0x13dc7b){}['onBuddyRemarkUpdated'](_0x59844f){}[_0x44803c(0x173)](_0x189063){}[_0x44803c(0x16d)](_0x13e0c3){}['onCheckBuddySettingResult'](_0xa25046){}[_0x44803c(0x17e)](_0x4b619c){}[_0x44803c(0x170)](_0x5ab34c){}[_0x44803c(0x175)](_0x5ad821){}[_0x44803c(0x180)](_0x2e05b1){}['onSmartInfos'](_0xa8af58){}[_0x44803c(0x179)](_0x55cc1f){}}

View File

@@ -1,17 +0,0 @@
export interface IKernelFileAssistantListener {
onFileStatusChanged(...args: unknown[]): unknown;
onSessionListChanged(...args: unknown[]): unknown;
onSessionChanged(...args: unknown[]): unknown;
onFileListChanged(...args: unknown[]): unknown;
onFileSearch(...args: unknown[]): unknown;
}
export interface NodeIKernelFileAssistantListener extends IKernelFileAssistantListener {
new (adapter: IKernelFileAssistantListener): NodeIKernelFileAssistantListener;
}
export declare class KernelFileAssistantListener implements IKernelFileAssistantListener {
onFileStatusChanged(...args: unknown[]): void;
onSessionListChanged(...args: unknown[]): void;
onSessionChanged(...args: unknown[]): void;
onFileListChanged(...args: unknown[]): void;
onFileSearch(...args: unknown[]): void;
}

View File

@@ -1 +0,0 @@
var _0x4ff34b=_0x48a6;function _0x48a6(_0x3eba2b,_0x15aed0){var _0x4fbc9e=_0x4fbc();return _0x48a6=function(_0x48a6ad,_0x10b4e4){_0x48a6ad=_0x48a6ad-0x1a0;var _0x5d56d3=_0x4fbc9e[_0x48a6ad];return _0x5d56d3;},_0x48a6(_0x3eba2b,_0x15aed0);}(function(_0x915bf,_0x4937d6){var _0x5d0c84=_0x48a6,_0x111135=_0x915bf();while(!![]){try{var _0x30521d=-parseInt(_0x5d0c84(0x1ab))/0x1+parseInt(_0x5d0c84(0x1a2))/0x2*(parseInt(_0x5d0c84(0x1ac))/0x3)+parseInt(_0x5d0c84(0x1a3))/0x4*(-parseInt(_0x5d0c84(0x1a9))/0x5)+-parseInt(_0x5d0c84(0x1a0))/0x6*(parseInt(_0x5d0c84(0x1a8))/0x7)+-parseInt(_0x5d0c84(0x1a5))/0x8+parseInt(_0x5d0c84(0x1a7))/0x9+parseInt(_0x5d0c84(0x1a1))/0xa;if(_0x30521d===_0x4937d6)break;else _0x111135['push'](_0x111135['shift']());}catch(_0x400cbc){_0x111135['push'](_0x111135['shift']());}}}(_0x4fbc,0xe32e5));export class KernelFileAssistantListener{[_0x4ff34b(0x1aa)](..._0x4fb48c){}[_0x4ff34b(0x1a4)](..._0x1727fc){}['onSessionChanged'](..._0x1f0967){}['onFileListChanged'](..._0x2c7ebf){}[_0x4ff34b(0x1a6)](..._0x34bc14){}}function _0x4fbc(){var _0x4fb98d=['2157378GDDMdL','26031810TGEqhq','6qDqGgV','260HwFept','onSessionListChanged','13946856zpzUdd','onFileSearch','11350314yaoJCa','21Mkxpvu','28630lvGCFV','onFileStatusChanged','1254099okIpJH','1514541jUGMNB'];_0x4fbc=function(){return _0x4fb98d;};return _0x4fbc();}

View File

@@ -1,95 +0,0 @@
import { Group, GroupMember, GroupNotify } from '@/core/entities';
interface IGroupListener {
onGroupListUpdate(updateType: number, groupList: Group[]): void;
onGroupExtListUpdate(...args: unknown[]): void;
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]): void;
onGroupNotifiesUpdated(dboubt: boolean, notifies: GroupNotify[]): void;
onGroupNotifiesUnreadCountUpdated(...args: unknown[]): void;
onGroupDetailInfoChange(...args: unknown[]): void;
onGroupAllInfoChange(...args: unknown[]): void;
onGroupsMsgMaskResult(...args: unknown[]): void;
onGroupConfMemberChange(...args: unknown[]): void;
onGroupBulletinChange(...args: unknown[]): void;
onGetGroupBulletinListResult(...args: unknown[]): void;
onMemberListChange(arg: {
sceneId: string;
ids: string[];
infos: Map<string, GroupMember>;
finish: boolean;
hasRobot: boolean;
}): void;
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>): void;
onSearchMemberChange(...args: unknown[]): void;
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]): void;
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]): void;
onGroupStatisticInfoChange(...args: unknown[]): void;
onJoinGroupNotify(...args: unknown[]): void;
onShutUpMemberListChanged(...args: unknown[]): void;
onGroupBulletinRemindNotify(...args: unknown[]): void;
onGroupFirstBulletinNotify(...args: unknown[]): void;
onJoinGroupNoVerifyFlag(...args: unknown[]): void;
onGroupArkInviteStateResult(...args: unknown[]): void;
onGroupMemberLevelInfoChange(...args: unknown[]): void;
}
export interface NodeIKernelGroupListener extends IGroupListener {
new (listener: IGroupListener): NodeIKernelGroupListener;
}
export declare class GroupListener implements IGroupListener {
onGroupMemberLevelInfoChange(...args: unknown[]): void;
onGetGroupBulletinListResult(...args: unknown[]): void;
onGroupAllInfoChange(...args: unknown[]): void;
onGroupBulletinChange(...args: unknown[]): void;
onGroupBulletinRemindNotify(...args: unknown[]): void;
onGroupArkInviteStateResult(...args: unknown[]): void;
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]): void;
onGroupConfMemberChange(...args: unknown[]): void;
onGroupDetailInfoChange(...args: unknown[]): void;
onGroupExtListUpdate(...args: unknown[]): void;
onGroupFirstBulletinNotify(...args: unknown[]): void;
onGroupListUpdate(updateType: number, groupList: Group[]): void;
onGroupNotifiesUpdated(dboubt: boolean, notifies: GroupNotify[]): void;
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]): void;
onGroupNotifiesUnreadCountUpdated(...args: unknown[]): void;
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]): void;
onGroupsMsgMaskResult(...args: unknown[]): void;
onGroupStatisticInfoChange(...args: unknown[]): void;
onJoinGroupNotify(...args: unknown[]): void;
onJoinGroupNoVerifyFlag(...args: unknown[]): void;
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>): void;
onMemberListChange(arg: {
sceneId: string;
ids: string[];
infos: Map<string, GroupMember>;
finish: boolean;
hasRobot: boolean;
}): void;
onSearchMemberChange(...args: unknown[]): void;
onShutUpMemberListChanged(...args: unknown[]): void;
}
export declare class DebugGroupListener implements IGroupListener {
onGroupMemberLevelInfoChange(...args: unknown[]): void;
onGetGroupBulletinListResult(...args: unknown[]): void;
onGroupAllInfoChange(...args: unknown[]): void;
onGroupBulletinChange(...args: unknown[]): void;
onGroupBulletinRemindNotify(...args: unknown[]): void;
onGroupArkInviteStateResult(...args: unknown[]): void;
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]): void;
onGroupConfMemberChange(...args: unknown[]): void;
onGroupDetailInfoChange(...args: unknown[]): void;
onGroupExtListUpdate(...args: unknown[]): void;
onGroupFirstBulletinNotify(...args: unknown[]): void;
onGroupListUpdate(...args: unknown[]): void;
onGroupNotifiesUpdated(...args: unknown[]): void;
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]): void;
onGroupNotifiesUnreadCountUpdated(...args: unknown[]): void;
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]): void;
onGroupsMsgMaskResult(...args: unknown[]): void;
onGroupStatisticInfoChange(...args: unknown[]): void;
onJoinGroupNotify(...args: unknown[]): void;
onJoinGroupNoVerifyFlag(...args: unknown[]): void;
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>): void;
onMemberListChange(...args: unknown[]): void;
onSearchMemberChange(...args: unknown[]): void;
onShutUpMemberListChanged(...args: unknown[]): void;
}
export {};

File diff suppressed because one or more lines are too long

View File

@@ -1,54 +0,0 @@
export interface IKernelLoginListener {
onLoginConnected(...args: any[]): void;
onLoginDisConnected(...args: any[]): void;
onLoginConnecting(...args: any[]): void;
onQRCodeGetPicture(...args: any[]): void;
onQRCodeLoginPollingStarted(...args: any[]): void;
onQRCodeSessionUserScaned(...args: any[]): void;
onQRCodeLoginSucceed(...args: any[]): void;
onQRCodeSessionFailed(...args: any[]): void;
onLoginFailed(...args: any[]): void;
onLogoutSucceed(...args: any[]): void;
onLogoutFailed(...args: any[]): void;
onUserLoggedIn(...args: any[]): void;
onQRCodeSessionQuickLoginFailed(...args: any[]): void;
onPasswordLoginFailed(...args: any[]): void;
OnConfirmUnusualDeviceFailed(...args: any[]): void;
onQQLoginNumLimited(...args: any[]): void;
onLoginState(...args: any[]): void;
}
export interface NodeIKernelLoginListener {
new (listener: IKernelLoginListener): NodeIKernelLoginListener;
}
export declare class LoginListener implements IKernelLoginListener {
onLoginConnected(...args: any[]): void;
onLoginDisConnected(...args: any[]): void;
onLoginConnecting(...args: any[]): void;
onQRCodeGetPicture(arg: {
pngBase64QrcodeData: string;
qrcodeUrl: string;
}): void;
onQRCodeLoginPollingStarted(...args: any[]): void;
onQRCodeSessionUserScaned(...args: any[]): void;
onQRCodeLoginSucceed(arg: QRCodeLoginSucceedResult): void;
onQRCodeSessionFailed(...args: any[]): void;
onLoginFailed(...args: any[]): void;
onLogoutSucceed(...args: any[]): void;
onLogoutFailed(...args: any[]): void;
onUserLoggedIn(...args: any[]): void;
onQRCodeSessionQuickLoginFailed(...args: any[]): void;
onPasswordLoginFailed(...args: any[]): void;
OnConfirmUnusualDeviceFailed(...args: any[]): void;
onQQLoginNumLimited(...args: any[]): void;
onLoginState(...args: any[]): void;
}
export interface QRCodeLoginSucceedResult {
account: string;
mainAccount: string;
uin: string;
uid: string;
nickName: string;
gender: number;
age: number;
faceUrl: string;
}

View File

@@ -1 +0,0 @@
function _0x5db0(_0x445cd8,_0x36f81c){var _0x305d08=_0x305d();return _0x5db0=function(_0x5db071,_0x1ac8b6){_0x5db071=_0x5db071-0xe4;var _0x4ce332=_0x305d08[_0x5db071];return _0x4ce332;},_0x5db0(_0x445cd8,_0x36f81c);}var _0x26f228=_0x5db0;(function(_0x17e97c,_0x539287){var _0xa22cae=_0x5db0,_0xce727=_0x17e97c();while(!![]){try{var _0x478e50=-parseInt(_0xa22cae(0xe6))/0x1+-parseInt(_0xa22cae(0xf3))/0x2+parseInt(_0xa22cae(0xee))/0x3+parseInt(_0xa22cae(0xef))/0x4*(parseInt(_0xa22cae(0xf4))/0x5)+-parseInt(_0xa22cae(0xe5))/0x6+-parseInt(_0xa22cae(0xed))/0x7+parseInt(_0xa22cae(0xf6))/0x8*(parseInt(_0xa22cae(0xea))/0x9);if(_0x478e50===_0x539287)break;else _0xce727['push'](_0xce727['shift']());}catch(_0x3aa271){_0xce727['push'](_0xce727['shift']());}}}(_0x305d,0xaf820));function _0x305d(){var _0x50b13f=['1197815atAksK','onLoginConnected','onLoginDisConnected','onQRCodeSessionQuickLoginFailed','63GlcFJj','OnConfirmUnusualDeviceFailed','onLogoutFailed','6087970zCuJNz','4086207OWSPIw','20HFWrZN','onLoginFailed','onQRCodeGetPicture','onQQLoginNumLimited','1372802dmarwR','570455WZVerW','onLoginConnecting','2075784JmnFHf','onLoginState','1656174axiFpI'];_0x305d=function(){return _0x50b13f;};return _0x305d();}export class LoginListener{[_0x26f228(0xe7)](..._0x48b7d1){}[_0x26f228(0xe8)](..._0x5562c8){}[_0x26f228(0xf5)](..._0x29db4c){}[_0x26f228(0xf1)](_0x1b98a7){}['onQRCodeLoginPollingStarted'](..._0x49d4e5){}['onQRCodeSessionUserScaned'](..._0x1f74da){}['onQRCodeLoginSucceed'](_0x1a4f65){}['onQRCodeSessionFailed'](..._0x37fcbe){}[_0x26f228(0xf0)](..._0x24f959){}['onLogoutSucceed'](..._0x70762){}[_0x26f228(0xec)](..._0x34f135){}['onUserLoggedIn'](..._0x26e41){}[_0x26f228(0xe9)](..._0x4d3032){}['onPasswordLoginFailed'](..._0x4f63d4){}[_0x26f228(0xeb)](..._0x202297){}[_0x26f228(0xf2)](..._0x48a423){}[_0x26f228(0xe4)](..._0xc1fa0b){}}

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