Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1619adfc27 | ||
|
|
5510fb473f | ||
|
|
be1878cb2b | ||
|
|
15ab121cbd | ||
|
|
aa79b0e861 | ||
|
|
b80e550bcd | ||
|
|
dbc40b5814 | ||
|
|
0d5696a644 | ||
|
|
ceffa05802 | ||
|
|
d5668920b6 | ||
|
|
516f2da144 | ||
|
|
33c94e1888 | ||
|
|
51ab58cd91 | ||
|
|
aa7798d1d1 | ||
|
|
9067a1fc92 | ||
|
|
4024b6c564 | ||
|
|
d39730928b | ||
|
|
e1f049229c | ||
|
|
8f2676ec19 | ||
|
|
32d26248dc | ||
|
|
16f926401b | ||
|
|
66d60d3599 | ||
|
|
5a35ab6c34 | ||
|
|
ba1542bd31 | ||
|
|
453060945a | ||
|
|
c8351be461 | ||
|
|
9954da22a6 | ||
|
|
907b5611eb | ||
|
|
5f075de212 | ||
|
|
8fcf3c5079 | ||
|
|
07cee90c7a | ||
|
|
75ad495b98 | ||
|
|
0bb7288ad2 | ||
|
|
ad72415532 | ||
|
|
0ad0353fc0 | ||
|
|
9fa0dcd7aa | ||
|
|
1f2e80cd39 | ||
|
|
6cb6034d43 | ||
|
|
25134c6ac6 | ||
|
|
92bf42878a | ||
|
|
9f4582d158 | ||
|
|
68af73970e | ||
|
|
b6ed8d4975 | ||
|
|
d07d3645ce | ||
|
|
123759ab17 | ||
|
|
f2f1f893d8 | ||
|
|
db93a8eed2 | ||
|
|
12ab6d4a7d | ||
|
|
add759e889 | ||
|
|
f315f7977d | ||
|
|
f2f6701ebd | ||
|
|
1a92794d33 | ||
|
|
7640deb798 | ||
|
|
f1e8ef1cf6 | ||
|
|
5e5ac0162e | ||
|
|
0c013820f0 | ||
|
|
4b3a9e5847 | ||
|
|
e4982256a4 | ||
|
|
babc4927a8 | ||
|
|
6dd84cf469 | ||
|
|
a8800e3899 | ||
|
|
5f03496046 | ||
|
|
41500c17a2 | ||
|
|
2dcfde8b9a | ||
|
|
5c3305d8fa | ||
|
|
0d1fe99f53 | ||
|
|
4c03ffeec7 | ||
|
|
8101d17482 | ||
|
|
bc7b4dcc2a | ||
|
|
3db8b9078d | ||
|
|
943dbbefd3 | ||
|
|
480abcb853 | ||
|
|
60aaaff58e | ||
|
|
e3b889bbe8 | ||
|
|
ac5506a43b | ||
|
|
b29f533a3b | ||
|
|
a8ee86b09e | ||
|
|
0238c53302 | ||
|
|
665e3c806f | ||
|
|
8c96838441 | ||
|
|
4a722daec6 | ||
|
|
4e0cdbcb91 | ||
|
|
08976624cd | ||
|
|
fdeba94653 | ||
|
|
d3b100b7e5 | ||
|
|
1de3e18b08 | ||
|
|
d5c3c95682 | ||
|
|
dabe1e29ed | ||
|
|
203d1c0cfc | ||
|
|
7edd8601be | ||
|
|
a4423247f4 | ||
|
|
4834b203a0 | ||
|
|
bbabb32d13 | ||
|
|
95112d6bdf | ||
|
|
36cdca5a3e | ||
|
|
6980a9f3fc | ||
|
|
7b09479cd2 | ||
|
|
5825fd6f36 | ||
|
|
2d5b45dd82 | ||
|
|
52dda1d1fe | ||
|
|
420624bee4 | ||
|
|
8abde7b7d0 | ||
|
|
9e5b1ba28e | ||
|
|
b9c7d3c18e | ||
|
|
10aeccbbe5 | ||
|
|
15d351ebc2 | ||
|
|
7194f31cb6 | ||
|
|
84b7e82446 | ||
|
|
8264423b1a | ||
|
|
37f897f3bf | ||
|
|
fe3efac145 | ||
|
|
9773aebefc | ||
|
|
06f2b8c371 | ||
|
|
e8f0bb8350 | ||
|
|
9bfa6b827b | ||
|
|
b21bc17a58 | ||
|
|
f4d5d417d0 | ||
|
|
91fc83621e | ||
|
|
461feca0ca | ||
|
|
5e9afab3f7 | ||
|
|
2599ca6450 | ||
|
|
fc99ad3a39 | ||
|
|
10e1c3e72c | ||
|
|
af5dedd4d4 | ||
|
|
3b986c1076 | ||
|
|
72f77e8b7c | ||
|
|
e893bf676f | ||
|
|
80eb34f611 | ||
|
|
5d01947552 | ||
|
|
d3a025ef7b | ||
|
|
c466df841e | ||
|
|
b3c6e2a0f3 | ||
|
|
076c9cfed7 | ||
|
|
c3f3d12f83 | ||
|
|
44974034ec | ||
|
|
d6175acd38 | ||
|
|
62eee5f05c | ||
|
|
d4e5201913 | ||
|
|
f4d584765a | ||
|
|
26e224f852 | ||
|
|
252358ed66 | ||
|
|
475afeb7c8 | ||
|
|
7cbbb846eb | ||
|
|
25f947968c | ||
|
|
cad824dcbc | ||
|
|
e506f50b00 | ||
|
|
96ec149a98 | ||
|
|
8c913512f6 | ||
|
|
4cc307299d | ||
|
|
407c6b4c5f | ||
|
|
8f87070434 | ||
|
|
4a63996ee2 | ||
|
|
0358fe7620 | ||
|
|
55e64395ed | ||
|
|
ff5fb18e14 | ||
|
|
52dd960857 | ||
|
|
430221c2de | ||
|
|
217bdf8f92 | ||
|
|
38c6c869bf | ||
|
|
84d46da67e | ||
|
|
eb9d6240d7 | ||
|
|
2d44a871b0 | ||
|
|
3f89f350ff | ||
|
|
1a8407a782 | ||
|
|
cf288a3f73 | ||
|
|
f1f37fb180 | ||
|
|
fb0dd079fd | ||
|
|
a6c584c85c | ||
|
|
77adf35a30 | ||
|
|
dc6951c2a9 | ||
|
|
d14ba3f0f7 | ||
|
|
78ddf36e35 | ||
|
|
d42734624d | ||
|
|
b5dbd9d59b | ||
|
|
bed3e1289b | ||
|
|
b11ca4e60e | ||
|
|
4fcf3aa2bd | ||
|
|
dc39da8ca5 | ||
|
|
c10c87d28e | ||
|
|
c6fe6f1cc5 | ||
|
|
1c2bbeb26d | ||
|
|
17ed3692d0 | ||
|
|
966a00f41e | ||
|
|
fd8d8f89aa | ||
|
|
305bb74072 | ||
|
|
7f4dcdd134 | ||
|
|
aac37dcce1 | ||
|
|
f539c662a5 | ||
|
|
c82f346dd0 | ||
|
|
21b4a87837 | ||
|
|
ae73bcf24b | ||
|
|
2a3b56bde1 | ||
|
|
b8ebededd8 | ||
|
|
227c4c422c | ||
|
|
652bfb93cc | ||
|
|
c2278e3536 | ||
|
|
caa2fca4e8 | ||
|
|
745cb0175c | ||
|
|
e5165a780f | ||
|
|
b4b91af02b | ||
|
|
5649ff9c2e | ||
|
|
5b4bf6c62a | ||
|
|
93cb662282 | ||
|
|
00a8715e58 | ||
|
|
7ecd479b3e | ||
|
|
8fe7d3aaec | ||
|
|
f32a693393 | ||
|
|
17ebc01597 | ||
|
|
827fb698e1 | ||
|
|
32bdf10fd2 | ||
|
|
b795e6c3d2 | ||
|
|
42ba524e4e | ||
|
|
317c6d96e3 | ||
|
|
3692d1499f | ||
|
|
b21fbad8a3 | ||
|
|
743334a68a | ||
|
|
951413eb38 | ||
|
|
32dcdef853 | ||
|
|
34c9254d4a | ||
|
|
14012a4668 | ||
|
|
575debca63 | ||
|
|
763cac8532 | ||
|
|
43faacd7a7 | ||
|
|
1d4e307e96 | ||
|
|
7f8933b0de | ||
|
|
81608ff025 | ||
|
|
db63675b8e | ||
|
|
f74a83bc46 | ||
|
|
bc1deba3e4 | ||
|
|
d6113a8f0a | ||
|
|
2062cd48ea | ||
|
|
1c965ef515 | ||
|
|
58291b7156 | ||
|
|
afd1648d80 | ||
|
|
21814ffa9a | ||
|
|
9d3522da54 | ||
|
|
e07a76755e | ||
|
|
ba46bcdeae | ||
|
|
8d7e44314c | ||
|
|
35a67498c7 | ||
|
|
90dd934f95 | ||
|
|
4087045542 | ||
|
|
d11cef5907 | ||
|
|
76c91d226c | ||
|
|
c2b4dd2afd | ||
|
|
25b39cb39a | ||
|
|
35dcb7b88b | ||
|
|
e5f7e7c26e | ||
|
|
c5c11fd6a6 | ||
|
|
8134083419 | ||
|
|
a87e624198 | ||
|
|
e4c62d20b4 | ||
|
|
fa195d9e55 | ||
|
|
5ef5773d23 | ||
|
|
6eea52afdf | ||
|
|
80e64af30f | ||
|
|
563b6ddc36 | ||
|
|
c051ab9dc4 | ||
|
|
87737a8bdb | ||
|
|
94273d80b0 | ||
|
|
a08ec2a4bd | ||
|
|
d246c556f4 | ||
|
|
65aa365e38 | ||
|
|
eeeae449b4 | ||
|
|
17c10a7ba2 | ||
|
|
69f4383678 | ||
|
|
07852a7295 | ||
|
|
20b7e9b6b5 | ||
|
|
75f43ccea4 | ||
|
|
59e5785e93 | ||
|
|
b38f52dba9 | ||
|
|
2a6b17a48e | ||
|
|
a6c056a894 | ||
|
|
5c3442a71f | ||
|
|
390253242f | ||
|
|
9ab80fe1ac | ||
|
|
91fdd09e7a | ||
|
|
db5bd5c8a4 | ||
|
|
ef94c2fe7c | ||
|
|
72a25ed8e1 | ||
|
|
eb065e218f | ||
|
|
33426736fc | ||
|
|
896658d5ce | ||
|
|
b14135ed72 | ||
|
|
a1baf2e32d | ||
|
|
f9aa2d3bce | ||
|
|
c95d0e0696 | ||
|
|
ad4b84d446 | ||
|
|
3e27d5fcb0 | ||
|
|
48a100f49a | ||
|
|
698649f981 | ||
|
|
780078c3aa | ||
|
|
4c25e4ddee | ||
|
|
c0a5ac2ac5 | ||
|
|
0435409870 | ||
|
|
c521269409 | ||
|
|
1e252b7e4c | ||
|
|
d72b1edc48 | ||
|
|
f7307e8e01 | ||
|
|
127905f04b | ||
|
|
261c6dabd5 | ||
|
|
cae84bbf02 | ||
|
|
cdb2bc52fa | ||
|
|
cd2972eee0 | ||
|
|
4036aa8d0e | ||
|
|
52c6927c44 | ||
|
|
a16e0a21a2 | ||
|
|
e796b21157 | ||
|
|
1c6bc478b4 | ||
|
|
98f39c6388 | ||
|
|
570c83571b | ||
|
|
c0c38d89e0 | ||
|
|
b866cfc03c | ||
|
|
28c2755b37 | ||
|
|
57bfc5c73a | ||
|
|
0f3f7d53a3 | ||
|
|
529e50fd7f | ||
|
|
2fa283f91d | ||
|
|
029a9ade93 | ||
|
|
f1ca8b15c8 | ||
|
|
4d8edd5da9 | ||
|
|
6c63990653 | ||
|
|
5b521409c6 | ||
|
|
3268fc1014 | ||
|
|
19afb4941b | ||
|
|
40e5111d41 | ||
|
|
a3a40e1e74 | ||
|
|
101caa6826 | ||
|
|
875fed8d77 | ||
|
|
69e28eb000 | ||
|
|
e5d3a8360c | ||
|
|
4545d9285b | ||
|
|
6702024805 | ||
|
|
78bad4842b | ||
|
|
b9a913cfed | ||
|
|
6f5a6f353f | ||
|
|
790c4f589d | ||
|
|
cd1bd3461f | ||
|
|
0280dcd6a8 | ||
|
|
fc337292bc | ||
|
|
fb1daa0e21 | ||
|
|
579b9dc0c2 | ||
|
|
dedd0be352 | ||
|
|
1c7d9c3513 | ||
|
|
0c7dfe2af4 | ||
|
|
8d1351a8a3 | ||
|
|
e6e68a6036 | ||
|
|
24658edc45 | ||
|
|
09eaa3116a | ||
|
|
e9bff466b5 | ||
|
|
5d77f50160 | ||
|
|
2ab91e363f | ||
|
|
34d881426f | ||
|
|
13ecaa0ad4 | ||
|
|
ce6185b1f7 | ||
|
|
2cfde6b75a | ||
|
|
37d0354751 | ||
|
|
0a0edcf203 | ||
|
|
d6aad2ea28 | ||
|
|
63084506ee | ||
|
|
c5d313574f | ||
|
|
caab998212 | ||
|
|
aa037cc3d9 | ||
|
|
642bffe374 | ||
|
|
d682b154fc | ||
|
|
d4a06d98cf | ||
|
|
856b5e16b1 | ||
|
|
a0aa208860 | ||
|
|
037a11e04f | ||
|
|
bd8a1d715f | ||
|
|
54ab1dc091 | ||
|
|
9471e63857 | ||
|
|
fa4a403f38 | ||
|
|
d608d65bf4 | ||
|
|
c0f2df172a | ||
|
|
788ef5d81c | ||
|
|
1c6b5cffe1 | ||
|
|
c04382b623 | ||
|
|
0bbe51f8fd | ||
|
|
ff7d7d15a0 | ||
|
|
4b3d083d3a | ||
|
|
a566dd390b | ||
|
|
7d1442da04 | ||
|
|
17fc982f55 | ||
|
|
ba417e2274 | ||
|
|
d345094b75 | ||
|
|
6da477480d | ||
|
|
e274088c06 | ||
|
|
1bcaa73c5c | ||
|
|
ca94e8f621 | ||
|
|
1c4e198f59 | ||
|
|
fdd13f9c66 | ||
|
|
4333ab624e | ||
|
|
9fe1eb3a42 | ||
|
|
ad251a7682 | ||
|
|
1fa740de2d | ||
|
|
466b89064a | ||
|
|
2748cb0ba3 | ||
|
|
aef0d5bdde | ||
|
|
c71e8f024a | ||
|
|
9411f07321 | ||
|
|
9b2a5c9bbf | ||
|
|
2b275523a0 | ||
|
|
31fe2f6da4 | ||
|
|
f95db623a5 | ||
|
|
a46313e483 | ||
|
|
31c330826e | ||
|
|
c4cf800142 | ||
|
|
b64a2b0006 | ||
|
|
a3702f2270 | ||
|
|
d221b1d470 | ||
|
|
0b22a6bc1d | ||
|
|
07e8acd003 | ||
|
|
9fce617c57 | ||
|
|
8d5c736975 | ||
|
|
4ccec05186 | ||
|
|
a4f456f002 | ||
|
|
fbdb941c27 | ||
|
|
a41cd42e8d | ||
|
|
77521e4627 | ||
|
|
b6a1242bac | ||
|
|
2f325cfe26 | ||
|
|
193b0ad0f0 | ||
|
|
ed476b7793 | ||
|
|
720fd94b7f | ||
|
|
ff87da105c | ||
|
|
a875e65536 | ||
|
|
0b2c6bb662 | ||
|
|
e44e2fbbb7 | ||
|
|
b3c93644fd | ||
|
|
a56b7ff636 | ||
|
|
c724236930 | ||
|
|
4853320b2b | ||
|
|
ba1acb6ac1 | ||
|
|
f32a6320fc | ||
|
|
9f914ce36a | ||
|
|
b037644e5a | ||
|
|
afd8c59f83 | ||
|
|
8aa4af3e91 | ||
|
|
630a8a2b97 | ||
|
|
dc34c4d00c | ||
|
|
fb42729dec | ||
|
|
b06989216a | ||
|
|
e5144f08cd | ||
|
|
c4a60190e8 | ||
|
|
efe9e4fa4c | ||
|
|
45800b1559 | ||
|
|
b0b2b8104f | ||
|
|
8dbc012825 | ||
|
|
a434176063 | ||
|
|
a013f750c7 | ||
|
|
aa1f49d02f | ||
|
|
7125a26309 | ||
|
|
329a35ebf0 | ||
|
|
d30043f595 | ||
|
|
745dfa1911 | ||
|
|
76203f49a7 | ||
|
|
870a915377 | ||
|
|
c174fce227 | ||
|
|
2b6e42e919 | ||
|
|
df73e1e5a3 | ||
|
|
3e902311d4 | ||
|
|
64a0037265 | ||
|
|
bcd4e38093 | ||
|
|
181a77d627 | ||
|
|
b353595ba9 | ||
|
|
75e3bb4f17 | ||
|
|
d2fa9192d4 | ||
|
|
4bcadc2de4 | ||
|
|
8ddff74260 | ||
|
|
95940fdb64 | ||
|
|
9cd5708948 | ||
|
|
d361683d79 | ||
|
|
9ad17a01f7 | ||
|
|
22ca1d443c | ||
|
|
2662e875ca | ||
|
|
8ae0d07ec1 | ||
|
|
76a9edb7f5 | ||
|
|
0ccb464e5b | ||
|
|
bef600efa2 | ||
|
|
58a182cd33 | ||
|
|
aa43334f41 | ||
|
|
a2a4c97f6c | ||
|
|
4217ba99fd | ||
|
|
589725f5cc | ||
|
|
3fea4602f8 | ||
|
|
8ea6aae875 | ||
|
|
2c70b2af68 | ||
|
|
54a2cbcb42 | ||
|
|
fdef821c60 | ||
|
|
dfa798a35d | ||
|
|
39b8eb6ff1 | ||
|
|
6cf71f67a9 | ||
|
|
f2e919725e | ||
|
|
869599126e | ||
|
|
3b1b200f6f | ||
|
|
93c646e3e4 | ||
|
|
3552f80a21 | ||
|
|
66d3a63998 | ||
|
|
6447825978 | ||
|
|
18b7df9fca | ||
|
|
c3781cab96 | ||
|
|
776098dba6 | ||
|
|
8d1b4f61e7 | ||
|
|
c13e2bdb96 | ||
|
|
4682254157 | ||
|
|
d7ca6b9213 | ||
|
|
4a76afbde8 | ||
|
|
a68349c23a | ||
|
|
920e005366 | ||
|
|
659f339020 | ||
|
|
3ee2d463af | ||
|
|
686ddb5460 | ||
|
|
e5d62488b7 | ||
|
|
eb93dd5005 | ||
|
|
6999d02d2d | ||
|
|
790e2b1427 | ||
|
|
a29c7cdfe4 | ||
|
|
6b7cd692a6 | ||
|
|
4d3925872a | ||
|
|
2bd0f6934a | ||
|
|
51783f17ed | ||
|
|
ce3aef3526 | ||
|
|
ee70afdfbb | ||
|
|
d96c4a56a2 | ||
|
|
9a39513dea | ||
|
|
8f22d63315 | ||
|
|
7f2a5bb95e | ||
|
|
0118dbd5fb | ||
|
|
09405de26c | ||
|
|
efa5ee0e57 | ||
|
|
80d558f37a | ||
|
|
901adc3fc7 | ||
|
|
01417be954 | ||
|
|
43b780cbe6 | ||
|
|
e83f36a12f | ||
|
|
77e3fc4ab0 | ||
|
|
eafd1adaba | ||
|
|
6b53abb7c9 | ||
|
|
f994c5d284 | ||
|
|
6fda220107 | ||
|
|
da290ed1c3 | ||
|
|
7e9cd80a1c | ||
|
|
379b7413d8 | ||
|
|
9181a4df16 | ||
|
|
df982afd51 | ||
|
|
5c2c3b4317 | ||
|
|
92d1309103 | ||
|
|
c43ee3c1d6 | ||
|
|
e0726e5283 | ||
|
|
5f3775584b | ||
|
|
77873d63c5 | ||
|
|
9e6b09765e | ||
|
|
1ad6ea4049 | ||
|
|
7c41da1cb9 | ||
|
|
adcf4bfc53 | ||
|
|
7a6321a9c1 | ||
|
|
d56b27a7b0 | ||
|
|
ed7657ab5f | ||
|
|
a414838416 | ||
|
|
93646577dc | ||
|
|
46db66038e | ||
|
|
efc4e9ce56 | ||
|
|
8d5eac7f80 | ||
|
|
7b94e49b81 | ||
|
|
c35fd4bdc8 | ||
|
|
98590e2d90 | ||
|
|
e6da0e5dd5 | ||
|
|
cb2baf747d | ||
|
|
a2f2eb03ce | ||
|
|
5c6acbb780 | ||
|
|
1be7031199 | ||
|
|
ed6399bde9 | ||
|
|
6709893781 | ||
|
|
686a426cda | ||
|
|
4f90bc7813 | ||
|
|
e307b289ae | ||
|
|
3baeff61a7 | ||
|
|
93ab9d12ee | ||
|
|
36e1317792 | ||
|
|
fa3e90a021 | ||
|
|
782a69cf13 | ||
|
|
d495f351c0 | ||
|
|
30bd3d2d52 | ||
|
|
ff5a21cca5 | ||
|
|
f8abb73c92 | ||
|
|
e97f323d9a | ||
|
|
3d27a4c05d | ||
|
|
9dbc13dbe4 | ||
|
|
c46a4c75b1 | ||
|
|
0bded73f16 | ||
|
|
1333733684 | ||
|
|
003be934de | ||
|
|
93ef20d358 | ||
|
|
94e1a6f0ba | ||
|
|
8661d09d57 | ||
|
|
0e5e21dc4e | ||
|
|
3b25c4987c | ||
|
|
2212eb17aa | ||
|
|
768bac1db8 | ||
|
|
3aef75085f | ||
|
|
ce8bef638a | ||
|
|
f0a0c90304 | ||
|
|
cd6c32b21d | ||
|
|
b31876d2d1 | ||
|
|
ebab8a190e | ||
|
|
1b7ce8e7a5 | ||
|
|
646bb6bd79 | ||
|
|
5a84b97ca9 | ||
|
|
6d41b5a4a1 | ||
|
|
a8bce36f3b | ||
|
|
ac2132f8ba | ||
|
|
cab4b57abe | ||
|
|
938fb30359 | ||
|
|
62346d7d9d | ||
|
|
cf1e5ca64b | ||
|
|
7d2d683d96 | ||
|
|
fe5042f1c3 | ||
|
|
a1dd76aee0 | ||
|
|
d1c91be167 | ||
|
|
9748d99f34 | ||
|
|
c90ffbeb62 | ||
|
|
eb7fafeabf | ||
|
|
3e50629462 | ||
|
|
65281a4554 | ||
|
|
454ec09d6a | ||
|
|
60e3c6858d | ||
|
|
f911f5b4fc | ||
|
|
ad1694d291 | ||
|
|
1130965f26 | ||
|
|
fe1f28998b | ||
|
|
45727fce05 | ||
|
|
d5c23e5add | ||
|
|
e3a8285f6c | ||
|
|
a791221cf6 | ||
|
|
b954d9b403 | ||
|
|
5e7e24a271 | ||
|
|
ffb1e598f6 | ||
|
|
bc2da8a645 | ||
|
|
6f2be3ed30 | ||
|
|
033a7bffb3 | ||
|
|
f2b2ea61a1 | ||
|
|
6f0783acc4 | ||
|
|
ce60aa3823 | ||
|
|
8075e70606 | ||
|
|
4402fc2d0a | ||
|
|
3e3ecda551 | ||
|
|
50beb8f346 | ||
|
|
8e033e3e06 | ||
|
|
dc029a318b | ||
|
|
8e91bc2c8e | ||
|
|
0ff5b4e90b | ||
|
|
20dec19bfe | ||
|
|
d261fbff26 | ||
|
|
6594b33bcc | ||
|
|
a1bb6cc1b1 | ||
|
|
7ce195b68e | ||
|
|
16d8d04aaa | ||
|
|
59565f7d90 | ||
|
|
43784a2495 | ||
|
|
3811d7469e | ||
|
|
c72b40a1e1 | ||
|
|
f00933969d | ||
|
|
759adc45e3 | ||
|
|
27ecf78372 | ||
|
|
c91b83a7ba | ||
|
|
39373ee63a | ||
|
|
2db64c69ae | ||
|
|
a699b71c02 | ||
|
|
6c07d22cda | ||
|
|
a2ee900ed5 | ||
|
|
e709f31b99 | ||
|
|
35afb12756 | ||
|
|
9bed9fe162 | ||
|
|
4ff5553804 | ||
|
|
32213be7a7 | ||
|
|
84894a73e1 | ||
|
|
b6ea185ce7 | ||
|
|
814ac0f731 | ||
|
|
a40bb29da3 | ||
|
|
e9b90079c0 | ||
|
|
dba383c27e | ||
|
|
42059b5817 | ||
|
|
f92a17c01b | ||
|
|
d6552ce333 | ||
|
|
0db89bde5a | ||
|
|
56a12185d4 | ||
|
|
c40170db5d | ||
|
|
1df3e9c414 | ||
|
|
b1570df8b9 | ||
|
|
023fd1ce36 | ||
|
|
a7fe74bc0c | ||
|
|
26c9abd9da | ||
|
|
a5e34645c5 | ||
|
|
b2831c0a19 | ||
|
|
648c1ea0f9 | ||
|
|
9cd927e06a | ||
|
|
4272413f55 | ||
|
|
e1711b7af6 | ||
|
|
f7d3f27d45 | ||
|
|
3a7a47f82d | ||
|
|
cc211706d5 | ||
|
|
22f74be4cd | ||
|
|
5a00d14f94 | ||
|
|
ecb4e7bf9f | ||
|
|
56e5b546e1 | ||
|
|
272f5a2f4f | ||
|
|
ddcbe78a01 | ||
|
|
00b6c964e2 | ||
|
|
d7d2b06ecc | ||
|
|
fafc59360d | ||
|
|
19e105785e | ||
|
|
b87ac09e43 | ||
|
|
af9092d7c7 | ||
|
|
24a1ffd652 | ||
|
|
662813cc58 | ||
|
|
d890b78290 | ||
|
|
58747d7d4a | ||
|
|
0773a4f39c | ||
|
|
66cc7f8a1f | ||
|
|
01ab40bf4a | ||
|
|
4c09147fd1 | ||
|
|
f9f426d788 | ||
|
|
ff8fa1bf31 | ||
|
|
59f99e4f6a | ||
|
|
7449ce9c3b | ||
|
|
f6bc8f0a1f | ||
|
|
4d10b8cdee | ||
|
|
5a61c5de09 | ||
|
|
f84d0db811 | ||
|
|
36ce3b08fe | ||
|
|
da8ea5b545 | ||
|
|
fad3dbf4cd | ||
|
|
034d12c347 | ||
|
|
c94dbf1d9a | ||
|
|
e516687a9e | ||
|
|
4a2f77b0a6 | ||
|
|
7b29ecba71 | ||
|
|
11241b8e07 | ||
|
|
52bbd1f20b | ||
|
|
4044750515 | ||
|
|
b670c546b9 | ||
|
|
f37bbf93cb | ||
|
|
87311ab41a | ||
|
|
ecb4d1845c | ||
|
|
35c232ab25 | ||
|
|
df0be2e251 | ||
|
|
871b3a102b | ||
|
|
02299e3892 | ||
|
|
6af4d6f5b8 | ||
|
|
4fb5700367 | ||
|
|
8579276381 | ||
|
|
7ba60b22c5 | ||
|
|
031932f41c | ||
|
|
079d0a89b1 | ||
|
|
c4fdce6d64 | ||
|
|
5604c2b29f | ||
|
|
74b5ab2b47 | ||
|
|
c29cbfe123 | ||
|
|
6fe5cb1ffd | ||
|
|
7edd5a7a8e | ||
|
|
c1edc1b99b | ||
|
|
4d1d890f72 | ||
|
|
fe0f82fa2b | ||
|
|
84083a65a8 | ||
|
|
fc91c6bc08 | ||
|
|
09120171ba | ||
|
|
a362f920dc | ||
|
|
9d7729f548 | ||
|
|
ed56e177cf | ||
|
|
9db28bd502 | ||
|
|
aded70eb2e | ||
|
|
dfbad85465 | ||
|
|
52076fe182 | ||
|
|
5575c3cb13 | ||
|
|
637d32efff | ||
|
|
fd54658e53 | ||
|
|
2f39a8d76e | ||
|
|
6a3e793500 | ||
|
|
3b3ffeda6b | ||
|
|
f7d92a3b11 | ||
|
|
d9d9ba8bf1 | ||
|
|
f5d9090183 | ||
|
|
705ecd1ef1 | ||
|
|
08b5266a86 | ||
|
|
ecc4846ba8 | ||
|
|
4aab705d11 | ||
|
|
4615a68bcc | ||
|
|
bf6934e8ac | ||
|
|
af8c304bd4 | ||
|
|
51dac5a5a8 | ||
|
|
56463d9e36 | ||
|
|
a6a339dc59 | ||
|
|
8423304ab5 | ||
|
|
bb7408dbe9 | ||
|
|
7eff4dcf02 | ||
|
|
d7ee3fec3d | ||
|
|
5e026a3e8d | ||
|
|
d5e117b89f | ||
|
|
c87a5501df | ||
|
|
7584ebba0b | ||
|
|
66075e3960 | ||
|
|
193ba781a0 | ||
|
|
3e5dd64acc | ||
|
|
d66ab7d389 | ||
|
|
d2e6b27ecd | ||
|
|
0588541357 | ||
|
|
096ea84af6 | ||
|
|
04d0cfd510 | ||
|
|
7653f969ec | ||
|
|
c4ab6a4a8d | ||
|
|
d1ecd1318f | ||
|
|
8d65b1427d | ||
|
|
e693a6057e | ||
|
|
d0aa490ac3 | ||
|
|
0b6cad7d4f | ||
|
|
14e6c6d9a6 | ||
|
|
b2061347a5 | ||
|
|
79979f0a3b | ||
|
|
48d70b2349 | ||
|
|
b1f6309662 | ||
|
|
1acde76292 | ||
|
|
3b4867d7ab | ||
|
|
5ae965f4d3 | ||
|
|
742427b77b | ||
|
|
3d70a101f1 | ||
|
|
99062a5ea3 | ||
|
|
056d87f7ae | ||
|
|
df5a58772c | ||
|
|
e45db05b8e | ||
|
|
d234f74703 | ||
|
|
3ae2a1be4a | ||
|
|
2b828abd90 | ||
|
|
4b598b1575 |
No files matched your search
@@ -0,0 +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.
|
||||
@@ -0,0 +1 @@
|
||||
VITE_BUILD_TYPE = Development
|
||||
@@ -0,0 +1 @@
|
||||
VITE_BUILD_TYPE = Production
|
||||
@@ -0,0 +1,68 @@
|
||||
module.exports = {
|
||||
'env': {
|
||||
'browser': true,
|
||||
'es2021': true,
|
||||
'node': true
|
||||
},
|
||||
'ignorePatterns': ['src/core/', 'src/core.lib/','src/proto/'],
|
||||
'extends': [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended'
|
||||
],
|
||||
'overrides': [
|
||||
{
|
||||
'env': {
|
||||
'node': true
|
||||
},
|
||||
'files': [
|
||||
'.eslintrc.{js,cjs}'
|
||||
],
|
||||
'parserOptions': {
|
||||
'sourceType': 'script'
|
||||
}
|
||||
}
|
||||
],
|
||||
'parser': '@typescript-eslint/parser',
|
||||
'parserOptions': {
|
||||
'ecmaVersion': 'latest',
|
||||
'sourceType': 'module'
|
||||
},
|
||||
'plugins': [
|
||||
'@typescript-eslint',
|
||||
'import'
|
||||
],
|
||||
'settings': {
|
||||
'import/parsers': {
|
||||
'@typescript-eslint/parser': ['.ts']
|
||||
},
|
||||
'import/resolver': {
|
||||
'typescript': {
|
||||
'alwaysTryTypes': true
|
||||
}
|
||||
}
|
||||
},
|
||||
'rules': {
|
||||
'indent': [
|
||||
'error',
|
||||
2
|
||||
],
|
||||
'linebreak-style': [
|
||||
'error',
|
||||
'unix'
|
||||
],
|
||||
'quotes': [
|
||||
'error',
|
||||
'single'
|
||||
],
|
||||
'semi': [
|
||||
'error',
|
||||
'always'
|
||||
],
|
||||
'no-unused-vars': 'off',
|
||||
'no-async-promise-executor': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-var-requires': 'off',
|
||||
'object-curly-spacing': ['error', 'always'],
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
name: Bug 反馈
|
||||
description: 报告可能的 NapCat 异常行为
|
||||
title: '[BUG] '
|
||||
labels: bug
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
欢迎来到 NapCat 的 Issue Tracker!请填写以下表格来提交 Bug。
|
||||
在提交新的 Bug 反馈前,请确保您:
|
||||
* 已经搜索了现有的 issues,并且没有找到可以解决您问题的方法
|
||||
* 不与现有的某一 issue 重复
|
||||
- type: input
|
||||
id: system-version
|
||||
attributes:
|
||||
label: 系统版本
|
||||
description: 运行 QQNT 的系统版本
|
||||
placeholder: Windows 10 Pro Workstation 22H2
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: qqnt-version
|
||||
attributes:
|
||||
label: QQNT 版本
|
||||
description: 可在 QQNT 的「关于」的设置页中找到
|
||||
placeholder: 9.9.7-21804
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: napcat-version
|
||||
attributes:
|
||||
label: NapCat 版本
|
||||
description: 可在 LiteLoaderQQNT 的设置页或是 QQNT 的设置页侧栏中找到
|
||||
placeholder: 1.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: onebot-client-version
|
||||
attributes:
|
||||
label: OneBot 客户端
|
||||
description: 连接至 NapCat 的客户端版本信息
|
||||
placeholder: Overflow 2.16.0-2cf7991-SNAPSHOT
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: 发生了什么?
|
||||
description: 填写你认为的 NapCat 的不正常行为
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: how-reproduce
|
||||
attributes:
|
||||
label: 如何复现
|
||||
description: 填写应当如何操作才能触发这个不正常行为
|
||||
placeholder: |
|
||||
1. xxx
|
||||
2. xxx
|
||||
3. xxx
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: what-expected
|
||||
attributes:
|
||||
label: 期望的结果?
|
||||
description: 填写你认为 NapCat 应当执行的正常行为
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: napcat-log
|
||||
attributes:
|
||||
label: NapCat 运行日志
|
||||
description: 粘贴相关日志内容到此处
|
||||
render: shell
|
||||
- type: textarea
|
||||
id: onebot-client-log
|
||||
attributes:
|
||||
label: OneBot 客户端运行日志
|
||||
description: 粘贴 OneBot 客户端的相关日志内容到此处
|
||||
render: shell
|
||||
@@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
||||
@@ -0,0 +1,74 @@
|
||||
name: "Build"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
if: ${{ startsWith(github.event.head_commit.message, 'build:') }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target_platform: [linux]
|
||||
target_arch: [x64, arm64]
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'NapNeko/NapCatQQ'
|
||||
submodules: true
|
||||
ref: main
|
||||
token: ${{ secrets.NAPCAT_BUILD }}
|
||||
- name: Use Node.js 20.X
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
- name: Build NuCat Linux
|
||||
run: |
|
||||
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
npm run build:prod
|
||||
cd dist
|
||||
npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
cd ..
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }}
|
||||
path: dist
|
||||
build-win32:
|
||||
if: ${{ startsWith(github.event.head_commit.message, 'build:') }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target_platform: [win32]
|
||||
target_arch: [x64]
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'NapNeko/NapCatQQ'
|
||||
submodules: true
|
||||
ref: main
|
||||
token: ${{ secrets.NAPCAT_BUILD }}
|
||||
- name: Use Node.js 20.X
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
- name: Build NuCat Linux
|
||||
run: |
|
||||
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
npm run build:prod
|
||||
cd dist
|
||||
npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
cd ..
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }}
|
||||
path: dist
|
||||
@@ -0,0 +1,138 @@
|
||||
name: "release"
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
check-version:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract version from tag
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
|
||||
|
||||
- name: Use Node.js 20.X
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Check Version
|
||||
run: |
|
||||
ls
|
||||
node ./script/checkVersion.cjs
|
||||
sh ./checkVersion.sh
|
||||
build-linux:
|
||||
needs: [check-version]
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target_platform: [linux]
|
||||
target_arch: [x64, arm64]
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'NapNeko/NapCatQQ'
|
||||
submodules: true
|
||||
ref: main
|
||||
token: ${{ secrets.NAPCAT_BUILD }}
|
||||
- name: Use Node.js 20.X
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Build NuCat Linux
|
||||
run: |
|
||||
export NAPCAT_BUILDSYS=${{ matrix.target_platform }}
|
||||
export NAPCAT_BUILDARCH=${{ matrix.target_arch }}
|
||||
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
npm run build:prod
|
||||
cd dist
|
||||
npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
cd ..
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }}
|
||||
path: dist
|
||||
build-win32:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [check-version]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target_platform: [win32]
|
||||
target_arch: [x64]
|
||||
steps:
|
||||
- name: Clone Main Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'NapNeko/NapCatQQ'
|
||||
submodules: true
|
||||
ref: main
|
||||
token: ${{ secrets.NAPCAT_BUILD }}
|
||||
|
||||
- name: Use Node.js 20.X
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20.x
|
||||
|
||||
- name: Build NuCat Linux
|
||||
run: |
|
||||
export NAPCAT_BUILDSYS=${{ matrix.target_platform }}
|
||||
export NAPCAT_BUILDARCH=${{ matrix.target_arch }}
|
||||
npm i --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
npm run build:prod
|
||||
cd dist
|
||||
npm i --omit=dev --arch=${{ matrix.target_arch }} --platform=${{ matrix.target_platform }}
|
||||
cd ..
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: NapCat.${{ matrix.target_platform }}.${{ matrix.target_arch }}
|
||||
path: dist
|
||||
|
||||
release-napcat:
|
||||
needs: [build-win32,build-linux]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download All Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
- name: Compress subdirectories
|
||||
run: |
|
||||
for dir in */; do
|
||||
base=$(basename "$dir")
|
||||
zip -r "${base}.zip" "$dir"
|
||||
done
|
||||
|
||||
- name: Extract version from tag
|
||||
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
|
||||
|
||||
- name: Clone Changes Log
|
||||
run: curl -o CHANGELOG.md https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/docs/changelogs/CHANGELOG.v${{ env.VERSION }}.md
|
||||
|
||||
- name: Create Release Draft and Upload Artifacts
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: NapCat V${{ env.VERSION }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
body_path: CHANGELOG.md
|
||||
files: |
|
||||
NapCat.win32.x64.zip
|
||||
NapCat.linux.x64.zip
|
||||
NapCat.linux.arm64.zip
|
||||
# NapCat.darwin.x64.zip
|
||||
# NapCat.darwin.arm64.zip
|
||||
draft: true
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# Develop
|
||||
node_modules/
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
out/
|
||||
dist/
|
||||
/src/core.lib/common/
|
||||
/localdebug/
|
||||
|
||||
# Editor
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea/*
|
||||
|
||||
# Build
|
||||
*.db
|
||||
checkVersion.sh
|
||||
@@ -0,0 +1,4 @@
|
||||
[submodule "src/core"]
|
||||
path = src/core
|
||||
url = https://github.com/NapNeko/core.git
|
||||
branch = master
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 NapCatQQ
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,14 +1,33 @@
|
||||
# NapCatQQ
|
||||
<div align="center">
|
||||
<img src="https://socialify.git.ci/NapNeko/NapCatQQ/image?description=1&language=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2FNapNeko%2FNapCatQQ%2Fmain%2Flogo.png&name=1&stargazers=1&theme=Auto" alt="NapCatQQ" width="640" height="320" />
|
||||
</div>
|
||||
|
||||
## 介绍
|
||||
无
|
||||
## 项目介绍
|
||||
|
||||
## 下载与安装
|
||||
前往release获取
|
||||
NapCatQQ 是基于 PC NTQQ 本体实现一套无头 Bot 框架。
|
||||
|
||||
## 使用与配置
|
||||
参考文档
|
||||
名字寓意 瞌睡猫QQ,像睡着了一样在后台低占用运行的无需GUI界面的NTQQ。
|
||||
|
||||
## 开源与安全
|
||||
为了防止过于扩散与违规使用,未来 NapCat 发版都会不公布源码,在未来形势有所转变下可能会发布源码。
|
||||
代码将进行混淆与插桩,请不要违法使用与宣传本项目。
|
||||
## 如何使用
|
||||
|
||||
可前往 [Release](https://github.com/NapNeko/NapCatQQ/releases/) 页面下载最新版本
|
||||
|
||||
**首次使用** 请务必前往 [官方文档](https://napneko.github.io/) 查看使用文档与教程
|
||||
|
||||
|
||||
## 项目声明
|
||||
|
||||
* 请不要在无关地方宣传NapCatQQ,本项目只是用于学习 node 相关知识,切勿用于违法用途
|
||||
|
||||
* NapCat 不会收集用户隐私信息,但是未来可能会为了更好的利于 NapCat 的优化会收集一些设备信息,如 cpu 架构,系统版本等
|
||||
|
||||
## 相关链接
|
||||
[Telegram Link](https://t.me/+nLZEnpne-pQ1OWFl)
|
||||
|
||||
## 鸣谢名单
|
||||
|
||||
[Lagrange](https://github.com/LagrangeDev/Lagrange.Core)
|
||||
|
||||
<!--
|
||||
QQ群:545402644
|
||||
-->
|
||||
@@ -0,0 +1,17 @@
|
||||
# v1.3.3
|
||||
|
||||
QQ Version: Windows 9.9.9-23424 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
* 尝试修复多开崩溃问题
|
||||
* 修复群列表更新问题
|
||||
* 修复兼容性问题支持Win7
|
||||
* 修复下载 http 资源缺少UA
|
||||
* 优化少量消息合并转发速度
|
||||
* 修复加载群通知时出现 getUserDetailInfo timeout 导致程序崩溃
|
||||
|
||||
## 新增与调整
|
||||
* 新增设置群公告 Api: /_send_group_notice
|
||||
* 新增重启实现 包括重启快速登录/普通重启 副作用: 原进程 无法清理
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,18 @@
|
||||
# v1.3.5
|
||||
|
||||
QQ Version: Windows 9.9.9-23424 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
* 优化启动脚本
|
||||
* 修复非管理时群成员减少事件上报 **无法获取操作者与操作类型**
|
||||
* 修复快速重启进程清理问题
|
||||
* 优化配置文件格式 支持自动更新配置 但仍然建议 **备份配置**
|
||||
* 修复正向反向ws多个客户端周期多次心跳问题
|
||||
|
||||
## 新增与调整
|
||||
* 支持WebUi热重载
|
||||
* 新增启动输出WEBUI秘钥
|
||||
* 新增群荣誉信息 /get_group_honor_info
|
||||
* 支持获取群系统消息 /get_group_system_msg
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,11 @@
|
||||
# v1.3.6
|
||||
|
||||
QQ Version: Windows 9.9.9-23424 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
* 修复戳一戳多次上报问题
|
||||
|
||||
## 新增与调整
|
||||
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,15 @@
|
||||
# v1.3.8
|
||||
|
||||
QQ Version: Windows 9.9.9-23873 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
* 优化打包后体积问题
|
||||
* 修复QQ等级获取
|
||||
* 兼容 9.7.x 版本换行符 统一为 \n
|
||||
* 修复处理加群请求 字段异常情况
|
||||
* 修复退群通知问题
|
||||
|
||||
## 新增与调整
|
||||
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,11 @@
|
||||
# v1.3.9
|
||||
|
||||
QQ Version: Windows 9.9.10-23873 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
* 修复QQ等级获取与兼容性问题
|
||||
|
||||
## 新增与调整
|
||||
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,12 @@
|
||||
# v1.4.0
|
||||
|
||||
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
|
||||
## 新增与调整
|
||||
* 支持空间Cookies获取
|
||||
* 支持获取在线设备 API /get_online_clients
|
||||
* 支持图片OCR API: /.ocr_image /ocr_image
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,14 @@
|
||||
# v1.4.1
|
||||
|
||||
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
* 提高部分Api兼容性
|
||||
* 优化日志膨胀问题
|
||||
* 在线状态刷新问题修复
|
||||
## 新增与调整
|
||||
* 支持非管理群 本地记录时间数据 (建议 **备份配置 清空配置 重新配置**)
|
||||
* 新增英译中接口 Api: /translate_en2zh
|
||||
* 新增群文件管理相关扩展接口 Api: /get_group_file_count /get_group_file_list /set_group_file_folder /del_group_file /del_group_file_folder
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,12 @@
|
||||
# v1.4.2
|
||||
|
||||
QQ Version: Windows 9.9.10-24108 / Linux 3.2.7-23361
|
||||
|
||||
## 修复与优化
|
||||
* 修复获取群文件列表Api
|
||||
* 修复退群通知问题
|
||||
|
||||
## 新增与调整
|
||||
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "1.4.1",
|
||||
"scripts": {
|
||||
"watch:dev": "vite --mode development",
|
||||
"watch:prod": "vite --mode production",
|
||||
"build:dev": "vite build --mode development",
|
||||
"build:prod": "vite build --mode production",
|
||||
"build": "npm run build:dev",
|
||||
"build:core": "cd ./src/core && npm run build && cd ../.. && node ./script/copy-core.cjs",
|
||||
"build:webui": "cd ./src/webui && vite build",
|
||||
"watch": "npm run watch:dev",
|
||||
"debug-win": "powershell dist/napcat.ps1",
|
||||
"lint": "eslint --fix src/**/*.{js,ts}",
|
||||
"release": "npm run build:prod",
|
||||
"depend": "cd dist && npm install --omit=dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@log4js-node/log4js-api": "^1.0.2",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-typescript": "^11.1.6",
|
||||
"@types/cors": "^2.8.17",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/figlet": "^1.5.8",
|
||||
"@types/fluent-ffmpeg": "^2.1.24",
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/qrcode-terminal": "^0.12.2",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||
"@typescript-eslint/parser": "^7.4.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"i": "^0.3.7",
|
||||
"javascript-obfuscator": "^4.1.0",
|
||||
"rollup": "^4.13.2",
|
||||
"rollup-plugin-dts": "^6.1.0",
|
||||
"rollup-plugin-obfuscator": "^1.1.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.2.6",
|
||||
"vite-plugin-cp": "^4.0.8",
|
||||
"vite-plugin-dts": "^3.8.2",
|
||||
"vite-tsconfig-paths": "^4.3.2",
|
||||
"@protobuf-ts/plugin": "^2.9.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^8.13.0",
|
||||
"commander": "^12.0.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^5.0.0-beta.2",
|
||||
"fast-xml-parser": "^4.3.6",
|
||||
"file-type": "^19.0.0",
|
||||
"fluent-ffmpeg": "^2.1.2",
|
||||
"image-size": "^1.1.1",
|
||||
"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": "^9.0.1",
|
||||
"ws": "^8.16.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
const fs = require("fs");
|
||||
const process = require("process");
|
||||
|
||||
console.log("[NapCat] [CheckVersion] 开始检测当前仓库版本...");
|
||||
try {
|
||||
const packageJson = require("../package.json");
|
||||
const currentVersion = packageJson.version;
|
||||
const targetVersion = process.env.VERSION;
|
||||
|
||||
console.log("[NapCat] [CheckVersion] currentVersion:", currentVersion, "targetVersion:", targetVersion);
|
||||
|
||||
// 验证 targetVersion 格式
|
||||
if (!targetVersion || typeof targetVersion !== 'string') {
|
||||
console.error("[NapCat] [CheckVersion] 目标版本格式不正确或未设置!");
|
||||
return;
|
||||
}
|
||||
|
||||
// 写入脚本文件的统一函数
|
||||
const writeScriptToFile = (content) => {
|
||||
fs.writeFileSync("./checkVersion.sh", content, { flag: 'w' });
|
||||
console.log("[NapCat] [CheckVersion] checkVersion.sh 文件已更新。");
|
||||
};
|
||||
|
||||
if (currentVersion === targetVersion) {
|
||||
// 不需要更新版本,写入一个简单的脚本
|
||||
const simpleScript = "#!/bin/bash\necho \"CheckVersion Is Done\"";
|
||||
writeScriptToFile(simpleScript);
|
||||
} else {
|
||||
// 更新版本,构建安全的sed命令
|
||||
const safeScriptContent = `
|
||||
#!/bin/bash
|
||||
git config --global user.email "bot@test.wumiao.wang"
|
||||
git config --global user.name "Version"
|
||||
sed -i "s/\\\"version\\\": \\\"${currentVersion}\\\"/\\\"version\\\": \\\"${targetVersion}\\\"/g" package.json
|
||||
git add .
|
||||
git commit -m "chore:version change"
|
||||
git push -u origin main`;
|
||||
writeScriptToFile(safeScriptContent);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("[NapCat] [CheckVersion] 检测过程中发生错误:", error);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
let fs = require('fs');
|
||||
let path = require('path');
|
||||
|
||||
const coreDistDir = path.join(path.resolve(__dirname, '../'), 'src/core/dist/core/src');
|
||||
const coreLibDir = path.join(path.resolve(__dirname, '../'), 'src/core.lib/src');
|
||||
|
||||
function copyDir(currentPath, outputDir) {
|
||||
fs.readdir(currentPath, { withFileTypes: true }, (err, entries) => {
|
||||
if (err?.errno === -4058) return;
|
||||
|
||||
entries.forEach(entry => {
|
||||
const localBasePath = path.join(currentPath, entry.name);
|
||||
const outputLocalBasePath = path.join(outputDir, entry.name);
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
// 如果是目录,递归调用
|
||||
if (!fs.existsSync(outputLocalBasePath)) {
|
||||
fs.mkdirSync(outputLocalBasePath, { recursive: true });
|
||||
}
|
||||
copyDir(localBasePath, outputLocalBasePath);
|
||||
}
|
||||
else{
|
||||
// 如果是文件,直接复制
|
||||
fs.copyFile(localBasePath, outputLocalBasePath, (err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
copyDir(coreDistDir, coreLibDir);
|
||||
@@ -0,0 +1,21 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { version } from '../src/onebot11/version'
|
||||
|
||||
const manifestPath = path.join(__dirname, '../package.json')
|
||||
|
||||
function readManifest (): any {
|
||||
if (fs.existsSync(manifestPath)) {
|
||||
return JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))
|
||||
}
|
||||
}
|
||||
|
||||
function writeManifest (manifest: any) {
|
||||
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))
|
||||
}
|
||||
|
||||
const manifest = readManifest()
|
||||
if (version !== manifest.version) {
|
||||
manifest.version = version
|
||||
writeManifest(manifest)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
chcp 65001
|
||||
set ELECTRON_RUN_AS_NODE=1
|
||||
"H:\Program Files\QQNT最新版\QQ.exe" %~dp0/napcat.cjs %*
|
||||
@@ -0,0 +1,15 @@
|
||||
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 "Error getting UninstallString: $_"
|
||||
}
|
||||
}
|
||||
$params = $args -join " "
|
||||
$QQpath = Get-QQpath
|
||||
$Bootfile = Join-Path (Get-Location) "\dist\inject.cjs"
|
||||
$env:ELECTRON_RUN_AS_NODE = 1
|
||||
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& '$QQpath' --expose-gc $Bootfile $params}"
|
||||
@@ -0,0 +1,17 @@
|
||||
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 {
|
||||
return "D:\QQ.exe"
|
||||
}
|
||||
}
|
||||
$params = $args -join " "
|
||||
$QQpath = Get-QQpath
|
||||
$Bootfile = Join-Path $PSScriptRoot "napcat.cjs"
|
||||
$env:ELECTRON_RUN_AS_NODE = 1
|
||||
$argumentList = '-noexit', '-noprofile', "-command `"$QQpath`" `"$Bootfile`" $params"
|
||||
Start-Process powershell -ArgumentList $argumentList -RedirectStandardOutput "log.txt" -RedirectStandardError "error.txt"
|
||||
powershell Get-Content -Wait -Encoding UTF8 log.txt
|
||||
@@ -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!QQ.exe"
|
||||
set ELECTRON_RUN_AS_NODE=1
|
||||
echo !QQPath!
|
||||
"!QQPath!" ./napcat.mjs %*
|
||||
@@ -0,0 +1,43 @@
|
||||
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)' $Bootfile $params}"
|
||||
@@ -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!QQ.exe"
|
||||
set ELECTRON_RUN_AS_NODE=1
|
||||
echo !QQPath!
|
||||
"!QQPath!" ./napcat.mjs %*
|
||||
@@ -0,0 +1,43 @@
|
||||
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 &{& '$($commandInfo.Path)' $Bootfile $params}"
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
get_script_dir() {
|
||||
local script_path="${1:-$0}"
|
||||
local script_dir
|
||||
script_path=$(readlink -f "$script_path")
|
||||
script_dir=$(dirname "$script_path")
|
||||
|
||||
echo "$script_dir"
|
||||
}
|
||||
|
||||
SCRIPT_DIR=$(get_script_dir)
|
||||
|
||||
export ELECTRON_RUN_AS_NODE=1
|
||||
|
||||
if ! [ -x /opt/QQ/qq ]; then
|
||||
echo "Error: /opt/QQ/qq is not executable or does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
/opt/QQ/qq "${SCRIPT_DIR}/napcat.mjs" "$@"
|
||||
@@ -0,0 +1,124 @@
|
||||
import express, { Express, Request, Response } from 'express';
|
||||
import cors from 'cors';
|
||||
import http from 'http';
|
||||
import { log, logDebug, logError } from '../utils/log';
|
||||
import { ob11Config } from '@/onebot11/config';
|
||||
|
||||
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;
|
||||
|
||||
constructor() {
|
||||
this.expressAPP = express();
|
||||
this.expressAPP.use(cors());
|
||||
this.expressAPP.use(express.urlencoded({ extended: true, limit: '5000mb' }));
|
||||
this.expressAPP.use((req, res, next) => {
|
||||
// 兼容处理没有带content-type的请求
|
||||
// log("req.headers['content-type']", req.headers['content-type'])
|
||||
req.headers['content-type'] = 'application/json';
|
||||
const originalJson = express.json({ limit: '5000mb' });
|
||||
// 调用原始的express.json()处理器
|
||||
originalJson(req, res, (err) => {
|
||||
if (err) {
|
||||
logError('Error parsing JSON:', err);
|
||||
return res.status(400).send('Invalid JSON');
|
||||
}
|
||||
next();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
authorize(req: Request, res: Response, next: () => void) {
|
||||
const serverToken = ob11Config.token;
|
||||
let clientToken = '';
|
||||
const authHeader = req.get('authorization');
|
||||
if (authHeader) {
|
||||
clientToken = authHeader.split('Bearer ').pop() || '';
|
||||
//logDebug('receive http header token', clientToken);
|
||||
} else if (req.query.access_token) {
|
||||
if (Array.isArray(req.query.access_token)) {
|
||||
clientToken = req.query.access_token[0].toString();
|
||||
} else {
|
||||
clientToken = req.query.access_token.toString();
|
||||
}
|
||||
//logDebug('receive http url token', clientToken);
|
||||
}
|
||||
|
||||
if (serverToken && clientToken != serverToken) {
|
||||
return res.status(403).send(JSON.stringify({ message: 'token verify failed!' }));
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
start(port: number, host: string) {
|
||||
try {
|
||||
this.expressAPP.get('/', (req: Request, res: Response) => {
|
||||
res.send(`${this.name}已启动`);
|
||||
});
|
||||
this.listen(port, host);
|
||||
} catch (e: any) {
|
||||
logError('HTTP服务启动失败', e.toString());
|
||||
// httpServerError = "HTTP服务启动失败, " + e.toString()
|
||||
}
|
||||
}
|
||||
|
||||
stop() {
|
||||
// httpServerError = ""
|
||||
if (this.server) {
|
||||
this.server.close();
|
||||
this.server = null;
|
||||
}
|
||||
}
|
||||
|
||||
restart(port: number, host: string) {
|
||||
this.stop();
|
||||
this.start(port, host);
|
||||
}
|
||||
|
||||
abstract handleFailed(res: Response, payload: any, err: any): void
|
||||
|
||||
registerRouter(method: 'post' | 'get' | string, url: string, handler: RegisterHandler) {
|
||||
if (!url.startsWith('/')) {
|
||||
url = '/' + url;
|
||||
}
|
||||
|
||||
// @ts-expect-error wait fix
|
||||
if (!this.expressAPP[method]) {
|
||||
const err = `${this.name} register router failed,${method} not exist`;
|
||||
logError(err);
|
||||
throw err;
|
||||
}
|
||||
// @ts-expect-error wait fix
|
||||
this.expressAPP[method](url, this.authorize, async (req: Request, res: Response) => {
|
||||
let payload = req.body;
|
||||
if (method == 'get') {
|
||||
payload = req.query;
|
||||
} else if (req.query) {
|
||||
payload = { ...req.query, ...req.body };
|
||||
}
|
||||
logDebug('收到http请求', url, payload);
|
||||
try {
|
||||
res.send(await handler(res, payload));
|
||||
} catch (e: any) {
|
||||
this.handleFailed(res, payload, e.stack.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected listen(port: number, host: string = '0.0.0.0') {
|
||||
host = host || '0.0.0.0';
|
||||
try {
|
||||
this.server = this.expressAPP.listen(port, host, () => {
|
||||
const info = `${this.name} started ${host}:${port}`;
|
||||
log(info);
|
||||
}).on('error', (err) => {
|
||||
logError('HTTP服务启动失败', err.toString());
|
||||
});
|
||||
} catch (e: any) {
|
||||
logError('HTTP服务启动失败, 请检查监听的ip地址和端口', e.stack.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import { WebSocket, WebSocketServer } from 'ws';
|
||||
import urlParse from 'url';
|
||||
import { IncomingMessage } from 'node:http';
|
||||
import { log } from '@/common/utils/log';
|
||||
|
||||
class WebsocketClientBase {
|
||||
private wsClient: WebSocket | undefined;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
send(msg: string) {
|
||||
if (this.wsClient && this.wsClient.readyState == WebSocket.OPEN) {
|
||||
this.wsClient.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
onMessage(msg: string) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class WebsocketServerBase {
|
||||
private ws: WebSocketServer | null = null;
|
||||
public token: string = '';
|
||||
|
||||
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());
|
||||
}
|
||||
this.ws.on('connection', (wsClient, req) => {
|
||||
const url: string = req.url!.split('?').shift() || '/';
|
||||
this.authorize(wsClient, req);
|
||||
this.onConnect(wsClient, url, req);
|
||||
wsClient.on('message', async (msg) => {
|
||||
this.onMessage(wsClient, url, msg.toString());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.ws && this.ws.close((err) => {
|
||||
log('ws server close failed!', err);
|
||||
});
|
||||
this.ws = null;
|
||||
}
|
||||
|
||||
restart(port: number) {
|
||||
this.stop();
|
||||
this.start(port);
|
||||
}
|
||||
|
||||
authorize(wsClient: WebSocket, req: IncomingMessage) {
|
||||
const url = req.url!.split('?').shift();
|
||||
log('ws connect', url);
|
||||
let clientToken: string = '';
|
||||
const authHeader = req.headers['authorization'];
|
||||
if (authHeader) {
|
||||
clientToken = authHeader.split('Bearer ').pop() || '';
|
||||
log('receive ws header token', clientToken);
|
||||
} else {
|
||||
const parsedUrl = urlParse.parse(req.url || '/', true);
|
||||
const urlToken = parsedUrl.query.access_token;
|
||||
if (urlToken) {
|
||||
if (Array.isArray(urlToken)) {
|
||||
clientToken = urlToken[0];
|
||||
} else {
|
||||
clientToken = urlToken;
|
||||
}
|
||||
log('receive ws url token', clientToken);
|
||||
}
|
||||
}
|
||||
if (this.token && clientToken != this.token) {
|
||||
this.authorizeFailed(wsClient);
|
||||
return wsClient.close();
|
||||
}
|
||||
}
|
||||
|
||||
authorizeFailed(wsClient: WebSocket) {
|
||||
|
||||
}
|
||||
|
||||
onConnect(wsClient: WebSocket, url: string, req: IncomingMessage) {
|
||||
|
||||
}
|
||||
|
||||
onMessage(wsClient: WebSocket, url: string, msg: string) {
|
||||
|
||||
}
|
||||
|
||||
sendHeart() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { sleep } from '@/common/utils/helper';
|
||||
|
||||
type AsyncQueueTask = (() => void) | (()=>Promise<void>);
|
||||
|
||||
|
||||
export class AsyncQueue {
|
||||
private tasks: (AsyncQueueTask)[] = [];
|
||||
|
||||
public addTask(task: AsyncQueueTask) {
|
||||
this.tasks.push(task);
|
||||
// console.log('addTask', this.tasks.length);
|
||||
if (this.tasks.length === 1) {
|
||||
this.runQueue().then().catch(()=>{});
|
||||
}
|
||||
}
|
||||
|
||||
private async runQueue() {
|
||||
// console.log('runQueue', this.tasks.length);
|
||||
while (this.tasks.length > 0) {
|
||||
const task = this.tasks[0];
|
||||
// console.log('typeof task', typeof task);
|
||||
try {
|
||||
const taskRet = task();
|
||||
// console.log('type of taskRet', typeof taskRet, taskRet);
|
||||
if (taskRet instanceof Promise) {
|
||||
await taskRet;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
this.tasks.shift();
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { log, logDebug, logError } from '@/common/utils/log';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const configDir = path.resolve(__dirname, 'config');
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
|
||||
|
||||
export class ConfigBase<T>{
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
protected getKeys(): string[] | null {
|
||||
// 决定 key 在json配置文件中的顺序
|
||||
return null;
|
||||
}
|
||||
|
||||
getConfigDir(){
|
||||
const configDir = path.resolve(__dirname, 'config');
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
return configDir;
|
||||
}
|
||||
getConfigPath(): string {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
read() {
|
||||
const configPath = this.getConfigPath();
|
||||
if (!fs.existsSync(configPath)) {
|
||||
try{
|
||||
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
|
||||
log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`);
|
||||
}
|
||||
catch (e: any) {
|
||||
logError(`创建配置文件 ${configPath} 时发生错误:`, e.message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
try {
|
||||
const data = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||
logDebug(`配置文件${configPath}已加载`, data);
|
||||
Object.assign(this, data);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
this.save(this); // 保存一次,让新版本的字段写入
|
||||
return this;
|
||||
} catch (e: any) {
|
||||
if (e instanceof SyntaxError) {
|
||||
logError(`配置文件 ${configPath} 格式错误,请检查配置文件:`, e.message);
|
||||
} else {
|
||||
logError(`读取配置文件 ${configPath} 时发生错误:`, e.message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
save(config: T) {
|
||||
Object.assign(this, config);
|
||||
const configPath = this.getConfigPath();
|
||||
try {
|
||||
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
|
||||
} catch (e: any) {
|
||||
logError(`保存配置文件 ${configPath} 时发生错误:`, e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
import { logError, logDebug } from "@/common/utils/log";
|
||||
|
||||
type group_id = number;
|
||||
type user_id = number;
|
||||
|
||||
class cacheNode<T> {
|
||||
value: T;
|
||||
groupId: group_id;
|
||||
userId: user_id;
|
||||
prev: cacheNode<T> | null;
|
||||
next: cacheNode<T> | null;
|
||||
timestamp: number;
|
||||
|
||||
constructor(groupId: group_id, userId: user_id, value: T) {
|
||||
this.groupId = groupId;
|
||||
this.userId = userId;
|
||||
this.value = value;
|
||||
this.prev = null;
|
||||
this.next = null;
|
||||
this.timestamp = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
type cache<T> = { [key: group_id]: { [key: user_id]: cacheNode<T> } };
|
||||
class LRU<T> {
|
||||
private maxAge: number;
|
||||
private maxSize: number;
|
||||
private currentSize: number;
|
||||
private cache: cache<T>;
|
||||
private head: cacheNode<T> | null = null;
|
||||
private tail: cacheNode<T> | null = null;
|
||||
private onFuncs: ((node: cacheNode<T>) => void)[] = [];
|
||||
|
||||
constructor(maxAge: number = 2e4, maxSize: number = 5e3) {
|
||||
this.maxAge = maxAge;
|
||||
this.maxSize = maxSize;
|
||||
this.cache = Object.create(null);
|
||||
this.currentSize = 0;
|
||||
|
||||
if (maxSize == 0) return;
|
||||
setInterval(() => this.removeExpired(), this.maxAge);
|
||||
}
|
||||
|
||||
// 移除LRU节点
|
||||
private removeLRUNode(node: cacheNode<T>) {
|
||||
logDebug(
|
||||
"removeLRUNode",
|
||||
node.groupId,
|
||||
node.userId,
|
||||
node.value,
|
||||
this.currentSize
|
||||
);
|
||||
node.prev = node.next = null;
|
||||
delete this.cache[node.groupId][node.userId];
|
||||
this.removeNode(node);
|
||||
this.onFuncs.forEach((func) => func(node));
|
||||
this.currentSize--;
|
||||
}
|
||||
|
||||
public on(func: (node: cacheNode<T>) => void) {
|
||||
this.onFuncs.push(func);
|
||||
}
|
||||
|
||||
private removeExpired() {
|
||||
const now = Date.now();
|
||||
let current = this.tail;
|
||||
const nodesToRemove: cacheNode<T>[] = [];
|
||||
let removedCount = 0;
|
||||
|
||||
// 收集需要删除的节点
|
||||
while (current && now - current.timestamp > this.maxAge) {
|
||||
nodesToRemove.push(current);
|
||||
current = current.prev;
|
||||
removedCount++;
|
||||
if (removedCount >= 100) break;
|
||||
}
|
||||
|
||||
// 更新链表指向
|
||||
if (nodesToRemove.length > 0) {
|
||||
const newTail = nodesToRemove[nodesToRemove.length - 1].prev;
|
||||
if (newTail) {
|
||||
newTail.next = null;
|
||||
} else {
|
||||
this.head = null;
|
||||
}
|
||||
this.tail = newTail;
|
||||
}
|
||||
|
||||
nodesToRemove.forEach((node) => {
|
||||
node.prev = node.next = null;
|
||||
delete this.cache[node.groupId][node.userId];
|
||||
|
||||
this.currentSize--;
|
||||
this.onFuncs.forEach((func) => func(node));
|
||||
});
|
||||
}
|
||||
|
||||
private addNode(node: cacheNode<T>) {
|
||||
node.next = this.head;
|
||||
if (this.head) this.head.prev = node;
|
||||
if (!this.tail) this.tail = node;
|
||||
this.head = node;
|
||||
}
|
||||
|
||||
private removeNode(node: cacheNode<T>) {
|
||||
if (node.prev) node.prev.next = node.next;
|
||||
if (node.next) node.next.prev = node.prev;
|
||||
if (node === this.head) this.head = node.next;
|
||||
if (node === this.tail) this.tail = node.prev;
|
||||
}
|
||||
|
||||
private moveToHead(node: cacheNode<T>) {
|
||||
if (this.head === node) return;
|
||||
|
||||
this.removeNode(node);
|
||||
this.addNode(node);
|
||||
node.prev = null;
|
||||
}
|
||||
|
||||
public set(groupId: group_id, userId: user_id, value: T) {
|
||||
if (!this.cache[groupId]) {
|
||||
this.cache[groupId] = Object.create(null);
|
||||
}
|
||||
|
||||
const groupObject = this.cache[groupId];
|
||||
|
||||
if (groupObject[userId]) {
|
||||
const node = groupObject[userId];
|
||||
node.value = value;
|
||||
node.timestamp = Date.now();
|
||||
this.moveToHead(node);
|
||||
} else {
|
||||
const node = new cacheNode(groupId, userId, value);
|
||||
groupObject[userId] = node;
|
||||
this.currentSize++;
|
||||
this.addNode(node);
|
||||
if (this.currentSize > this.maxSize) {
|
||||
const tail = this.tail!;
|
||||
this.removeLRUNode(tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default LRU;
|
||||
@@ -0,0 +1,72 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import { systemPlatform } from '@/common/utils/system';
|
||||
|
||||
export const exePath = process.execPath;
|
||||
|
||||
export const pkgInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'package.json');
|
||||
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') {
|
||||
throw new Error('Something went wrong when load QQ info path');
|
||||
}
|
||||
|
||||
export { configVersionInfoPath };
|
||||
|
||||
type QQPkgInfo = {
|
||||
version: string;
|
||||
buildVersion: string;
|
||||
platform: string;
|
||||
eleArch: string;
|
||||
}
|
||||
type QQVersionConfigInfo = {
|
||||
baseVersion: string;
|
||||
curVersion: string;
|
||||
prevVersion: string;
|
||||
onErrorVersions: Array<any>;
|
||||
buildId: string;
|
||||
}
|
||||
|
||||
let _qqVersionConfigInfo: QQVersionConfigInfo = {
|
||||
'baseVersion': '9.9.9-23361',
|
||||
'curVersion': '9.9.9-23361',
|
||||
'prevVersion': '',
|
||||
'onErrorVersions': [],
|
||||
'buildId': '23361'
|
||||
};
|
||||
|
||||
if (fs.existsSync(configVersionInfoPath)) {
|
||||
try {
|
||||
const _ =JSON.parse(fs.readFileSync(configVersionInfoPath).toString());
|
||||
_qqVersionConfigInfo = Object.assign(_qqVersionConfigInfo, _);
|
||||
} catch (e) {
|
||||
console.error('Load QQ version config info failed, Use default version', e);
|
||||
}
|
||||
}
|
||||
|
||||
export const qqVersionConfigInfo: QQVersionConfigInfo = _qqVersionConfigInfo;
|
||||
|
||||
export const qqPkgInfo: QQPkgInfo = JSON.parse(fs.readFileSync(pkgInfoPath).toString());
|
||||
// platform_type: 3,
|
||||
// app_type: 4,
|
||||
// app_version: '9.9.9-23159',
|
||||
// qua: 'V1_WIN_NQ_9.9.9_23159_GW_B',
|
||||
// appid: '537213764',
|
||||
// platVer: '10.0.26100',
|
||||
// clientVer: '9.9.9-23159',
|
||||
|
||||
let _appid: string = '537213803'; // 默认为 Windows 平台的 appid
|
||||
if (systemPlatform === 'linux') {
|
||||
_appid = '537213827';
|
||||
}
|
||||
// todo: mac 平台的 appid
|
||||
export const appid = _appid;
|
||||
@@ -0,0 +1,135 @@
|
||||
import fs from 'fs';
|
||||
import { encode, getDuration, getWavFileInfo, isWav } 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 { spawn } from 'node:child_process';
|
||||
import { getTempDir } from '@/common/utils/file';
|
||||
|
||||
let TEMP_DIR = './';
|
||||
setTimeout(() => {
|
||||
TEMP_DIR = getTempDir();
|
||||
}, 100);
|
||||
export async function encodeSilk(filePath: string) {
|
||||
function getFileHeader(filePath: string) {
|
||||
// 定义要读取的字节数
|
||||
const bytesToRead = 7;
|
||||
try {
|
||||
const buffer = fs.readFileSync(filePath, {
|
||||
encoding: null,
|
||||
flag: 'r',
|
||||
});
|
||||
|
||||
const fileHeader = buffer.toString('hex', 0, bytesToRead);
|
||||
return fileHeader;
|
||||
} catch (err) {
|
||||
console.error('读取文件错误:', err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async function isWavFile(filePath: string) {
|
||||
return isWav(fs.readFileSync(filePath));
|
||||
}
|
||||
|
||||
async function guessDuration(pttPath: string) {
|
||||
const pttFileInfo = await fsPromise.stat(pttPath);
|
||||
let duration = pttFileInfo.size / 1024 / 3; // 3kb/s
|
||||
duration = Math.floor(duration);
|
||||
duration = Math.max(1, duration);
|
||||
log('通过文件大小估算语音的时长:', duration);
|
||||
return duration;
|
||||
}
|
||||
|
||||
// function verifyDuration(oriDuration: number, guessDuration: number) {
|
||||
// // 单位都是秒
|
||||
// if (oriDuration - guessDuration > 10) {
|
||||
// return guessDuration
|
||||
// }
|
||||
// oriDuration = Math.max(1, oriDuration)
|
||||
// return oriDuration
|
||||
// }
|
||||
// async function getAudioSampleRate(filePath: string) {
|
||||
// try {
|
||||
// const mm = await import('music-metadata');
|
||||
// const metadata = await mm.parseFile(filePath);
|
||||
// log(`${filePath}采样率`, metadata.format.sampleRate);
|
||||
// return metadata.format.sampleRate;
|
||||
// } catch (error) {
|
||||
// log(`${filePath}采样率获取失败`, error.stack);
|
||||
// // console.error(error);
|
||||
// }
|
||||
// }
|
||||
|
||||
try {
|
||||
const pttPath = path.join(TEMP_DIR, uuidv4());
|
||||
if (getFileHeader(filePath) !== '02232153494c4b') {
|
||||
log(`语音文件${filePath}需要转换成silk`);
|
||||
const _isWav = await isWavFile(filePath);
|
||||
const pcmPath = pttPath + '.pcm';
|
||||
let sampleRate = 0;
|
||||
const convert = () => {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
// todo: 通过配置文件获取ffmpeg路径
|
||||
const ffmpegPath = process.env.FFMPEG_PATH || 'ffmpeg';
|
||||
const cp = spawn(ffmpegPath, ['-y', '-i', filePath, '-ar', '24000', '-ac', '1', '-f', 's16le', pcmPath]);
|
||||
cp.on('error', err => {
|
||||
log('FFmpeg处理转换出错: ', err.message);
|
||||
return reject(err);
|
||||
});
|
||||
cp.on('exit', (code, signal) => {
|
||||
const EXIT_CODES = [0, 255];
|
||||
if (code == null || EXIT_CODES.includes(code)) {
|
||||
sampleRate = 24000;
|
||||
const data = fs.readFileSync(pcmPath);
|
||||
fs.unlink(pcmPath, (err) => {
|
||||
});
|
||||
return resolve(data);
|
||||
}
|
||||
log(`FFmpeg exit: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`);
|
||||
reject(Error('FFmpeg处理转换失败'));
|
||||
});
|
||||
});
|
||||
};
|
||||
let input: Buffer;
|
||||
if (!_isWav) {
|
||||
input = await convert();
|
||||
} else {
|
||||
input = fs.readFileSync(filePath);
|
||||
const allowSampleRate = [8000, 12000, 16000, 24000, 32000, 44100, 48000];
|
||||
const { fmt } = getWavFileInfo(input);
|
||||
// log(`wav文件信息`, fmt)
|
||||
if (!allowSampleRate.includes(fmt.sampleRate)) {
|
||||
input = await convert();
|
||||
}
|
||||
}
|
||||
const silk = await encode(input, sampleRate);
|
||||
fs.writeFileSync(pttPath, silk.data);
|
||||
log(`语音文件${filePath}转换成功!`, pttPath, '时长:', silk.duration);
|
||||
return {
|
||||
converted: true,
|
||||
path: pttPath,
|
||||
duration: silk.duration / 1000
|
||||
};
|
||||
} else {
|
||||
const silk = fs.readFileSync(filePath);
|
||||
let duration = 0;
|
||||
try {
|
||||
duration = getDuration(silk) / 1000;
|
||||
} catch (e: any) {
|
||||
log('获取语音文件时长失败, 使用文件大小推测时长', filePath, e.stack);
|
||||
duration = await guessDuration(filePath);
|
||||
}
|
||||
|
||||
return {
|
||||
converted: false,
|
||||
path: filePath,
|
||||
duration,
|
||||
};
|
||||
}
|
||||
} catch (error: any) {
|
||||
logError('convert silk failed', error.stack);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import * as os from 'os';
|
||||
import path from 'node:path';
|
||||
import fs from 'fs';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
export function getModuleWithArchName(moduleName: string) {
|
||||
const systemPlatform = os.platform();
|
||||
const cpuArch = os.arch();
|
||||
return `${moduleName}-${systemPlatform}-${cpuArch}.node`;
|
||||
}
|
||||
|
||||
export function cpModule(moduleName: string) {
|
||||
const currentDir = path.resolve(__dirname);
|
||||
const fileName = `./${getModuleWithArchName(moduleName)}`;
|
||||
try {
|
||||
fs.copyFileSync(path.join(currentDir, fileName), path.join(currentDir, `${moduleName}.node`));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
// 接收到的临时会话消息uid
|
||||
const createTempUinTableSQL = `
|
||||
CREATE TABLE IF NOT EXISTS temp_uins (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
uid TEXT,
|
||||
uin TEXT
|
||||
)`;
|
||||
this.db!.run(createTempUinTableSQL, function (err) {
|
||||
if (err) {
|
||||
logError('Could not create table temp_uins', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async getCurrentMaxShortId() {
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
this.db!.get('SELECT MAX(shortId) as maxId FROM msgs', (err, row: { maxId: number }) => {
|
||||
if (err) {
|
||||
logDebug('Could not get max short id, Use default -2147483640', err);
|
||||
return resolve(-2147483640);
|
||||
}
|
||||
logDebug('数据库中消息最大短id', row?.maxId);
|
||||
resolve(row?.maxId ?? -2147483640);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async getMsg(query: string, params: any[]) {
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 被动收到的临时会话消息uin->uid
|
||||
async getReceivedTempUinMap() {
|
||||
const stmt = 'SELECT * FROM temp_uins';
|
||||
return new Promise<Record<string, string>>((resolve, reject) => {
|
||||
this.db!.all(stmt, (err, rows: { uin: string, uid: string }[]) => {
|
||||
if (err) {
|
||||
logError('db could not get temp uin map', err);
|
||||
reject(err);
|
||||
}
|
||||
const map: Record<string, string> = {};
|
||||
rows.forEach(row => {
|
||||
map[row.uin] = row.uid;
|
||||
});
|
||||
resolve(map);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 通过uin获取临时会话消息uid
|
||||
async getUidByTempUin(uid: string) {
|
||||
const stmt = 'SELECT * FROM temp_uins WHERE uin = ?';
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
this.db!.get(stmt, [uid], (err, row: { uin: string, uid: string }) => {
|
||||
if (err) {
|
||||
logError('db could not get temp uin map', err);
|
||||
reject(err);
|
||||
}
|
||||
resolve(row?.uid);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async addTempUin(uin: string, uid: string) {
|
||||
const existUid = await this.getUidByTempUin(uin);
|
||||
if (!existUid) {
|
||||
const stmt = this.db!.prepare('INSERT INTO temp_uins (uin, uid) VALUES (?, ?)');
|
||||
return new Promise((resolve, reject) => {
|
||||
stmt.run(uin, uid, function (err: any) {
|
||||
if (err) {
|
||||
logError('db could not add temp uin', 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(),
|
||||
console.log("插入入群时间失败", userId, groupId);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const dbUtil = new DBUtil();
|
||||
@@ -0,0 +1,273 @@
|
||||
import fs from 'fs';
|
||||
import fsPromise from 'fs/promises';
|
||||
import crypto from 'crypto';
|
||||
import util from 'util';
|
||||
import path from 'node:path';
|
||||
import { log } from './log';
|
||||
import { dbUtil } from '@/common/utils/db';
|
||||
import * as fileType from 'file-type';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { napCatCore } from '@/core';
|
||||
|
||||
export const getNapCatDir = () => {
|
||||
const p = path.join(napCatCore.dataPath, 'NapCat');
|
||||
fs.mkdirSync(p, { recursive: true });
|
||||
return p;
|
||||
};
|
||||
export const getTempDir = () => {
|
||||
const p = path.join(getNapCatDir(), 'temp');
|
||||
// 创建临时目录
|
||||
if (!fs.existsSync(p)) {
|
||||
fs.mkdirSync(p, { recursive: true });
|
||||
}
|
||||
return p;
|
||||
};
|
||||
|
||||
|
||||
export function isGIF(path: string) {
|
||||
const buffer = Buffer.alloc(4);
|
||||
const fd = fs.openSync(path, 'r');
|
||||
fs.readSync(fd, buffer, 0, 4, 0);
|
||||
fs.closeSync(fd);
|
||||
return buffer.toString() === 'GIF8';
|
||||
}
|
||||
|
||||
// 定义一个异步函数来检查文件是否存在
|
||||
export function checkFileReceived(path: string, timeout: number = 3000): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
function check() {
|
||||
if (fs.existsSync(path)) {
|
||||
resolve();
|
||||
} else if (Date.now() - startTime > timeout) {
|
||||
reject(new Error(`文件不存在: ${path}`));
|
||||
} else {
|
||||
setTimeout(check, 100);
|
||||
}
|
||||
}
|
||||
|
||||
check();
|
||||
});
|
||||
}
|
||||
|
||||
export async function file2base64(path: string) {
|
||||
const readFile = util.promisify(fs.readFile);
|
||||
const result = {
|
||||
err: '',
|
||||
data: ''
|
||||
};
|
||||
try {
|
||||
// 读取文件内容
|
||||
// if (!fs.existsSync(path)){
|
||||
// path = path.replace("\\Ori\\", "\\Thumb\\");
|
||||
// }
|
||||
try {
|
||||
await checkFileReceived(path, 5000);
|
||||
} catch (e: any) {
|
||||
result.err = e.toString();
|
||||
return result;
|
||||
}
|
||||
const data = await readFile(path);
|
||||
// 转换为Base64编码
|
||||
result.data = data.toString('base64');
|
||||
} catch (err: any) {
|
||||
result.err = err.toString();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
export function calculateFileMD5(filePath: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建一个流式读取器
|
||||
const stream = fs.createReadStream(filePath);
|
||||
const hash = crypto.createHash('md5');
|
||||
|
||||
stream.on('data', (data: Buffer) => {
|
||||
// 当读取到数据时,更新哈希对象的状态
|
||||
hash.update(data);
|
||||
});
|
||||
|
||||
stream.on('end', () => {
|
||||
// 文件读取完成,计算哈希
|
||||
const md5 = hash.digest('hex');
|
||||
resolve(md5);
|
||||
});
|
||||
|
||||
stream.on('error', (err: Error) => {
|
||||
// 处理可能的读取错误
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export interface HttpDownloadOptions {
|
||||
url: string;
|
||||
headers?: Record<string, string> | string;
|
||||
}
|
||||
|
||||
export async function httpDownload(options: string | HttpDownloadOptions): Promise<Buffer> {
|
||||
const chunks: Buffer[] = [];
|
||||
let url: string;
|
||||
let headers: Record<string, string> = {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36'
|
||||
};
|
||||
if (typeof options === 'string') {
|
||||
url = options;
|
||||
} else {
|
||||
url = options.url;
|
||||
if (options.headers) {
|
||||
if (typeof options.headers === 'string') {
|
||||
headers = JSON.parse(options.headers);
|
||||
} else {
|
||||
headers = options.headers;
|
||||
}
|
||||
}
|
||||
}
|
||||
const fetchRes = await fetch(url, { headers });
|
||||
if (!fetchRes.ok) throw new Error(`下载文件失败: ${fetchRes.statusText}`);
|
||||
|
||||
const blob = await fetchRes.blob();
|
||||
const buffer = await blob.arrayBuffer();
|
||||
return Buffer.from(buffer);
|
||||
}
|
||||
|
||||
type Uri2LocalRes = {
|
||||
success: boolean,
|
||||
errMsg: string,
|
||||
fileName: string,
|
||||
ext: string,
|
||||
path: string,
|
||||
isLocal: boolean
|
||||
}
|
||||
|
||||
export async function uri2local(uri: string, fileName: string | null = null): Promise<Uri2LocalRes> {
|
||||
const res = {
|
||||
success: false,
|
||||
errMsg: '',
|
||||
fileName: '',
|
||||
ext: '',
|
||||
path: '',
|
||||
isLocal: false
|
||||
};
|
||||
if (!fileName) {
|
||||
fileName = uuidv4();
|
||||
}
|
||||
let filePath = path.join(getTempDir(), fileName);
|
||||
let url = null;
|
||||
try {
|
||||
url = new URL(uri);
|
||||
} catch (e: any) {
|
||||
res.errMsg = `uri ${uri} 解析失败,` + e.toString() + ` 可能${uri}不存在`;
|
||||
return res;
|
||||
}
|
||||
|
||||
// log("uri protocol", url.protocol, uri);
|
||||
if (url.protocol == 'base64:') {
|
||||
// base64转成文件
|
||||
const base64Data = uri.split('base64://')[1];
|
||||
try {
|
||||
const buffer = Buffer.from(base64Data, 'base64');
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
|
||||
} catch (e: any) {
|
||||
res.errMsg = 'base64文件下载失败,' + e.toString();
|
||||
return res;
|
||||
}
|
||||
} else if (url.protocol == 'http:' || url.protocol == 'https:') {
|
||||
// 下载文件
|
||||
let buffer: Buffer | null = null;
|
||||
try {
|
||||
buffer = await httpDownload(uri);
|
||||
} catch (e: any) {
|
||||
res.errMsg = `${url}下载失败,` + e.toString();
|
||||
return res;
|
||||
}
|
||||
try {
|
||||
const pathInfo = path.parse(decodeURIComponent(url.pathname));
|
||||
if (pathInfo.name) {
|
||||
fileName = pathInfo.name;
|
||||
if (pathInfo.ext) {
|
||||
fileName += pathInfo.ext;
|
||||
// res.ext = pathInfo.ext
|
||||
}
|
||||
}
|
||||
fileName = fileName.replace(/[/\\:*?"<>|]/g, '_');
|
||||
res.fileName = fileName;
|
||||
filePath = path.join(getTempDir(), uuidv4() + fileName);
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
} catch (e: any) {
|
||||
res.errMsg = `${url}下载失败,` + e.toString();
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
let pathname: string;
|
||||
if (url.protocol === 'file:') {
|
||||
// await fs.copyFile(url.pathname, filePath);
|
||||
pathname = decodeURIComponent(url.pathname);
|
||||
if (process.platform === 'win32') {
|
||||
filePath = pathname.slice(1);
|
||||
} else {
|
||||
filePath = pathname;
|
||||
}
|
||||
} else {
|
||||
const cache = await dbUtil.getFileCacheByName(uri);
|
||||
if (cache) {
|
||||
filePath = cache.path;
|
||||
} else {
|
||||
filePath = uri;
|
||||
}
|
||||
}
|
||||
|
||||
res.isLocal = true;
|
||||
}
|
||||
// else{
|
||||
// res.errMsg = `不支持的file协议,` + url.protocol
|
||||
// return res
|
||||
// }
|
||||
// if (isGIF(filePath) && !res.isLocal) {
|
||||
// await fs.rename(filePath, filePath + ".gif");
|
||||
// filePath += ".gif";
|
||||
// }
|
||||
if (!res.isLocal && !res.ext) {
|
||||
try {
|
||||
const ext: string | undefined = (await fileType.fileTypeFromFile(filePath))?.ext;
|
||||
if (ext) {
|
||||
log('获取文件类型', ext, filePath);
|
||||
fs.renameSync(filePath, filePath + `.${ext}`);
|
||||
filePath += `.${ext}`;
|
||||
res.fileName += `.${ext}`;
|
||||
res.ext = ext;
|
||||
}
|
||||
} catch (e) {
|
||||
// log("获取文件类型失败", filePath,e.stack)
|
||||
}
|
||||
}
|
||||
res.success = true;
|
||||
res.path = filePath;
|
||||
return res;
|
||||
}
|
||||
|
||||
export async function copyFolder(sourcePath: string, destPath: string) {
|
||||
try {
|
||||
const entries = await fsPromise.readdir(sourcePath, { withFileTypes: true });
|
||||
await fsPromise.mkdir(destPath, { recursive: true });
|
||||
for (const entry of entries) {
|
||||
const srcPath = path.join(sourcePath, entry.name);
|
||||
const dstPath = path.join(destPath, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
await copyFolder(srcPath, dstPath);
|
||||
} else {
|
||||
try {
|
||||
await fsPromise.copyFile(srcPath, dstPath);
|
||||
} catch (error) {
|
||||
console.error(`无法复制文件 '${srcPath}' 到 '${dstPath}': ${error}`);
|
||||
// 这里可以决定是否要继续复制其他文件
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('复制文件夹时出错:', error);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
import crypto from 'node:crypto';
|
||||
import path from 'node:path';
|
||||
import fs from 'fs/promises';
|
||||
import { log, logDebug } from './log';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function getMd5(s: string) {
|
||||
|
||||
const h = crypto.createHash('md5');
|
||||
h.update(s);
|
||||
return h.digest('hex');
|
||||
}
|
||||
|
||||
export function isNull(value: any) {
|
||||
return value === undefined || value === null;
|
||||
}
|
||||
|
||||
export function isNumeric(str: string) {
|
||||
return /^\d+$/.test(str);
|
||||
}
|
||||
|
||||
export function truncateString(obj: any, maxLength = 500) {
|
||||
if (obj !== null && typeof obj === 'object') {
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (typeof obj[key] === 'string') {
|
||||
// 如果是字符串且超过指定长度,则截断
|
||||
if (obj[key].length > maxLength) {
|
||||
obj[key] = obj[key].substring(0, maxLength) + '...';
|
||||
}
|
||||
} else if (typeof obj[key] === 'object') {
|
||||
// 如果是对象或数组,则递归调用
|
||||
truncateString(obj[key], maxLength);
|
||||
}
|
||||
});
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 函数缓存装饰器,根据方法名、参数、自定义key生成缓存键,在一定时间内返回缓存结果
|
||||
* @param ttl 超时时间,单位毫秒
|
||||
* @param customKey 自定义缓存键前缀,可为空,防止方法名参数名一致时导致缓存键冲突
|
||||
* @returns 处理后缓存或调用原方法的结果
|
||||
*/
|
||||
export function cacheFunc(ttl: number, customKey: string = '') {
|
||||
const cache = new Map<string, { expiry: number; value: any }>();
|
||||
|
||||
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor {
|
||||
const originalMethod = descriptor.value;
|
||||
const className = target.constructor.name; // 获取类名
|
||||
const methodName = propertyKey; // 获取方法名
|
||||
descriptor.value = async function (...args: any[]) {
|
||||
const cacheKey = `${customKey}${className}.${methodName}:${JSON.stringify(args)}`;
|
||||
const cached = cache.get(cacheKey);
|
||||
if (cached && cached.expiry > Date.now()) {
|
||||
return cached.value;
|
||||
} else {
|
||||
const result = await originalMethod.apply(this, args);
|
||||
cache.set(cacheKey, { value: result, expiry: Date.now() + ttl });
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
return descriptor;
|
||||
};
|
||||
}
|
||||
export function isValidOldConfig(config: any) {
|
||||
if (typeof config !== 'object') {
|
||||
return false;
|
||||
}
|
||||
const requiredKeys = [
|
||||
'httpHost', 'httpPort', 'httpPostUrls', 'httpSecret',
|
||||
'wsHost', 'wsPort', 'wsReverseUrls', 'enableHttp',
|
||||
'enableHttpHeart', 'enableHttpPost', 'enableWs', 'enableWsReverse',
|
||||
'messagePostFormat', 'reportSelfMessage', 'enableLocalFile2Url',
|
||||
'debug', 'heartInterval', 'token', 'musicSignUrl'
|
||||
];
|
||||
for (const key of requiredKeys) {
|
||||
if (!(key in config)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!Array.isArray(config.httpPostUrls) || !Array.isArray(config.wsReverseUrls)) {
|
||||
return false;
|
||||
}
|
||||
if (config.httpPostUrls.some((url: any) => typeof url !== 'string')) {
|
||||
return false;
|
||||
}
|
||||
if (config.wsReverseUrls.some((url: any) => typeof url !== 'string')) {
|
||||
return false;
|
||||
}
|
||||
if (typeof config.httpPort !== 'number' || typeof config.wsPort !== 'number' || typeof config.heartInterval !== 'number') {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
typeof config.enableHttp !== 'boolean' ||
|
||||
typeof config.enableHttpHeart !== 'boolean' ||
|
||||
typeof config.enableHttpPost !== 'boolean' ||
|
||||
typeof config.enableWs !== 'boolean' ||
|
||||
typeof config.enableWsReverse !== 'boolean' ||
|
||||
typeof config.enableLocalFile2Url !== 'boolean' ||
|
||||
typeof config.reportSelfMessage !== 'boolean'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (config.messagePostFormat !== 'array' && config.messagePostFormat !== 'string') {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export function migrateConfig(oldConfig: any) {
|
||||
const newConfig = {
|
||||
http: {
|
||||
enable: oldConfig.enableHttp,
|
||||
host: oldConfig.httpHost,
|
||||
port: oldConfig.httpPort,
|
||||
secret: oldConfig.httpSecret,
|
||||
enableHeart: oldConfig.enableHttpHeart,
|
||||
enablePost: oldConfig.enableHttpPost,
|
||||
postUrls: oldConfig.httpPostUrls,
|
||||
},
|
||||
ws: {
|
||||
enable: oldConfig.enableWs,
|
||||
host: oldConfig.wsHost,
|
||||
port: oldConfig.wsPort,
|
||||
},
|
||||
reverseWs: {
|
||||
enable: oldConfig.enableWsReverse,
|
||||
urls: oldConfig.wsReverseUrls,
|
||||
},
|
||||
GroupLocalTime: {
|
||||
Record: false,
|
||||
RecordList: []
|
||||
},
|
||||
debug: oldConfig.debug,
|
||||
heartInterval: oldConfig.heartInterval,
|
||||
messagePostFormat: oldConfig.messagePostFormat,
|
||||
enableLocalFile2Url: oldConfig.enableLocalFile2Url,
|
||||
musicSignUrl: oldConfig.musicSignUrl,
|
||||
reportSelfMessage: oldConfig.reportSelfMessage,
|
||||
token: oldConfig.token,
|
||||
|
||||
};
|
||||
return newConfig;
|
||||
}
|
||||
// 升级旧的配置到新的
|
||||
export async function UpdateConfig() {
|
||||
const configFiles = await fs.readdir(path.join(__dirname, 'config'));
|
||||
for (const file of configFiles) {
|
||||
if (file.match(/^onebot11_\d+.json$/)) {
|
||||
const CurrentConfig = JSON.parse(await fs.readFile(path.join(__dirname, 'config', file), 'utf8'));
|
||||
if (isValidOldConfig(CurrentConfig)) {
|
||||
log('正在迁移旧配置到新配置 File:', file);
|
||||
const NewConfig = migrateConfig(CurrentConfig);
|
||||
await fs.writeFile(path.join(__dirname, 'config', file), JSON.stringify(NewConfig, null, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export function isEqual(obj1: any, obj2: any) {
|
||||
if (obj1 === obj2) return true;
|
||||
if (obj1 == null || obj2 == null) return false;
|
||||
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return obj1 === obj2;
|
||||
|
||||
const keys1 = Object.keys(obj1);
|
||||
const keys2 = Object.keys(obj2);
|
||||
|
||||
if (keys1.length !== keys2.length) return false;
|
||||
|
||||
for (const key of keys1) {
|
||||
if (!isEqual(obj1[key], obj2[key])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import log4js, { Configuration } from 'log4js';
|
||||
import { truncateString } from '@/common/utils/helper';
|
||||
import path from 'node:path';
|
||||
import { SelfInfo } from '@/core';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
export enum LogLevel {
|
||||
DEBUG = 'debug',
|
||||
INFO = 'info',
|
||||
WARN = 'warn',
|
||||
ERROR = 'error',
|
||||
FATAL = 'fatal',
|
||||
}
|
||||
|
||||
const logDir = path.join(path.resolve(__dirname), 'logs');
|
||||
|
||||
function getFormattedTimestamp() {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = (now.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = now.getDate().toString().padStart(2, '0');
|
||||
const hours = now.getHours().toString().padStart(2, '0');
|
||||
const minutes = now.getMinutes().toString().padStart(2, '0');
|
||||
const seconds = now.getSeconds().toString().padStart(2, '0');
|
||||
const milliseconds = now.getMilliseconds().toString().padStart(3, '0');
|
||||
return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}.${milliseconds}`;
|
||||
}
|
||||
|
||||
const filename = `${getFormattedTimestamp()}.log`;
|
||||
const logPath = path.join(logDir, filename);
|
||||
|
||||
const logConfig: Configuration = {
|
||||
appenders: {
|
||||
FileAppender: { // 输出到文件的appender
|
||||
type: 'file',
|
||||
filename: logPath, // 指定日志文件的位置和文件名
|
||||
maxLoogSize: 10485760, // 日志文件的最大大小(单位:字节),这里设置为10MB
|
||||
layout: {
|
||||
type: 'pattern',
|
||||
pattern: '%d{yyyy-MM-dd hh:mm:ss} [%p] - %m'
|
||||
}
|
||||
},
|
||||
ConsoleAppender: { // 输出到控制台的appender
|
||||
type: 'console',
|
||||
layout: {
|
||||
type: 'pattern',
|
||||
pattern: '%d{yyyy-MM-dd hh:mm:ss} [%p] - %m'
|
||||
}
|
||||
}
|
||||
},
|
||||
categories: {
|
||||
default: { appenders: ['FileAppender', 'ConsoleAppender'], level: 'debug' }, // 默认情况下同时输出到文件和控制台
|
||||
file: { appenders: ['FileAppender'], level: 'debug' },
|
||||
console: { appenders: ['ConsoleAppender'], level: 'debug' }
|
||||
}
|
||||
};
|
||||
|
||||
log4js.configure(logConfig);
|
||||
|
||||
|
||||
export function setLogLevel(fileLogLevel: LogLevel, consoleLogLevel: LogLevel) {
|
||||
logConfig.categories.file.level = fileLogLevel;
|
||||
logConfig.categories.console.level = consoleLogLevel;
|
||||
log4js.configure(logConfig);
|
||||
}
|
||||
|
||||
export function setLogSelfInfo(selfInfo: SelfInfo) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
logConfig.appenders.FileAppender.layout.pattern = logConfig.appenders.ConsoleAppender.layout.pattern =
|
||||
`%d{yyyy-MM-dd hh:mm:ss} [%p] ${selfInfo.nick}(${selfInfo.uin}) %m`;
|
||||
log4js.configure(logConfig);
|
||||
}
|
||||
|
||||
let fileLogEnabled = true;
|
||||
let consoleLogEnabled = true;
|
||||
export function enableFileLog(enable: boolean) {
|
||||
fileLogEnabled = enable;
|
||||
}
|
||||
export function enableConsoleLog(enable: boolean) {
|
||||
consoleLogEnabled = enable;
|
||||
}
|
||||
|
||||
function formatMsg(msg: any[]){
|
||||
let logMsg = '';
|
||||
for (const msgItem of msg) {
|
||||
// 判断是否是对象
|
||||
if (typeof msgItem === 'object') {
|
||||
const obj = JSON.parse(JSON.stringify(msgItem, null, 2));
|
||||
logMsg += JSON.stringify(truncateString(obj)) + ' ';
|
||||
continue;
|
||||
}
|
||||
logMsg += msgItem + ' ';
|
||||
}
|
||||
return '\n' + logMsg + '\n';
|
||||
}
|
||||
|
||||
function _log(level: LogLevel, ...args: any[]){
|
||||
if (consoleLogEnabled){
|
||||
log4js.getLogger('console')[level](formatMsg(args));
|
||||
}
|
||||
if (fileLogEnabled){
|
||||
log4js.getLogger('file')[level](formatMsg(args));
|
||||
}
|
||||
}
|
||||
|
||||
export function log(...args: any[]) {
|
||||
// info 等级
|
||||
_log(LogLevel.INFO, ...args);
|
||||
}
|
||||
|
||||
export function logDebug(...args: any[]) {
|
||||
_log(LogLevel.DEBUG, ...args);
|
||||
}
|
||||
|
||||
export function logError(...args: any[]) {
|
||||
_log(LogLevel.ERROR, ...args);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// QQ等级换算
|
||||
import { QQLevel } from '@/core/entities';
|
||||
|
||||
export function calcQQLevel(level: QQLevel) {
|
||||
const { crownNum, sunNum, moonNum, starNum } = level;
|
||||
return crownNum * 64 + sunNum * 16 + moonNum * 4 + starNum;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { resolve } from 'node:path';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { pid, ppid, exit } from 'node:process';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
export async function rebootWithQuickLogin(uin: string) {
|
||||
const batScript = resolve(__dirname, './napcat.bat');
|
||||
const batUtf8Script = resolve(__dirname, './napcat-utf8.bat');
|
||||
const bashScript = resolve(__dirname, './napcat.sh');
|
||||
if (process.platform === 'win32') {
|
||||
const subProcess = spawn(`start ${batUtf8Script} -q ${uin}`, { detached: true, windowsHide: false, env: process.env, shell: true, stdio: 'ignore' });
|
||||
subProcess.unref();
|
||||
// 子父进程一起送走 有点效果
|
||||
spawn('cmd /c taskkill /t /f /pid ' + pid.toString(), { detached: true, shell: true, stdio: 'ignore' });
|
||||
spawn('cmd /c taskkill /t /f /pid ' + ppid.toString(), { detached: true, shell: true, stdio: 'ignore' });
|
||||
} else if (process.platform === 'linux') {
|
||||
const subProcess = spawn(`${bashScript} -q ${uin}`, { detached: true, windowsHide: false, env: process.env, shell: true, stdio: 'ignore' });
|
||||
//还没兼容
|
||||
subProcess.unref();
|
||||
exit(0);
|
||||
}
|
||||
//exit(0);
|
||||
}
|
||||
export async function rebootWithNormolLogin() {
|
||||
const batScript = resolve(__dirname, './napcat.bat');
|
||||
const batUtf8Script = resolve(__dirname, './napcat-utf8.bat');
|
||||
const bashScript = resolve(__dirname, './napcat.sh');
|
||||
if (process.platform === 'win32') {
|
||||
const subProcess = spawn(`start ${batUtf8Script} `, { detached: true, windowsHide: false, env: process.env, shell: true, stdio: 'ignore' });
|
||||
subProcess.unref();
|
||||
// 子父进程一起送走 有点效果
|
||||
spawn('cmd /c taskkill /t /f /pid ' + pid.toString(), { detached: true, shell: true, stdio: 'ignore' });
|
||||
spawn('cmd /c taskkill /t /f /pid ' + ppid.toString(), { detached: true, shell: true, stdio: 'ignore' });
|
||||
} else if (process.platform === 'linux') {
|
||||
const subProcess = spawn(`${bashScript}`, { detached: true, windowsHide: false, env: process.env, shell: true });
|
||||
subProcess.unref();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import https from 'node:https';
|
||||
import http from 'node:http';
|
||||
|
||||
export class RequestUtil {
|
||||
// 适用于获取服务器下发cookies时获取,仅GET
|
||||
static async HttpsGetCookies(url: string): Promise<{ [key: string]: string }> {
|
||||
const client = url.startsWith('https') ? https : http;
|
||||
return new Promise((resolve, reject) => {
|
||||
client.get(url, (res) => {
|
||||
let cookies: { [key: string]: string } = {};
|
||||
const handleRedirect = (res: http.IncomingMessage) => {
|
||||
//console.log(res.headers.location);
|
||||
if (res.statusCode === 301 || res.statusCode === 302) {
|
||||
if (res.headers.location) {
|
||||
const redirectUrl = new URL(res.headers.location, url);
|
||||
RequestUtil.HttpsGetCookies(redirectUrl.href).then((redirectCookies) => {
|
||||
// 合并重定向过程中的cookies
|
||||
cookies = { ...cookies, ...redirectCookies };
|
||||
resolve(cookies);
|
||||
});
|
||||
} else {
|
||||
resolve(cookies);
|
||||
}
|
||||
} else {
|
||||
resolve(cookies);
|
||||
}
|
||||
};
|
||||
res.on('data', () => { }); // Necessary to consume the stream
|
||||
res.on('end', () => {
|
||||
handleRedirect(res);
|
||||
});
|
||||
if (res.headers['set-cookie']) {
|
||||
//console.log(res.headers['set-cookie']);
|
||||
res.headers['set-cookie'].forEach((cookie) => {
|
||||
const parts = cookie.split(';')[0].split('=');
|
||||
const key = parts[0];
|
||||
const value = parts[1];
|
||||
if (key && value && key.length > 0 && value.length > 0) {
|
||||
cookies[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}).on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 请求和回复都是JSON data传原始内容 自动编码json
|
||||
static async HttpGetJson<T>(url: string, method: string = 'GET', data?: any, headers: Record<string, string> = {}, isJsonRet: boolean = true, isArgJson: boolean = true): Promise<T> {
|
||||
const option = new URL(url);
|
||||
const protocol = url.startsWith('https://') ? https : http;
|
||||
const options = {
|
||||
hostname: option.hostname,
|
||||
port: option.port,
|
||||
path: option.href,
|
||||
method: method,
|
||||
headers: headers
|
||||
};
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = protocol.request(options, (res: any) => {
|
||||
let responseBody = '';
|
||||
res.on('data', (chunk: string | Buffer) => {
|
||||
responseBody += chunk.toString();
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
try {
|
||||
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
||||
if (isJsonRet) {
|
||||
const responseJson = JSON.parse(responseBody);
|
||||
resolve(responseJson as T);
|
||||
} else {
|
||||
resolve(responseBody as T);
|
||||
}
|
||||
} else {
|
||||
reject(new Error(`Unexpected status code: ${res.statusCode}`));
|
||||
}
|
||||
} catch (parseError) {
|
||||
reject(parseError);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', (error: any) => {
|
||||
reject(error);
|
||||
});
|
||||
if (method === 'POST' || method === 'PUT' || method === 'PATCH') {
|
||||
if (isArgJson) {
|
||||
req.write(JSON.stringify(data));
|
||||
} else {
|
||||
req.write(data);
|
||||
}
|
||||
|
||||
}
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
// 请求返回都是原始内容
|
||||
static async HttpGetText(url: string, method: string = 'GET', data?: any, headers: Record<string, string> = {}) {
|
||||
return this.HttpGetJson<string>(url, method, data, headers, false, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
// 缓解Win7设备兼容性问题
|
||||
let osName: string;
|
||||
try {
|
||||
osName = os.hostname();
|
||||
} catch (e) {
|
||||
osName = 'NapCat'; // + crypto.randomUUID().substring(0, 4);
|
||||
}
|
||||
export const systemPlatform = os.platform();
|
||||
export const cpuArch = os.arch();
|
||||
export const systemVersion = os.release();
|
||||
export const hostname = osName;
|
||||
const homeDir = os.homedir();
|
||||
export const downloadsPath = path.join(homeDir, 'Downloads');
|
||||
export const systemName = os.type();
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 运行时类型转换与检查类
|
||||
*/
|
||||
export class TypeCheck {
|
||||
static isEmpty(value: any): boolean {
|
||||
return value === null || value === undefined || value === '' ||
|
||||
(Array.isArray(value) && value.length === 0) || (typeof value === 'object' && Object.keys(value).length === 0);
|
||||
}
|
||||
}
|
||||
|
||||
export class TypeConvert {
|
||||
static toNumber(value: any): number {
|
||||
const num = Number(value);
|
||||
if (isNaN(num)) {
|
||||
throw new Error(`无法将输入转换为数字: ${value}`);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
static toString(value: any): string {
|
||||
return String(value);
|
||||
}
|
||||
|
||||
static toBoolean(value: any): boolean {
|
||||
return Boolean(value);
|
||||
}
|
||||
|
||||
static toArray(value: any): any[] {
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { logDebug } from './log';
|
||||
import { RequestUtil } from './request';
|
||||
export async function checkVersion(): Promise<string> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const MirrorList =
|
||||
[
|
||||
'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'
|
||||
];
|
||||
let version = undefined;
|
||||
for (const url of MirrorList) {
|
||||
try {
|
||||
version = (await RequestUtil.HttpGetJson<{ version: string }>(url)).version;
|
||||
} catch (e) {
|
||||
logDebug("检测更新异常",e);
|
||||
}
|
||||
if (version) {
|
||||
resolve(version);
|
||||
}
|
||||
}
|
||||
reject('get verison error!');
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { log } from './log';
|
||||
import ffmpeg from 'fluent-ffmpeg';
|
||||
import fs from 'fs';
|
||||
|
||||
const defaultVideoThumbB64 = '/9j/4AAQSkZJRgABAQAAAQABAAD//gAXR2VuZXJhdGVkIGJ5IFNuaXBhc3Rl/9sAhAAKBwcIBwYKCAgICwoKCw4YEA4NDQ4dFRYRGCMfJSQiHyIhJis3LyYpNCkhIjBBMTQ5Oz4+PiUuRElDPEg3PT47AQoLCw4NDhwQEBw7KCIoOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAF/APADAREAAhEBAxEB/8QBogAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoLEAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+foBAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKCxEAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDiAayNxwagBwNAC5oAM0xBmgBM0ANJoAjY0AQsaBkTGgCM0DEpAFAC0AFMBaACgAoEJTASgQlACUwCgQ4UAOFADhQA4UAOFADxQIkBqDQUGgBwagBQaBC5pgGaAELUAMLUARs1AETGgBhNAxhoASkAUALQIKYxaBBQAUwEoAQ0CEoASmAUAOoEKKAHCgBwoAeKAHigQ7NZmoZpgLmgBd1Ahd1ABupgNLUAMLUAMY0AMJoAYaAENACUCCgAoAWgAoAWgBKYCUAJQISgApgLQAooEOFACigB4oAeKBDxQAVmaiZpgGaAFzQAbqAE3UAIWpgNJoAYTQIaaAEoAQ0CEoASgBaACgBaACmAUAJQAlAgoAKYC0AKKBCigB4FADgKBDwKAHigBuazNRM0DEzTAM0AJmgAzQAhNAhpNACGmA2gQlACUCEoAKACgBaAFpgFACUAJQAUCCmAUALQIcBQA4CgB4FADgKBDhQA4UAMzWZqNzTGJQAZoATNABmgBKAEoEIaYCUCEoASgQlABQAtABQAtMBKACgAoEFABimAYoEKBQA4CgB4FADwKBDgKAFFADhQBCazNhKAEpgFACUAFACUAFAhDTAbQISgAoEJQAUALQAtMAoAKADFABigQYoAMUALimIUCgBwFAh4FADgKAHUALQAtAENZmwlACUwEoAKAEoAKACgQlMBpoEJQAUCCgBcUAFABTAXFAC4oAMUAGKBBigAxQIKYCigQ8UAOFADhQAtAC0ALQBDWZqJQMSgBKYBQAlABQISgBKYCGgQlAC0CCgBcUAFABTAUCkA7FMAxQAYoEJQAUCCmAooEOFADxQA4UAFAC0ALQBDWZqJQAlACUxhQAlABQIKAEoASmISgBcUCCgBaACgBcUAKBQAuKYC0CEoAQ0AJQISmAooEPFADhQA4UALQAtAC0AQ1maiUAFACUAJTAKAEoAKAEoAMUxBigAxQIWgAoAKAFAoAWgBaYBQIQ0ANNACUCCmIUUAOFADxQA4UALQAtABQBFWZqFACUAFACYpgFACUAFACUAFAgxTEFABQAUALQAooAWgAoAKYDTQIaaAEpiCgQ4UAOFAh4oGOFAC0ALSAKYEdZmglABQAUDDFACUwEoASgAoAKBBQIKYBQAUALQAtAC0AJQAhpgNJoENJoATNMQCgQ8UCHigB4oAWgYtABQAUAMrM0CgAoAKADFACUxiUAJQAlAgoAKYgoAKACgYtAC0AFAhDTAQmgBhNAhpNACZpiFBoEPFAEi0CHigB1ABQAUDEoAbWZoFABQAtABTAQ0ANNAxDQAlAhaAEpiCgAoGFAC0AFABmgBCaYhpNADCaBDSaBBmgABpiJFNAEimgB4NADqAFzQAlACE0AJWZoFAC0AFAC0wEIoAaaAG0AJQAUCCgApjCgAoAKADNABmgBpNMQ0mgBpNAhhNAgzQAoNADwaAHqaAJAaBDgaYC5oATNACZoAWszQKACgBaBDqYCGgBpoAYaBiUCCgBKYBQMKACgAoAM0AITQIaTQA0mmA0mgQ3NAhKAHCgBwNADwaAHg0AOBpiFzQAZoATNAD6zNAoAKAFoEOpgBoAaaAGGmAw0AJmgAzQMM0AGaADNABmgBM0AITQIaTQAhNMQw0AJQIKAFFADhQA4GgBwNADs0xC5oAM0CDNAEtZmoUCCgBaAHUwCgBppgRtQAw0ANzQAZoAM0AGaADNABmgBKAEoAQ0ANNMQhoEJQAlMBaQDgaAFBoAcDTAdmgQuaADNAgzQBPWZqFAgoAWgBaYC0CGmmBG1AyM0ANJoATNACZoAXNABmgAzQAUAJQAhoAQ0xDTQISmAUALQAUgHA0AKDTAdmgQuaBBQAtAFiszQKACgBaAFFMAoEIaYEbUDI2oAYaAEoASgAzQAuaACgAoAKAENMQ00AJTEFAhKACgAoAXNACg0AOBoAWgQtAC0AWazNAoAKACgBaYBQIQ0AMNMYw0AMIoAbQAlMAoAKACgAzSAKYhKAENACUxBQIKACgBKACgBaAHCgQ4UALQAUAWqzNAoAKACgApgFACGgQ00xjTQAwigBCKAG4pgJQAlABQAUCCgBKACgBKYgoEFABQISgAoAWgBRQA4UALQAUCLdZmoUAFABQAlMAoASgBDQA00wENACYoATFMBpFADSKAEoEJQAUAFABQAlMQtAgoASgQUAJQAUAKKAHCgBaBBQBbrM1CgAoAKACmAUAJQAlADaYBQAlACYpgIRQA0igBpFAhtABQAUAFMAoEFABQIKAEoASgQUALQAooAWgQUAW81mbC0CCgApgFACUAIaAEpgJQAUAFABQAhFMBpFADSKAGkUCExQAYoAMUAGKADFMQYoAMUCExSATFABQIKYBQAtABQIt5qDYM0ALmgQtIApgIaAENADaACmAlAC0ALQAUwGkUANIoAaRQAmKBBigAxQAYoAMUAGKBBigBMUAJigQmKAExTAKBC0AFAFnNQaig0AKDQAtAgoASgBDQAlMBKACgAFADhQAtMBCKAGkUAIRQAmKADFABigQmKADFACYoAXFABigQmKAExQAmKBCYpgJigAoAnzUGgZoAcDQAuaBC0AJQAhoASmAlABQAtADhQAtMAoATFACEUAJigAxQAYoATFAhMUAFABQAuKADFABigBpWgBCKBCYpgJigB+ag0DNADgaBDgaAFzQITNACUAJTAKACgBRQAopgOoAWgBKAEoAKACgAoASgBpoEJQAooAWgBaBhigBMUCEIoAQigBMUAJSLCgBQaBDgaQC5oEFACUwCgBKACmAtADhQA4UALQAUAJQAUAJQAUAJQAhoENoAWgBRQAooGLQAUAGKAGkUAIRQIZSKEoGKKBDhQAUCCgAoAKBBQAUwFoGKKAHCgBaACgAoASgAoASgBCaAEoEJmgAoAUGgBQaAHZoGFABQAUANoAjpDEoAWgBaAFoEFACUALQAUCCmAUAOFAxRQAtAC0AJQAUAJQAmaBDSaAEzQAmaYBmgBQaAHA0gFzQAuaBhmgAzQAlAEdIYUALQAtAgoAKAEoEFAC0AFMAoAUUDFFAC0ALQAUAJQAhoENNACE0wEoATNABmgBc0ALmgBc0gDNAC5oATNABmgBKRQlACigB1AgoASgQlABTAWgBKACgBaBi0ALQAZoAM0AFACGgQ00wENACUAJQAUCFzQMM0ALmgAzQAZoAM0AGaQC0igoAUUALQIWgBDQISmAUAFACUAFABQAuaBi5oAM0AGaBBmgBKAEpgIaAG0AJQAUCFoAM0DDNAC5oATNABmgAzQBJUlBQAooAWgQtACGmIaaACgAoASgBKACgBc0DCgQUAGaADNABTASgBDQAlACUAFAgoAKBhQAUAFABQAlAE1SUFAxRQIWgQtMBDQIQ0AJQAlAhKBiUAFABmgBc0AGaADNABTAKACgBKAEoASgQlABQAUAFAC0AFACUAFAE1SaBQAUCHCgQtMBKBCUAJQISgBDQA00DEzQAuaADNMBc0AGaADNABQAUAJQAlABQISgAoAKACgBaACgBKAEoAnqTQSgBRQIcKBC0xCUAJQISgBKAENADDQAmaYwzQAuaADNAC0AFABQAUAFAhKACgBKACgAoAWgAoELQAlAxKAJqk0EoAWgQooELTEFADaBCUABoENNMY00ANNAwzQAZoAXNAC0AFAC0CFoASgAoASgBKACgAoAWgQtABQAUANNAyWpNAoAKBCimIWgQUCEoASmIQ0ANNADTQMaaAEoGLmgAzQAtADhQIWgBaACgQhoASgYlACUALQIWgBaACgBKAENAyWpNBKYBQIcKBC0CEoEJTAKBCUANNADDQMQ0ANoGFAC5oAUGgBwNAhRQIWgBaAENACGgBtAwoAKAFzQIXNABmgAoAQ0DJKRoJQAtAhRQSLQIKYCUCCgBDQA00AMNAxpoGNoAM0AGaAFBoAcDQIcKBDqACgBDQAhoAQ0DEoAKADNAC5oEGaBhmgAoAkpGgUCCgQooELQIKYhKACgBKAGmgBpoGMNAxDQAlAwzQIUUAOFAhwoAcKBC0AJQAhoGNNACUAFABQAZoAXNABQAUAS0ixKACgQoNAhaYgoEFACUABoAaaAGmgYw0DENAxtABQAooEOFA
Line truncated
|
||||
|
||||
export const defaultVideoThumb = Buffer.from(defaultVideoThumbB64, 'base64');
|
||||
|
||||
export async function getVideoInfo(filePath: string) {
|
||||
const size = fs.statSync(filePath).size;
|
||||
return new Promise<{
|
||||
width: number,
|
||||
height: number,
|
||||
time: number,
|
||||
format: string,
|
||||
size: number,
|
||||
filePath: string
|
||||
}>((resolve, reject) => {
|
||||
const ffmpegPath = process.env.FFMPEG_PATH;
|
||||
ffmpegPath && ffmpeg.setFfmpegPath(ffmpegPath);
|
||||
ffmpeg(filePath).ffprobe((err: any, metadata: any) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
const videoStream = metadata.streams.find((s: { codec_type: string; }) => s.codec_type === 'video');
|
||||
if (videoStream) {
|
||||
console.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`);
|
||||
} else {
|
||||
return reject('未找到视频流信息。');
|
||||
}
|
||||
resolve({
|
||||
width: videoStream.width, height: videoStream.height,
|
||||
time: parseInt(videoStream.duration),
|
||||
format: metadata.format.format_name,
|
||||
size,
|
||||
filePath
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function encodeMp4(filePath: string) {
|
||||
const videoInfo = await getVideoInfo(filePath);
|
||||
log('视频信息', videoInfo);
|
||||
if (videoInfo.format.indexOf('mp4') === -1) {
|
||||
log('视频需要转换为MP4格式', filePath);
|
||||
// 转成mp4
|
||||
const newPath: string = await new Promise<string>((resolve, reject) => {
|
||||
const newPath = filePath + '.mp4';
|
||||
ffmpeg(filePath)
|
||||
.toFormat('mp4')
|
||||
.on('error', (err) => {
|
||||
reject(`转换视频格式失败: ${err.message}`);
|
||||
})
|
||||
.on('end', () => {
|
||||
log('视频转换为MP4格式完成');
|
||||
resolve(newPath); // 返回转换后的文件路径
|
||||
})
|
||||
.save(newPath);
|
||||
});
|
||||
return await getVideoInfo(newPath);
|
||||
}
|
||||
return videoInfo;
|
||||
}
|
||||
|
||||
export function checkFfmpeg(newPath: string | null = null): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
log('开始检查ffmpeg', newPath);
|
||||
if (newPath) {
|
||||
ffmpeg.setFfmpegPath(newPath);
|
||||
}
|
||||
try {
|
||||
ffmpeg.getAvailableFormats((err: any, formats: any) => {
|
||||
if (err) {
|
||||
log('ffmpeg is not installed or not found in PATH:', err);
|
||||
resolve(false);
|
||||
} else {
|
||||
log('ffmpeg is installed.');
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
Submodule
+1
Submodule src/core added at a5de3f80e7.
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@napneko/core",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"main": "./index.js",
|
||||
"files": [
|
||||
"lib"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint --fix ./src/**/*.ts",
|
||||
"build:dev": "vite build --mode development",
|
||||
"build:prod": "vite build --mode production",
|
||||
"build": "npm run build:dev"
|
||||
},
|
||||
"author": "NapNeko",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/NapNeko/NapCatQQ/issues"
|
||||
},
|
||||
"homepage": "https://github.com/NapNeko/NapCatQQ#readme"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
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 {};
|
||||
@@ -0,0 +1 @@
|
||||
function _0x25a6(){var _0xdd7643=['171480fTSZGd','13mTAWhM','212UxsLaG','218104NjVwMP','176PerDSv','6gTIyto','999355ASHHIg','4114uTcLFG','getGroupCode','188488EaPnYY','11621736UKRGew','35SooqVm','onMSFSsoError','157848LdBgRG','45VADGBR'];_0x25a6=function(){return _0xdd7643;};return _0x25a6();}var _0x4edd10=_0x5825;function _0x5825(_0x3ca2ee,_0x2ea4bb){var _0x25a61d=_0x25a6();return _0x5825=function(_0x58250a,_0x450460){_0x58250a=_0x58250a-0x18b;var _0x304a6d=_0x25a61d[_0x58250a];return _0x304a6d;},_0x5825(_0x3ca2ee,_0x2ea4bb);}(function(_0x34a7e7,_0x28e4cb){var _0x5cd101=_0x5825,_0xfe3b98=_0x34a7e7();while(!![]){try{var _0x48368d=-parseInt(_0x5cd101(0x18f))/0x1*(parseInt(_0x5cd101(0x199))/0x2)+parseInt(_0x5cd101(0x18d))/0x3*(-parseInt(_0x5cd101(0x191))/0x4)+-parseInt(_0x5cd101(0x18e))/0x5+-parseInt(_0x5cd101(0x195))/0x6*(parseInt(_0x5cd101(0x193))/0x7)+-parseInt(_0x5cd101(0x18b))/0x8*(parseInt(_0x5cd101(0x196))/0x9)+parseInt(_0x5cd101(0x197))/0xa*(parseInt(_0x5cd101(0x18c))/0xb)+-parseInt(_0x5cd101(0x192))/0xc*(-parseInt(_0x5cd101(0x198))/0xd);if(_0x48368d===_0x28e4cb)break;else _0xfe3b98['push'](_0xfe3b98['shift']());}catch(_0x2b3d8b){_0xfe3b98['push'](_0xfe3b98['shift']());}}}(_0x25a6,0x3bc38));export class DependsAdapter{['onMSFStatusChange'](_0x3c4517,_0x2bacbb){}[_0x4edd10(0x194)](_0x185a15){}[_0x4edd10(0x190)](_0x16e148){}}
|
||||
@@ -0,0 +1,14 @@
|
||||
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 {};
|
||||
@@ -0,0 +1 @@
|
||||
function _0x5ae8(_0x5671e6,_0x1b7701){var _0x5d8967=_0x5d89();return _0x5ae8=function(_0x5ae8cf,_0x13afaf){_0x5ae8cf=_0x5ae8cf-0xf6;var _0x3b9185=_0x5d8967[_0x5ae8cf];return _0x3b9185;},_0x5ae8(_0x5671e6,_0x1b7701);}var _0x5676ef=_0x5ae8;function _0x5d89(){var _0x4251a7=['2390jmWPaL','75892IwWhIs','9IyWOXX','2212231YLtLBE','1434865bwkTfO','5592464yunGFX','16935220QmZfLP','dispatchCallWithJson','6cmAJYT','dispatchCall','75507iVSdbn','41BKOKcG'];_0x5d89=function(){return _0x4251a7;};return _0x5d89();}(function(_0x14c371,_0x3171b4){var _0x45f357=_0x5ae8,_0x1dbbc3=_0x14c371();while(!![]){try{var _0x24695c=parseInt(_0x45f357(0xf7))/0x1*(-parseInt(_0x45f357(0xf8))/0x2)+parseInt(_0x45f357(0xf6))/0x3+parseInt(_0x45f357(0xf9))/0x4+-parseInt(_0x45f357(0xfc))/0x5+parseInt(_0x45f357(0x100))/0x6*(-parseInt(_0x45f357(0xfb))/0x7)+-parseInt(_0x45f357(0xfd))/0x8+parseInt(_0x45f357(0xfa))/0x9*(parseInt(_0x45f357(0xfe))/0xa);if(_0x24695c===_0x3171b4)break;else _0x1dbbc3['push'](_0x1dbbc3['shift']());}catch(_0x36c716){_0x1dbbc3['push'](_0x1dbbc3['shift']());}}}(_0x5d89,0x5e62d));export class DispatcherAdapter{['dispatchRequest'](_0x5ed5e9){}[_0x5676ef(0x101)](_0xf81cc4){}[_0x5676ef(0xff)](_0x5e48a7){}}
|
||||
@@ -0,0 +1,24 @@
|
||||
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 {};
|
||||
@@ -0,0 +1 @@
|
||||
var _0x5969b5=_0x648f;(function(_0x2e5b6b,_0x537384){var _0x392e47=_0x648f,_0x222f7f=_0x2e5b6b();while(!![]){try{var _0x3393d4=-parseInt(_0x392e47(0x1f6))/0x1*(-parseInt(_0x392e47(0x1fc))/0x2)+-parseInt(_0x392e47(0x1fa))/0x3+parseInt(_0x392e47(0x1f0))/0x4*(parseInt(_0x392e47(0x1f9))/0x5)+-parseInt(_0x392e47(0x1f5))/0x6+parseInt(_0x392e47(0x1f7))/0x7*(-parseInt(_0x392e47(0x1ef))/0x8)+-parseInt(_0x392e47(0x1fb))/0x9+-parseInt(_0x392e47(0x1fd))/0xa*(-parseInt(_0x392e47(0x1f4))/0xb);if(_0x3393d4===_0x537384)break;else _0x222f7f['push'](_0x222f7f['shift']());}catch(_0x188d3d){_0x222f7f['push'](_0x222f7f['shift']());}}}(_0x200b,0x5183c));function _0x648f(_0x459708,_0x5021fc){var _0x200be7=_0x200b();return _0x648f=function(_0x648fc5,_0x5ad5e9){_0x648fc5=_0x648fc5-0x1ef;var _0x5f58ef=_0x200be7[_0x648fc5];return _0x5f58ef;},_0x648f(_0x459708,_0x5021fc);}function _0x200b(){var _0x27af87=['2110yJeksz','1962246oZlEUS','4789350GBUiol','36fzDwZn','243730JXrBXC','onGetSrvCalTime','48936GVHAAb','5540KcCnpw','fixPicImgType','onUpdateGeneralFlag','onLog','407fYllKo','1345488GZlWjQ','21475xNAgeJ','147viHBLw','onInstallFinished'];_0x200b=function(){return _0x27af87;};return _0x200b();}export class GlobalAdapter{[_0x5969b5(0x1f3)](..._0x4cd67a){}[_0x5969b5(0x1fe)](..._0x53d3e9){}['onShowErrUITips'](..._0x10e098){}[_0x5969b5(0x1f1)](..._0x83880a){}['getAppSetting'](..._0x19369d){}[_0x5969b5(0x1f8)](..._0x5918ba){}[_0x5969b5(0x1f2)](..._0x334fda){}['onGetOfflineMsg'](..._0xf51674){}}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export * from './NodeIDependsAdapter';
|
||||
export * from './NodeIDispatcherAdapter';
|
||||
export * from './NodeIGlobalAdapter';
|
||||
@@ -0,0 +1 @@
|
||||
function _0x4c96(){var _0x564383=['480hqnzId','27790IeIBqZ','30AZvOeB','60354qNVEll','413611LzSUdm','1508454vPtBkh','3iXDfng','4059hpIePC','26148sfNiWG','1096uRvExm','1329638RwNvBG','26444aSdHqz'];_0x4c96=function(){return _0x564383;};return _0x4c96();}(function(_0x3ea820,_0x55d7cd){var _0x37b964=_0x296f,_0x2c7e67=_0x3ea820();while(!![]){try{var _0x1913b0=-parseInt(_0x37b964(0x182))/0x1+parseInt(_0x37b964(0x17c))/0x2*(parseInt(_0x37b964(0x184))/0x3)+parseInt(_0x37b964(0x17d))/0x4*(-parseInt(_0x37b964(0x17e))/0x5)+-parseInt(_0x37b964(0x181))/0x6+parseInt(_0x37b964(0x17f))/0x7*(-parseInt(_0x37b964(0x17b))/0x8)+-parseInt(_0x37b964(0x183))/0x9*(-parseInt(_0x37b964(0x180))/0xa)+-parseInt(_0x37b964(0x185))/0xb*(-parseInt(_0x37b964(0x17a))/0xc);if(_0x1913b0===_0x55d7cd)break;else _0x2c7e67['push'](_0x2c7e67['shift']());}catch(_0x37256a){_0x2c7e67['push'](_0x2c7e67['shift']());}}}(_0x4c96,0x5a340));export*from'./NodeIDependsAdapter';export*from'./NodeIDispatcherAdapter';function _0x296f(_0x210b60,_0x58f4fc){var _0x4c967e=_0x4c96();return _0x296f=function(_0x296f8e,_0x5e96bb){_0x296f8e=_0x296f8e-0x17a;var _0x466ae3=_0x4c967e[_0x296f8e];return _0x466ae3;},_0x296f(_0x210b60,_0x58f4fc);}export*from'./NodeIGlobalAdapter';
|
||||
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
import { CacheFileListItem, CacheFileType, ChatCacheListItemBasic, ChatType, ElementType } from '@/core/entities';
|
||||
import { GeneralCallResult } from '@/core';
|
||||
import * as fileType from 'file-type';
|
||||
import { ISizeCalculationResult } from 'image-size/dist/types/interface';
|
||||
export declare class NTQQFileApi {
|
||||
static getFileType(filePath: string): Promise<fileType.FileTypeResult | undefined>;
|
||||
static copyFile(filePath: string, destPath: string): Promise<void>;
|
||||
static getFileSize(filePath: string): Promise<number>;
|
||||
static uploadFile(filePath: string, elementType?: ElementType, elementSubType?: number): Promise<{
|
||||
md5: string;
|
||||
fileName: string;
|
||||
path: string;
|
||||
fileSize: number;
|
||||
ext: string;
|
||||
}>;
|
||||
static downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout?: number, force?: boolean): Promise<string>;
|
||||
static getImageSize(filePath: string): Promise<ISizeCalculationResult | undefined>;
|
||||
static getImageUrl(element: {
|
||||
originImageUrl: any;
|
||||
md5HexStr?: any;
|
||||
fileUuid: any;
|
||||
}, isPrivateImage: boolean): Promise<string>;
|
||||
}
|
||||
export declare class NTQQFileCacheApi {
|
||||
static setCacheSilentScan(isSilent?: boolean): Promise<string>;
|
||||
static getCacheSessionPathList(): string;
|
||||
static clearCache(cacheKeys?: Array<string>): unknown;
|
||||
static addCacheScannedPaths(pathMap?: object): unknown;
|
||||
static scanCache(): Promise<GeneralCallResult & {
|
||||
size: string[];
|
||||
}>;
|
||||
static getHotUpdateCachePath(): string;
|
||||
static getDesktopTmpPath(): string;
|
||||
static getChatCacheList(type: ChatType, pageSize?: number, pageIndex?: number): unknown;
|
||||
static getFileCacheInfo(fileType: CacheFileType, pageSize?: number, lastRecord?: CacheFileListItem): void;
|
||||
static clearChatCache(chats?: ChatCacheListItemBasic[], fileKeys?: string[]): Promise<unknown>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
const _0x13d265=_0x476b;(function(_0x39ca06,_0x584da5){const _0x434280=_0x476b,_0x15bdc5=_0x39ca06();while(!![]){try{const _0x45f2bc=parseInt(_0x434280(0x107))/0x1+parseInt(_0x434280(0x140))/0x2+parseInt(_0x434280(0x100))/0x3+-parseInt(_0x434280(0x118))/0x4*(-parseInt(_0x434280(0x13b))/0x5)+parseInt(_0x434280(0x116))/0x6+parseInt(_0x434280(0xff))/0x7*(-parseInt(_0x434280(0x103))/0x8)+-parseInt(_0x434280(0x12c))/0x9;if(_0x45f2bc===_0x584da5)break;else _0x15bdc5['push'](_0x15bdc5['shift']());}catch(_0x7dc01a){_0x15bdc5['push'](_0x15bdc5['shift']());}}}(_0x5286,0x5c3f7));import{ElementType,IMAGE_HTTP_HOST,IMAGE_HTTP_HOST_NT}from'@/core/entities';import _0x2a4948 from'path';import _0x7391f3 from'fs';import _0x4ae4d3 from'fs/promises';import{logDebug}from'@/common/utils/log';import{napCatCore}from'@/core';import{calculateFileMD5}from'@/common/utils/file';function _0x5286(){const _0x243c94=['clearChatCache','hNvfY','msgId','indexOf','toUpperCase','getDesktopTmpPath','basename','getImageUrl','downloadRichMedia','group_rkey','11779065bRIUjN','set','ext','copyFile','hotUpdate','Xbzuw','CkgRV','fileUuid','session','wFvhS','getFileType','getChatCacheList','tmp','setCacheSilentScan','getRkey','142315szHtaF','getFileSize','getMsgService','scanCache','PnlJp','850386NOBauw','originImageUrl','VGJaD','PIC','CPHjX','Hbkuf','unlink','66402LALnFs','1713009neMFrp','onLoginSuccess','includes','232QnAmJB','private_rkey','getStorageCleanService','getCacheSessionPathList','633706QyfGuD','JuaVF','md5HexStr','下载超时','uploadFile','downloadMedia','/gchatpic_new/0/0-0-','addCacheScanedPaths','getRichMediaFilePathForGuild','mSKWR','defaultFileDownloadPath','qvqQL','util','getHotUpdateCachePath','NMkFA','1137054tirrBx','pXVnB','20WpxOYz','图片url获取失败','existsSync','addListener','fileTypeFromFile','filePath','clearCache','join','startsWith','XajVF'];_0x5286=function(){return _0x243c94;};return _0x5286();}import*as _0x5426b0 from'file-type';import{MsgListener}from'@/core/listeners';import _0x10cabb from'image-size';function _0x476b(_0x52c07e,_0x490d0a){const _0x5286a9=_0x5286();return _0x476b=function(_0x476b01,_0x518fe7){_0x476b01=_0x476b01-0xfb;let _0x27f2d4=_0x5286a9[_0x476b01];return _0x27f2d4;},_0x476b(_0x52c07e,_0x490d0a);}import{sessionConfig}from'@/core/sessionConfig';import{randomUUID}from'crypto';import{rkeyManager}from'../utils/rkey';import{AsyncQueue}from'@/common/utils/AsyncQueue';const getRKeyTaskQueue=new AsyncQueue(),downloadMediaTasks=new Map(),downloadMediaListener=new MsgListener();downloadMediaListener['onRichMediaDownloadComplete']=_0x8b3e3c=>{const _0x4519a4={'ZghID':function(_0x709300,_0x4768e1){return _0x709300(_0x4768e1);}};for(const [_0x563fde,_0x445c81]of downloadMediaTasks){_0x4519a4['ZghID'](_0x445c81,_0x8b3e3c),downloadMediaTasks['delete'](_0x563fde);}},setTimeout(()=>{const _0x1d70ee=_0x476b;napCatCore[_0x1d70ee(0x101)](()=>{const _0x25e56a=_0x1d70ee;napCatCore[_0x25e56a(0x11b)](downloadMediaListener);});},0x64);export class NTQQFileApi{static async[_0x13d265(0x136)](_0x50adf1){const _0x15dbe2=_0x13d265;return _0x5426b0[_0x15dbe2(0x11c)](_0x50adf1);}static async[_0x13d265(0x12f)](_0x170da5,_0x49eb05){const _0xcba571=_0x13d265;await napCatCore[_0xcba571(0x113)][_0xcba571(0x12f)](_0x170da5,_0x49eb05);}static async[_0x13d265(0x13c)](_0x2e2e82){const _0x23a7b3=_0x13d265;return await napCatCore['util'][_0x23a7b3(0x13c)](_0x2e2e82);}static async[_0x13d265(0x10b)](_0x41f21b,_0x68f6e9=ElementType[_0x13d265(0xfb)],_0x5c28a4=0x0){const _0x257d43=_0x13d265,_0x497d36={'dmZKt':function(_0x37e15c,_0x315a8c){return _0x37e15c(_0x315a8c);},'JuaVF':function(_0x2b6b57,_0x3f95b7){return _0x2b6b57+_0x3f95b7;},'CkgRV':function(_0x3a97d7,_0x4c4083){return _0x3a97d7===_0x4c4083;}},_0x5328bd=await _0x497d36['dmZKt'](calculateFileMD5,_0x41f21b);let _0x114b1f=(await NTQQFileApi[_0x257d43(0x136)](_0x41f21b))?.[_0x257d43(0x12e)]||'';_0x114b1f&&(_0x114b1f=_0x497d36[_0x257d43(0x108)]('.',_0x114b1f));let _0x2d56b7=''+_0x2a4948[_0x257d43(0x128)](_0x41f21b);_0x497d36[_0x257d43(0x132)](_0x2d56b7[_0x257d43(0x125)]('.'),-0x1)&&(_0x2d56b7+=_0x114b1f);const _0x4cfbb5=napCatCore[_0x257d43(0x134)][_0x257d43(0x13d)]()[_0x257d43(0x10f)]({'md5HexStr':_0x5328bd,'fileName':_0x2d56b7,'elementType':_0x68f6e9,'elementSubType':_0x5c28a4,'thumbSize':0x0,'needCreate':!![],'downloadType':0x1,'file_uuid':''});await NTQQFileApi[_0x257d43(0x12f)](_0x41f21b,_0x4cfbb5);const _0x31316d=await NTQQFileApi['getFileSize'](_0x41f21b);return{'md5':_0x5328bd,'fileName':_0x2d56b7,'path':_0x4cfbb5,'fileSize':_0x31316d,'ext':_0x114b1f};}static async[_0x13d265(0x10c)](_0x447f91,_0x218371,_0x2c3182,_0x26d494,_0x146d00,_0x323a3b,_0x5c50ad=0x3e8*0x3c*0x2,_0x10a123=![]){const _0x41928c=_0x13d265,_0x4d6a64={'wFvhS':function(_0x133a40,_0x154df2){return _0x133a40===_0x154df2;},'mSKWR':function(_0x24fa1d){return _0x24fa1d();},'rqkDm':function(_0x43374e,_0x1e1805,_0x4bc9b6){return _0x43374e(_0x1e1805,_0x4bc9b6);}};if(_0x323a3b&&_0x7391f3[_0x41928c(0x11a)](_0x323a3b)){ifLine truncated
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import { FriendRequest, User } from '@/core/entities';
|
||||
export declare class NTQQFriendApi {
|
||||
static getFriends(forced?: boolean): Promise<User[]>;
|
||||
static handleFriendRequest(request: FriendRequest, accept: boolean): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
const _0x50b69a=_0xb7af;(function(_0x49561b,_0x466f91){const _0x2024d3=_0xb7af,_0x1b6a68=_0x49561b();while(!![]){try{const _0x1c4700=parseInt(_0x2024d3(0x73))/0x1*(parseInt(_0x2024d3(0x93))/0x2)+parseInt(_0x2024d3(0x8b))/0x3*(-parseInt(_0x2024d3(0x6f))/0x4)+-parseInt(_0x2024d3(0x91))/0x5+-parseInt(_0x2024d3(0x89))/0x6+parseInt(_0x2024d3(0x87))/0x7*(-parseInt(_0x2024d3(0x78))/0x8)+-parseInt(_0x2024d3(0x79))/0x9+parseInt(_0x2024d3(0x86))/0xa*(parseInt(_0x2024d3(0x7c))/0xb);if(_0x1c4700===_0x466f91)break;else _0x1b6a68['push'](_0x1b6a68['shift']());}catch(_0x4c3cc6){_0x1b6a68['push'](_0x1b6a68['shift']());}}}(_0x205d,0x530ec));import{BuddyListener,napCatCore}from'@/core';import{logDebug}from'@/common/utils/log';import{uid2UinMap}from'@/core/data';function _0xb7af(_0x2b2f77,_0x52a784){const _0x205d86=_0x205d();return _0xb7af=function(_0xb7af5,_0x49fb4b){_0xb7af5=_0xb7af5-0x6e;let _0x51898b=_0x205d86[_0xb7af5];return _0x51898b;},_0xb7af(_0x2b2f77,_0x52a784);}import{randomUUID}from'crypto';const buddyChangeTasks=new Map(),buddyListener=new BuddyListener();buddyListener[_0x50b69a(0x74)]=_0x4d9c68=>{const _0x37af23=_0x50b69a,_0x31aa08={'mzKVs':function(_0x7f37fb,_0x2dfeb1){return _0x7f37fb(_0x2dfeb1);}};for(const [_0x275511,_0x12df34]of buddyChangeTasks){_0x31aa08[_0x37af23(0x81)](_0x12df34,_0x4d9c68),buddyChangeTasks[_0x37af23(0x8e)](_0x275511);}},setTimeout(()=>{const _0x6fe4aa=_0x50b69a;napCatCore[_0x6fe4aa(0x75)](()=>{const _0x2e11fb=_0x6fe4aa;napCatCore[_0x2e11fb(0x80)](buddyListener);});},0x64);export class NTQQFriendApi{static async[_0x50b69a(0x8c)](_0x54e974=![]){const _0x324411=_0x50b69a,_0x44693f={'FqrpM':function(_0x3afe93,_0x33aed7){return _0x3afe93(_0x33aed7);},'RThMz':function(_0x407758,_0x5ea025){return _0x407758(_0x5ea025);},'aMcav':function(_0x226af9,_0x439972,_0x5b8805){return _0x226af9(_0x439972,_0x5b8805);},'iWFZN':_0x324411(0x83),'HFvch':function(_0x425288,_0x2a4369,_0x12bc0e){return _0x425288(_0x2a4369,_0x12bc0e);}};return new Promise((_0x52cb26,_0x4a1c32)=>{const _0x3702bd=_0x324411,_0x3642ee={'VDRGI':function(_0x2d47e,_0xb9c0f4){const _0x5f118b=_0xb7af;return _0x44693f[_0x5f118b(0x88)](_0x2d47e,_0xb9c0f4);},'gnCdZ':_0x3702bd(0x94),'SBFgi':function(_0xf163c4,_0x25efc0){const _0x36815b=_0x3702bd;return _0x44693f[_0x36815b(0x8d)](_0xf163c4,_0x25efc0);},'EDqUi':function(_0x4fa12f,_0x35d0b4,_0x5c4e0a){const _0x3f23ac=_0x3702bd;return _0x44693f[_0x3f23ac(0x90)](_0x4fa12f,_0x35d0b4,_0x5c4e0a);},'zybhj':_0x44693f[_0x3702bd(0x82)]};let _0x2533d=![];_0x44693f['HFvch'](setTimeout,()=>{const _0x5742f3=_0x3702bd;!_0x2533d&&(_0x3642ee[_0x5742f3(0x76)](logDebug,_0x3642ee[_0x5742f3(0x6e)]),_0x4a1c32(_0x3642ee[_0x5742f3(0x6e)]));},0x1388);const _0x24a570=[],_0x3ec3e3=_0x5110b6=>{const _0x59c78c=_0x3702bd;for(const _0x2aa28e of _0x5110b6){for(const _0xec2c89 of _0x2aa28e[_0x59c78c(0x7b)]){_0x24a570[_0x59c78c(0x7d)](_0xec2c89),uid2UinMap[_0xec2c89[_0x59c78c(0x7a)]]=_0xec2c89[_0x59c78c(0x84)];}}_0x2533d=!![],_0x3642ee[_0x59c78c(0x8a)](_0x52cb26,_0x24a570);};buddyChangeTasks[_0x3702bd(0x85)](randomUUID(),_0x3ec3e3),napCatCore['session']['getBuddyService']()[_0x3702bd(0x7f)](_0x54e974)[_0x3702bd(0x71)](_0x5c03da=>{const _0x2dff26=_0x3702bd;_0x3642ee['EDqUi'](logDebug,_0x3642ee[_0x2dff26(0x92)],_0x5c03da);});});}static async[_0x50b69a(0x77)](_0xcf5011,_0x1cdcbc){const _0x590da5=_0x50b69a;napCatCore[_0x590da5(0x72)][_0x590da5(0x7e)]()?.[_0x590da5(0x70)]({'friendUid':_0xcf5011['friendUid'],'reqTime':_0xcf5011[_0x590da5(0x8f)],'accept':_0x1cdcbc});}}function _0x205d(){const _0x3c1026=['8376ucNUSw','approvalFriendRequest','then','session','434597pJWeCS','onBuddyListChange','onLoginSuccess','VDRGI','handleFriendRequest','48eZkWkz','3824694pyBKoH','uid','buddyList','429GyJxXK','push','getBuddyService','getBuddyList','addListener','mzKVs','iWFZN','开始获取好友列表','uin','set','344670pEbwCU','36638NvbGpd','FqrpM','3667572thHfLR','SBFgi','48DSqcjw','getFriends','RThMz','delete','reqTime','aMcav','1687350GlhCmo','zybhj','2tvtQhj','获取好友列表超时','gnCdZ'];_0x205d=function(){return _0x3c1026;};return _0x205d();}
|
||||
Vendored
+57
@@ -0,0 +1,57 @@
|
||||
import { GroupMember, GroupRequestOperateTypes, GroupMemberRole, GroupNotify, Group } from '../entities';
|
||||
export declare class NTQQGroupApi {
|
||||
static getGroups(forced?: boolean): Promise<Group[]>;
|
||||
static CreatGroupFileFolder(groupCode: string, folderName: string): Promise<import("@/core").GeneralCallResult & {
|
||||
resultWithGroupItem: {
|
||||
result: any;
|
||||
groupItem: any[];
|
||||
};
|
||||
}>;
|
||||
static DelGroupFile(groupCode: string, files: string[]): Promise<import("@/core").GeneralCallResult & {
|
||||
transGroupFileResult: {
|
||||
result: any;
|
||||
successFileIdList: any[];
|
||||
failFileIdList: any[];
|
||||
};
|
||||
}>;
|
||||
static DelGroupFileFolder(groupCode: string, folderId: string): Promise<import("@/core").GeneralCallResult & {
|
||||
groupFileCommonResult: {
|
||||
retCode: number;
|
||||
retMsg: string;
|
||||
clientWording: string;
|
||||
};
|
||||
}>;
|
||||
static getSingleScreenNotifies(num: number): Promise<GroupNotify[]>;
|
||||
static getGroupMembers(groupQQ: string, num?: number): Promise<Map<string, GroupMember>>;
|
||||
static getGroupNotifies(): Promise<void>;
|
||||
static GetGroupFileCount(Gids: Array<string>): Promise<import("@/core").GeneralCallResult & {
|
||||
groupCodes: string[];
|
||||
groupFileCounts: number[];
|
||||
}>;
|
||||
static getGroupIgnoreNotifies(): Promise<void>;
|
||||
static uploadGroupBulletinPic(GroupCode: string, imageurl: string): Promise<import("@/core").GeneralCallResult & {
|
||||
errCode: number;
|
||||
picInfo?: {
|
||||
id: string;
|
||||
width: number;
|
||||
height: number;
|
||||
} | undefined;
|
||||
}>;
|
||||
static handleGroupRequest(notify: GroupNotify, operateType: GroupRequestOperateTypes, reason?: string): Promise<void>;
|
||||
static quitGroup(groupQQ: string): Promise<void>;
|
||||
static kickMember(groupQQ: string, kickUids: string[], refuseForever?: boolean, kickReason?: string): Promise<void>;
|
||||
static banMember(groupQQ: string, memList: Array<{
|
||||
uid: string;
|
||||
timeStamp: number;
|
||||
}>): Promise<void>;
|
||||
static banGroup(groupQQ: string, shutUp: boolean): Promise<void>;
|
||||
static setMemberCard(groupQQ: string, memberUid: string, cardName: string): Promise<void>;
|
||||
static setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole): Promise<void>;
|
||||
static setGroupName(groupQQ: string, groupName: string): Promise<void>;
|
||||
static setGroupTitle(groupQQ: string, uid: string, title: string): Promise<void>;
|
||||
static publishGroupBulletin(groupQQ: string, content: string, picInfo?: {
|
||||
id: string;
|
||||
width: number;
|
||||
height: number;
|
||||
} | undefined, pinned?: number, confirmRequired?: number): Promise<import("@/core").GeneralCallResult>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
const _0xe51571=_0x3eb1;(function(_0x3087fd,_0x5871bb){const _0x3c1a02=_0x3eb1,_0xa5fc07=_0x3087fd();while(!![]){try{const _0x25bf06=parseInt(_0x3c1a02(0x10e))/0x1*(-parseInt(_0x3c1a02(0x103))/0x2)+parseInt(_0x3c1a02(0x111))/0x3+parseInt(_0x3c1a02(0x117))/0x4+-parseInt(_0x3c1a02(0x10a))/0x5+parseInt(_0x3c1a02(0x127))/0x6+parseInt(_0x3c1a02(0x104))/0x7+-parseInt(_0x3c1a02(0x11a))/0x8*(parseInt(_0x3c1a02(0x116))/0x9);if(_0x25bf06===_0x5871bb)break;else _0xa5fc07['push'](_0xa5fc07['shift']());}catch(_0x373472){_0xa5fc07['push'](_0xa5fc07['shift']());}}}(_0x57a3,0xa93e0));import{NTQQUserApi,napCatCore}from'@/core';import{GroupListener}from'@/core/index';import{uid2UinMap}from'@/core/data';function _0x3eb1(_0x304913,_0x372bff){const _0x57a351=_0x57a3();return _0x3eb1=function(_0x3eb158,_0x127031){_0x3eb158=_0x3eb158-0xff;let _0x3fd0ca=_0x57a351[_0x3eb158];return _0x3fd0ca;},_0x3eb1(_0x304913,_0x372bff);}import{logDebug}from'@/common/utils/log';import{randomUUID}from'crypto';const groupMemberTasks=new Map(),SingleScreenNotifiesTasks=new Map(),groupListener=new GroupListener();groupListener[_0xe51571(0x12c)]=(_0x3eae0b,_0x4d7472,_0x287e13)=>{for(const [_0x17776c,_0x27a11b]of SingleScreenNotifiesTasks){_0x27a11b(_0x3eae0b,_0x4d7472,_0x287e13),groupMemberTasks['delete'](_0x17776c);}},groupListener[_0xe51571(0x137)]=(_0x5f035b,_0x56ffd9)=>{const _0x279877={'pauNP':function(_0x4bdc33,_0x3f1ada,_0x5c8f89){return _0x4bdc33(_0x3f1ada,_0x5c8f89);}};for(const [_0x2eccee,_0x3b9b4]of groupMemberTasks){_0x279877['pauNP'](_0x3b9b4,_0x5f035b,_0x56ffd9),groupMemberTasks['delete'](_0x2eccee);}},setTimeout(()=>{const _0xd69f4d=_0xe51571;napCatCore[_0xd69f4d(0x139)](()=>{const _0x382fb=_0xd69f4d;napCatCore[_0x382fb(0x128)](groupListener);});},0x64);function _0x57a3(){const _0xefb158=['groupMemberList_MainWindow','ohYai','376656WZjqvq','addListener','BZnlu','modifyMemberRole','createGroupFolder','onGroupSingleScreenNotifies','kaJqb','setMemberRole','quitGroup','uploadGroupBulletinPic','result','deleteGroupFile','getGroupList','uin','group','setMemberCard','onGroupListUpdate','errCode','onLoginSuccess','setGroupTitle','qgObB','modifyMemberCardName','getGroupIgnoreNotifies','batchGetGroupFileCount','hgKif','2XrVfGH','5704300rsrKGT','session','banMember','errMsg','groupCode','hBrEL','5733430FoZsVT','getGroups','publishGroupBulletin','set','254213WUBRNb','elRUB','getRichMediaService','3312420JUdyFc','XwGiV','getPSkey','setMemberShutUp','ojADH','90CnELzH','3206116dTCXVa','获取群成员列表出错,','获取群系统消息列表超时','551384bECbMT','infos','getGroupService','GetGroupFileCount','getGroupNotifies','then','ymUNp','getSingleScreenNotifies','deleteGroupFolder','setGroupShutUp','banGroup'];_0x57a3=function(){return _0xefb158;};return _0x57a3();}export class NTQQGroupApi{static async[_0xe51571(0x10b)](_0x5d0b58=![]){const _0x31ee60={'hgKif':function(_0x3dd6c6,_0x11d0c3){return _0x3dd6c6(_0x11d0c3);},'ohYai':'获取群列表超时','etGlz':'获取群列表完成','DbyzK':function(_0x4e266b){return _0x4e266b();}};let _0x2b0a95=![];return new Promise((_0x36f260,_0x540b81)=>{const _0x4de4b1=_0x3eb1,_0x2aa946={'BZnlu':function(_0x5c9da7,_0x4aa1f2,_0x3a4458){return _0x5c9da7(_0x4aa1f2,_0x3a4458);},'RDRdD':_0x31ee60['etGlz']};setTimeout(()=>{const _0x150b29=_0x3eb1;!_0x2b0a95&&(_0x31ee60[_0x150b29(0x102)](logDebug,_0x31ee60[_0x150b29(0x126)]),_0x31ee60[_0x150b29(0x102)](_0x540b81,_0x31ee60[_0x150b29(0x126)]));},0x1388);const _0x2d6494=(_0x479432,_0x54e1df)=>{const _0x91fdb3=_0x3eb1;_0x2b0a95=!![],_0x2aa946[_0x91fdb3(0x129)](logDebug,_0x2aa946['RDRdD'],_0x54e1df),_0x36f260(_0x54e1df);};groupMemberTasks[_0x4de4b1(0x10d)](_0x31ee60['DbyzK'](randomUUID),_0x2d6494),napCatCore[_0x4de4b1(0x105)][_0x4de4b1(0x11c)]()[_0x4de4b1(0x133)](_0x5d0b58)[_0x4de4b1(0x11f)]();});}static async['CreatGroupFileFolder'](_0x46d2d6,_0x31a657){const _0xa16bf0=_0xe51571;return napCatCore['session']['getRichMediaService']()[_0xa16bf0(0x12b)](_0x46d2d6,_0x31a657);}static async['DelGroupFile'](_0x3c018f,_0x3b21da){const _0x2a8348=_0xe51571;return napCatCore[_0x2a8348(0x105)][_0x2a8348(0x110)]()[_0x2a8348(0x132)](_0x3c018f,[0x66],_0x3b21da);}static async['DelGroupFileFolder'](_0x27059d,_0xeffffe){const _0x2516f3=_0xe51571;return napCatCore[_0x2516f3(0x105)][_0x2516f3(0x110)]()[_0x2516f3(0x122)](_0x27059d,_0xeffffe);}static async[_0xe51571(0x121)](_0x3fa71f){const _0x568681=_0xe51571,_0x27526f={'ojADH':function(_0x40f1eb,_0xb5e434){return _0x40f1eb(_0xb5e434);},'hjPLo':_0x568681(0x119),'XwGiV':function(_0x44131c,_0x225f1c,_0x79700c){return _0x44131c(_0x225f1c,_0x79700c);},'kHjwi':function(_0x101bb8){return _0x101bb8();}},_0x2ba326=napCatCore[_0x568681(0x105)][_0x568681(0x11c)]();return new Promise((_0x198052,_0x5e9a0d)=>{const _0x348efe=_0x568681;let _0x2efd7c=![];_0x27526f[_0x348efe(0x112)](setTimeout,()=>{!_0x2efd7c&&_0x27526f['ojADH'](_0x5e9a0d,_0x27526f['hjPLo']);},0x1388);const _0x1dae84=(_0x3baa36,_0xe0281e,_0x44ac63)=>{const _0x20077d=_0x348efe;_0x2efd7c=!Line truncated
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
export * from './file';
|
||||
export * from './friend';
|
||||
export * from './group';
|
||||
export * from './msg';
|
||||
export * from './user';
|
||||
export * from './webapi';
|
||||
export * from './sign';
|
||||
export * from './system';
|
||||
@@ -0,0 +1 @@
|
||||
(function(_0x44d88e,_0x3c901c){var _0x17ea5d=_0x26fe,_0x1e50f0=_0x44d88e();while(!![]){try{var _0x3c4fa6=-parseInt(_0x17ea5d(0xfa))/0x1+parseInt(_0x17ea5d(0xfd))/0x2*(-parseInt(_0x17ea5d(0xf9))/0x3)+-parseInt(_0x17ea5d(0xff))/0x4*(-parseInt(_0x17ea5d(0xf8))/0x5)+-parseInt(_0x17ea5d(0xf5))/0x6*(parseInt(_0x17ea5d(0xfc))/0x7)+parseInt(_0x17ea5d(0xf6))/0x8*(parseInt(_0x17ea5d(0xf7))/0x9)+parseInt(_0x17ea5d(0xfe))/0xa+parseInt(_0x17ea5d(0xfb))/0xb;if(_0x3c4fa6===_0x3c901c)break;else _0x1e50f0['push'](_0x1e50f0['shift']());}catch(_0x54bba9){_0x1e50f0['push'](_0x1e50f0['shift']());}}}(_0x31df,0x4c10b));export*from'./file';function _0x31df(){var _0x45d2fc=['3183400EYIjub','628FgYzdZ','6vypAal','1361072jDCfWn','9YETdFZ','1925JOuyVk','3znzxEI','262643AzxByq','7134897mkPDIl','750211ckkELe','1032334pqrDra'];_0x31df=function(){return _0x45d2fc;};return _0x31df();}export*from'./friend';export*from'./group';export*from'./msg';function _0x26fe(_0x368a7b,_0x2ae140){var _0x31df65=_0x31df();return _0x26fe=function(_0x26fe18,_0x1263c8){_0x26fe18=_0x26fe18-0xf5;var _0x5dca3b=_0x31df65[_0x26fe18];return _0x5dca3b;},_0x26fe(_0x368a7b,_0x2ae140);}export*from'./user';export*from'./webapi';export*from'./sign';export*from'./system';
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
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, unknownArg: 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>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
const _0x5763e9=_0x291a;function _0x4022(){const _0x15709e=['aGXSb','PBncB','AUVwi','aYImL','转发消息超时','mSgXU','GdgOa','10hAfYOo','length','kIVvk','getMsgsIncludeSelf','recallMsg','sendStatus','onAddSendMsg','fetchRecentContact','parse','HPLIK','nfhSS','sendMsg','inYwk','dekSO','set','anUjl','获取群文件列表超时','activateChatAndGetHistory','nHtMv','delete','getRichMediaService','LUQnG','forwardMsg','253284mQVxZV','map','multiForwardMsgWithComment','getMsgService','forEach','getGroupFileList','ehinZ','getMsgsByMsgId','multiForwardMsg','OCKMT','发送超时','416136BQvanq','InlWc','568631UvzErI','setEmojiLike','chatType','com.tencent.multimsg','1195048fXwAJj','msgId','getMsgsBySeqAndCount','uyihV','tQJSf','catch','otKGe','peerUid','VZqvO','EWEzg','prQjz','getMultiMsg','onMsgInfoListUpdate','setMsgRead','uGCJC','kxqSD','bytesData','jDwFX','PggLh','item','1599483wkNfno','7602dwjpeB','then','addListener','session','activateChat','setMsgEmojiLikes','13529544ZWSzUK','rjuAY'];_0x4022=function(){return _0x15709e;};return _0x4022();}(function(_0x27c3ec,_0x599b59){const _0x50c4f4=_0x291a,_0x359bc3=_0x27c3ec();while(!![]){try{const _0x89f37=-parseInt(_0x50c4f4(0x18a))/0x1+-parseInt(_0x50c4f4(0x190))/0x2+-parseInt(_0x50c4f4(0x158))/0x3+parseInt(_0x50c4f4(0x17f))/0x4*(parseInt(_0x50c4f4(0x168))/0x5)+parseInt(_0x50c4f4(0x159))/0x6+parseInt(_0x50c4f4(0x18c))/0x7+parseInt(_0x50c4f4(0x15f))/0x8;if(_0x89f37===_0x599b59)break;else _0x359bc3['push'](_0x359bc3['shift']());}catch(_0x3432db){_0x359bc3['push'](_0x359bc3['shift']());}}}(_0x4022,0x564ea));import{selfInfo}from'@/core/data';function _0x291a(_0x388b8b,_0x4c7965){const _0x402205=_0x4022();return _0x291a=function(_0x291a3f,_0x49cbe1){_0x291a3f=_0x291a3f-0x152;let _0x4bdf23=_0x402205[_0x291a3f];return _0x4bdf23;},_0x291a(_0x388b8b,_0x4c7965);}import{log,logError}from'@/common/utils/log';import{sleep}from'@/common/utils/helper';import{napCatCore}from'@/core';import{MsgListener}from'@/core/listeners';import{randomUUID}from'crypto';const sendMessagePool={},sendSuccessCBMap={},GroupFileInfoUpdateTasks=new Map(),sentMsgTasks=new Map(),msgListener=new MsgListener();msgListener['onGroupFileInfoUpdate']=_0x3b15a2=>{for(const [_0x4ccd37,_0x59437f]of GroupFileInfoUpdateTasks){_0x59437f(_0x3b15a2),GroupFileInfoUpdateTasks['delete'](_0x4ccd37);}},msgListener[_0x5763e9(0x16e)]=_0x3fa185=>{const _0x567302=_0x5763e9,_0x20d659={'VsEYS':function(_0x5871c5,_0x2989f6){return _0x5871c5(_0x2989f6);},'aGXSb':function(_0x437aaa,_0x2d15f0){return _0x437aaa instanceof _0x2d15f0;}};for(const [_0x29501f,_0x175d6c]of sentMsgTasks){_0x20d659['VsEYS'](_0x175d6c,_0x3fa185),sentMsgTasks[_0x567302(0x17b)](_0x29501f);}if(sendMessagePool[_0x3fa185['peerUid']]){const _0x41aa00=sendMessagePool[_0x3fa185['peerUid']]?.(_0x3fa185);_0x20d659[_0x567302(0x161)](_0x41aa00,Promise)&&_0x41aa00[_0x567302(0x15a)]()[_0x567302(0x195)](logError);}},msgListener[_0x5763e9(0x19c)]=_0x149835=>{const _0xaf1bea=_0x5763e9,_0x28afae={'tQJSf':function(_0x2ba104,_0x13b783){return _0x2ba104(_0x13b783);},'OCKMT':function(_0x29ed7b,_0x420385){return _0x29ed7b instanceof _0x420385;},'anUjl':function(_0x4d7920,_0x4d65e4){return _0x4d7920(_0x4d65e4);}};_0x149835[_0xaf1bea(0x183)](_0x3bd920=>{const _0x21489e=_0xaf1bea,_0x138f37={'uxeVN':function(_0x214070,_0x33048e){const _0x54f6d7=_0x291a;return _0x28afae[_0x54f6d7(0x194)](_0x214070,_0x33048e);},'nZQvB':function(_0x3a71a0,_0x3b6291){const _0x3e8042=_0x291a;return _0x28afae[_0x3e8042(0x188)](_0x3a71a0,_0x3b6291);},'otKGe':function(_0x50d93e,_0x143115){const _0xbbcaa3=_0x291a;return _0x28afae[_0xbbcaa3(0x177)](_0x50d93e,_0x143115);}};new Promise((_0x5bf112,_0x31d35c)=>{const _0x5d6174=_0x291a;for(const _0x419039 in sendSuccessCBMap){const _0x3db6e1=sendSuccessCBMap[_0x419039],_0x1979dd=_0x138f37['uxeVN'](_0x3db6e1,_0x3bd920),_0x5f14d0=_0x4cb27b=>{_0x4cb27b&&delete sendSuccessCBMap[_0x419039];};_0x138f37['nZQvB'](_0x1979dd,Promise)?_0x1979dd['then'](_0x5f14d0):_0x138f37[_0x5d6174(0x196)](_0x5f14d0,_0x1979dd);}})[_0x21489e(0x15a)]()['catch'](log);});},setTimeout(()=>{napCatCore['onLoginSuccess'](()=>{const _0x514b92=_0x291a;napCatCore[_0x514b92(0x15b)](msgListener);});},0x64);export class NTQQMsgApi{static async[_0x5763e9(0x18d)](_0x27c51f,_0x59c709,_0x4e61ae,_0x5c75e1=!![]){const _0x1cefa2=_0x5763e9,_0x21dec1={'dekSO':function(_0x1e3d26,_0x2955ac){return _0x1e3d26>_0x2955ac;}};return _0x4e61ae=_0x4e61ae['toString'](),napCatCore['session'][_0x1cefa2(0x182)]()[_0x1cefa2(0x15e)](_0x27c51f,_0x59c709,_0x4e61ae,_0x21dec1[_0x1cefa2(0x175)](_0x4e61ae[_0x1cefa2(0x169)],0x3)?'2':'1',_0x5c75e1);}static async[_0x5763e9(0x19b)](_0x25d5cd,_0x11b20e,_0x57d916){const _0x84e8b3=_0x5763e9;return napCatCore[_0x84e8b3(0x15c)]['getMsgService']()['getMultiMsg'](_0x25d5cd,_0x11b20e,_0x57d916);}static async[_0x5763e9(0x186)](_0x574177,_0x2ed96f){const _0x519515=_0x5763e9;return await napCatCore[_0x519515(0x15c)][_0x519515(0x182)]()[_0x519515(0x186)](_0x574177,_0x2ed96f);}static async[_0x5763e9(0Line truncated
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
export interface IdMusicSignPostData {
|
||||
type: 'qq' | '163';
|
||||
id: string | number;
|
||||
}
|
||||
export interface CustomMusicSignPostData {
|
||||
type: 'custom';
|
||||
url: string;
|
||||
audio: string;
|
||||
title: string;
|
||||
image?: string;
|
||||
singer?: string;
|
||||
}
|
||||
export interface MiniAppLuaJsonType {
|
||||
prompt: string;
|
||||
title: string;
|
||||
preview: string;
|
||||
jumpUrl: string;
|
||||
tag: string;
|
||||
tagIcon: string;
|
||||
source: string;
|
||||
sourcelogo: string;
|
||||
}
|
||||
export declare function SignMiniApp(CardData: MiniAppLuaJsonType): Promise<string>;
|
||||
@@ -0,0 +1 @@
|
||||
(function(_0x1429c6,_0x5ae080){const _0x1eb8aa=_0x5c22,_0x14ca7d=_0x1429c6();while(!![]){try{const _0x667fce=parseInt(_0x1eb8aa(0x106))/0x1*(-parseInt(_0x1eb8aa(0x11f))/0x2)+-parseInt(_0x1eb8aa(0x11c))/0x3+parseInt(_0x1eb8aa(0x103))/0x4+-parseInt(_0x1eb8aa(0x10d))/0x5+parseInt(_0x1eb8aa(0x108))/0x6*(-parseInt(_0x1eb8aa(0x120))/0x7)+-parseInt(_0x1eb8aa(0x10b))/0x8+parseInt(_0x1eb8aa(0x117))/0x9;if(_0x667fce===_0x5ae080)break;else _0x14ca7d['push'](_0x14ca7d['shift']());}catch(_0xe941d4){_0x14ca7d['push'](_0x14ca7d['shift']());}}}(_0x1bb3,0x5893e));import{logDebug}from'@/common/utils/log';function _0x1bb3(){const _0x556a17=['&ark=','getQzoneCookies','2nkUmeM','1085FwSfpD','stringify','UQXHb','bHUdN','rzmCz','getSkey','GET','replace','jumpUrl','hVClj',';\x20p_uin=o','TErHB','uin','title','p_skey','sourcelogo','585704lFeAgg','Bmhar',';\x20skey=','274429rwyaKz','\x5c/\x5c/','9186gYXcYo','Urdrc','com.tencent.miniapp.lua','1027640mKgHtm','DSqyw','65405pEWuHa','litsI','tag',';\x20uin=o','lMdCh','skey','signed_ark','tagIcon','ZgWhF','miniapp','13162680XDWxBZ','source','MiniApp\x20JSON\x20消息生成失败','https://h5.qzone.qq.com/v2/vip/tx/trpc/ark-share/GenNewSignedArk?g_tk=','data','1778586PoJXvC'];_0x1bb3=function(){return _0x556a17;};return _0x1bb3();}import{NTQQUserApi}from'./user';import{selfInfo}from'../data';import{RequestUtil}from'@/common/utils/request';import{WebApi}from'./webapi';function _0x5c22(_0x365a40,_0x61dbae){const _0x1bb39c=_0x1bb3();return _0x5c22=function(_0x5c2268,_0x4a0821){_0x5c2268=_0x5c2268-0xf9;let _0x14d02d=_0x1bb39c[_0x5c2268];return _0x14d02d;},_0x5c22(_0x365a40,_0x61dbae);}export async function SignMiniApp(_0x111979){const _0x3fae1e=_0x5c22,_0x50f0d8={'hVClj':_0x3fae1e(0x10a),'LyOnu':_0x3fae1e(0x116),'jtklL':'normal','DSqyw':_0x3fae1e(0x107),'Bmhar':function(_0x44da54,_0x1ff457){return _0x44da54+_0x1ff457;},'UQXHb':function(_0x3fdb6b,_0x131985){return _0x3fdb6b+_0x131985;},'ZgWhF':function(_0x2a8605,_0x32c8be){return _0x2a8605+_0x32c8be;},'litsI':'p_skey=','Urdrc':_0x3fae1e(0xfd),'lMdCh':_0x3fae1e(0x110),'rzmCz':_0x3fae1e(0x11a),'TErHB':function(_0x386319,_0x381994){return _0x386319(_0x381994);},'iyWrA':_0x3fae1e(0xf9),'BZpll':function(_0x393bfd,_0x19fcd2,_0x4ddb4f){return _0x393bfd(_0x19fcd2,_0x4ddb4f);},'bHUdN':_0x3fae1e(0x119)};let _0x12847a={'app':_0x50f0d8[_0x3fae1e(0xfc)],'bizsrc':'tianxuan.imgJumpArk','view':_0x50f0d8['LyOnu'],'prompt':_0x111979['prompt'],'config':{'type':_0x50f0d8['jtklL'],'forward':0x1,'autosize':0x0},'meta':{'miniapp':{'title':_0x111979[_0x3fae1e(0x100)],'preview':_0x111979['preview'][_0x3fae1e(0xfa)](/\\/g,_0x3fae1e(0x107)),'jumpUrl':_0x111979[_0x3fae1e(0xfb)][_0x3fae1e(0xfa)](/\\/g,_0x50f0d8[_0x3fae1e(0x10c)]),'tag':_0x111979[_0x3fae1e(0x10f)],'tagIcon':_0x111979[_0x3fae1e(0x114)][_0x3fae1e(0xfa)](/\\/g,_0x3fae1e(0x107)),'source':_0x111979[_0x3fae1e(0x118)],'sourcelogo':_0x111979[_0x3fae1e(0x102)][_0x3fae1e(0xfa)](/\\/g,_0x3fae1e(0x107))}}};const _0x180f11=await NTQQUserApi[_0x3fae1e(0x125)]();let _0x137813=await NTQQUserApi[_0x3fae1e(0x11e)]();const _0x158fc5=WebApi['genBkn'](_0x137813[_0x3fae1e(0x101)]),_0x3c203b=_0x50f0d8[_0x3fae1e(0x104)](_0x50f0d8[_0x3fae1e(0x104)](_0x50f0d8[_0x3fae1e(0x122)](_0x50f0d8[_0x3fae1e(0x115)](_0x50f0d8[_0x3fae1e(0x10e)],_0x137813[_0x3fae1e(0x101)])+_0x3fae1e(0x105),_0x137813[_0x3fae1e(0x112)]),_0x50f0d8[_0x3fae1e(0x109)]),selfInfo[_0x3fae1e(0xff)])+_0x50f0d8[_0x3fae1e(0x111)]+selfInfo[_0x3fae1e(0xff)];let _0x304cb8=_0x50f0d8[_0x3fae1e(0x122)](_0x50f0d8[_0x3fae1e(0x124)],_0x158fc5)+_0x3fae1e(0x11d)+_0x50f0d8[_0x3fae1e(0xfe)](encodeURIComponent,JSON[_0x3fae1e(0x121)](_0x12847a)),_0x157879='';try{let _0x4adeca=await RequestUtil['HttpGetJson'](_0x304cb8,_0x50f0d8['iyWrA'],undefined,{'Cookie':_0x3c203b});_0x157879=_0x4adeca[_0x3fae1e(0x11b)][_0x3fae1e(0x113)];}catch(_0x9a2f3e){_0x50f0d8['BZpll'](logDebug,_0x50f0d8[_0x3fae1e(0x123)],_0x9a2f3e);}return _0x157879;}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
export declare class NTQQSystemApi {
|
||||
static hasOtherRunningQQProcess(): Promise<boolean>;
|
||||
static ORCImage(filePath: string): Promise<import("@/core").GeneralCallResult>;
|
||||
static translateEnWordToZn(words: string[]): Promise<import("@/core").GeneralCallResult & {
|
||||
words: string[];
|
||||
}>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
function _0x475c(){var _0x9ea50e=['hasOtherRunningQQProcess','1222848YuKNDC','6kXqoEg','496343SyUBxf','translateEnWordToZn','2647945pEnvxJ','getRichMediaService','wantWinScreenOCR','4775988VbqpFu','469754xwOsWC','2370488msbkKS','45LbyXnZ','911912qjaneW','getNodeMiscService'];_0x475c=function(){return _0x9ea50e;};return _0x475c();}function _0x5526(_0x1db919,_0x351be8){var _0x475ccd=_0x475c();return _0x5526=function(_0x55261b,_0x61acdf){_0x55261b=_0x55261b-0x11a;var _0x3f5f47=_0x475ccd[_0x55261b];return _0x3f5f47;},_0x5526(_0x1db919,_0x351be8);}var _0x513e71=_0x5526;(function(_0x351568,_0x1e87d1){var _0x2726c4=_0x5526,_0x19ca8d=_0x351568();while(!![]){try{var _0x2f6fcb=parseInt(_0x2726c4(0x127))/0x1+-parseInt(_0x2726c4(0x11f))/0x2+-parseInt(_0x2726c4(0x125))/0x3+parseInt(_0x2726c4(0x122))/0x4+-parseInt(_0x2726c4(0x11b))/0x5*(parseInt(_0x2726c4(0x126))/0x6)+-parseInt(_0x2726c4(0x11e))/0x7+parseInt(_0x2726c4(0x120))/0x8*(parseInt(_0x2726c4(0x121))/0x9);if(_0x2f6fcb===_0x1e87d1)break;else _0x19ca8d['push'](_0x19ca8d['shift']());}catch(_0x1042bf){_0x19ca8d['push'](_0x19ca8d['shift']());}}}(_0x475c,0x55d16));import{napCatCore}from'@/core';export class NTQQSystemApi{static async['hasOtherRunningQQProcess'](){var _0x494623=_0x5526;return napCatCore['util'][_0x494623(0x124)]();}static async['ORCImage'](_0x1af039){var _0x1dfa5b=_0x5526;return napCatCore['session'][_0x1dfa5b(0x123)]()[_0x1dfa5b(0x11d)](_0x1af039);}static async[_0x513e71(0x11a)](_0x3db422){var _0x217f95=_0x513e71;return napCatCore['session'][_0x217f95(0x11c)]()[_0x217f95(0x11a)](_0x3db422);}}
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
import { User } from '@/core/entities';
|
||||
import { GeneralCallResult } from '@/core';
|
||||
export declare class NTQQUserApi {
|
||||
static setSelfOnlineStatus(status: number, extStatus: number, batteryStatus: number): Promise<GeneralCallResult>;
|
||||
static like(uid: string, count?: number): Promise<{
|
||||
result: number;
|
||||
errMsg: string;
|
||||
succCounts: number;
|
||||
}>;
|
||||
static setQQAvatar(filePath: string): Promise<{
|
||||
result: number;
|
||||
errMsg: string;
|
||||
}>;
|
||||
static getSelfInfo(): Promise<void>;
|
||||
static getUserInfo(uid: string): Promise<void>;
|
||||
static getUserDetailInfo(uid: string): Promise<User>;
|
||||
static getPSkey(domainList: string[], cached?: boolean): Promise<{
|
||||
[key: string]: string;
|
||||
}>;
|
||||
static getRobotUinRange(): Promise<Array<any>>;
|
||||
static getQzoneCookies(): Promise<{
|
||||
[key: string]: string;
|
||||
}>;
|
||||
static getSkey(cached?: boolean): Promise<string | undefined>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
const _0x3d52d6=_0x1b50;(function(_0x1e5830,_0x3ed884){const _0x51bd86=_0x1b50,_0x53f897=_0x1e5830();while(!![]){try{const _0x246212=parseInt(_0x51bd86(0x129))/0x1*(-parseInt(_0x51bd86(0x138))/0x2)+parseInt(_0x51bd86(0xfd))/0x3+parseInt(_0x51bd86(0x143))/0x4+parseInt(_0x51bd86(0x102))/0x5*(parseInt(_0x51bd86(0x103))/0x6)+parseInt(_0x51bd86(0x12d))/0x7*(parseInt(_0x51bd86(0x137))/0x8)+parseInt(_0x51bd86(0x145))/0x9*(-parseInt(_0x51bd86(0x135))/0xa)+-parseInt(_0x51bd86(0x10a))/0xb*(-parseInt(_0x51bd86(0x11c))/0xc);if(_0x246212===_0x3ed884)break;else _0x53f897['push'](_0x53f897['shift']());}catch(_0x3b007b){_0x53f897['push'](_0x53f897['shift']());}}}(_0x55d4,0xca027));import{Credentials,selfInfo,uid2UinMap}from'@/core/data';function _0x55d4(){const _0x145b92=['PskeyTime','getPSkey','robotUinRanges','getMsgService','getPskey','uid','FTkbG','https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=','&clientkey=','BLhBx','push','setBuddyProfileLike','then','12120dLiIzW','forceFetchClientKey','result','getSelfInfo','FNhhx','ZSFXN','verLr','YzcYL','onLoginSuccess','HttpsGetCookies','like','SCDWT','assign','492617gEpApj','xoewm','set','getUserDetailInfoWithBizInfo','387674WyoChn','fromEntries','IKzhS','EKJaU','getUserInfo','%2Finfocenter&keyindex=19%27','length','skey','14427580RHohvs','CFgPh','80pqdxHU','6HBhBJd','&u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=','hqmVO','Skey','domainPskeyMap','pMQvV','setQQAvatar','delete','&u1=https%3A%2F%2Fuser.qzone.qq.com%2F','knXNr','setSelfOnlineStatus','5465380eEIaOS','CsifL','9dFtcgt','now','hfNCY','uin','IiYuJ','get','EABpH','entries','PskeyData','CreatTime','getTipOffService','3896244zIHWuw','response','获取Pskey失败','KeyIndex','SpkNf','17045VWNfRD','318AUjVPh','clientKey','ClientKey','getRobotUinRange','getProfileService','session','keyIndex','3795ITdVap','errMsg','EeTZe','kFAfp','UwIVi'];_0x55d4=function(){return _0x145b92;};return _0x55d4();}import{napCatCore}from'@/core';import{ProfileListener}from'@/core/listeners';import{randomUUID}from'crypto';import{RequestUtil}from'@/common/utils/request';import{logDebug,logError}from'@/common/utils/log';const userInfoCache={},profileListener=new ProfileListener(),userDetailHandlers=new Map();function _0x1b50(_0x14ba7c,_0x3ea0b6){const _0x55d4ea=_0x55d4();return _0x1b50=function(_0x1b506f,_0x5199ba){_0x1b506f=_0x1b506f-0xf6;let _0xd3caa7=_0x55d4ea[_0x1b506f];return _0xd3caa7;},_0x1b50(_0x14ba7c,_0x3ea0b6);}profileListener['onProfileDetailInfoChanged']=_0xe4ff9a=>{const _0x49b23e=_0x1b50;userInfoCache[_0xe4ff9a[_0x49b23e(0x114)]]=_0xe4ff9a,userDetailHandlers['forEach'](_0x4482d4=>_0x4482d4(_0xe4ff9a));},setTimeout(()=>{const _0x144791=_0x1b50;napCatCore[_0x144791(0x124)](()=>{napCatCore['addListener'](profileListener);});},0x64);export class NTQQUserApi{static async[_0x3d52d6(0x142)](_0x40ca2a,_0x1f0146,_0x1dc3f2){const _0x1f2b54=_0x3d52d6;return napCatCore[_0x1f2b54(0x108)][_0x1f2b54(0x112)]()['setStatus']({'status':_0x40ca2a,'extStatus':_0x1f0146,'batteryStatus':_0x1dc3f2});}static async[_0x3d52d6(0x126)](_0x5b8fe4,_0x4e0f91=0x1){const _0x47bb48=_0x3d52d6;return napCatCore[_0x47bb48(0x108)]['getProfileLikeService']()[_0x47bb48(0x11a)]({'friendUid':_0x5b8fe4,'sourceId':0x47,'doLikeCount':_0x4e0f91,'doLikeTollCount':0x0});}static async[_0x3d52d6(0x13e)](_0xdec8c4){const _0x279ad9=_0x3d52d6,_0x27ad8c=napCatCore[_0x279ad9(0x108)][_0x279ad9(0x107)]()['setHeader'](_0xdec8c4);return{'result':_0x27ad8c?.[_0x279ad9(0x11e)],'errMsg':_0x27ad8c?.[_0x279ad9(0x10b)]};}static async[_0x3d52d6(0x11f)](){}static async[_0x3d52d6(0x131)](_0x3875bf){}static async['getUserDetailInfo'](_0x394360){const _0x34b683={'CsifL':function(_0xe28acf,_0x455c96){return _0xe28acf(_0x455c96);},'zjpeC':function(_0x1e63e3){return _0x1e63e3();},'yQPPb':function(_0x4b14d0,_0x39e573,_0x44dc1e){return _0x4b14d0(_0x39e573,_0x44dc1e);}},_0x3e0fe1=napCatCore['session']['getProfileService']();return new Promise((_0x166137,_0x2f4018)=>{const _0x22012d=_0x1b50,_0x517283={'EeTZe':function(_0x58b08b,_0x2e2b0e){const _0x3077cc=_0x1b50;return _0x34b683[_0x3077cc(0x144)](_0x58b08b,_0x2e2b0e);}},_0x47be5d=_0x34b683['zjpeC'](randomUUID);let _0x181154=![],_0x3a293e=undefined,_0xefc1e5=!![];_0x34b683['yQPPb'](setTimeout,()=>{const _0x4ae69b=_0x1b50;!_0x181154&&(_0x3a293e?_0x517283[_0x4ae69b(0x10c)](_0x166137,_0x3a293e):_0x517283[_0x4ae69b(0x10c)](_0x2f4018,'getUserDetailInfo\x20timeout')),userDetailHandlers[_0x4ae69b(0x13f)](_0x47be5d);},0x1388),userDetailHandlers['set'](_0x47be5d,_0x127602=>{const _0x3eb48d=_0x1b50;_0x127602['uid']===_0x394360&&(uid2UinMap[_0x394360]=_0x127602[_0x3eb48d(0x148)],_0xefc1e5?(_0x3a293e=_0x127602,_0xefc1e5=![]):(_0x181154=!![],_0x517283['EeTZe'](_0x166137,_0x127602)));}),_0x3e0fe1[_0x22012d(0x12c)](_0x394360,[0x0])[_0x22012d(0x11b)](_0x4d3a5d=>{});});}static async[_0x3d52d6(0x110)](_0x5b56f4,_0x341c6d=!![]){const _0x37f85b=_0x3d52d6,_0x2ec163={'hfNCY':function(_0x2fbc69,_0x26b908)Line truncated
|
||||
Vendored
+105
@@ -0,0 +1,105 @@
|
||||
export declare enum WebHonorType {
|
||||
ALL = "all",
|
||||
TALKACTIVE = "talkative",
|
||||
PERFROMER = "performer",
|
||||
LEGEND = "legend",
|
||||
STORONGE_NEWBI = "strong_newbie",
|
||||
EMOTION = "emotion"
|
||||
}
|
||||
export interface WebApiGroupMember {
|
||||
uin: number;
|
||||
role: number;
|
||||
g: number;
|
||||
join_time: number;
|
||||
last_speak_time: number;
|
||||
lv: {
|
||||
point: number;
|
||||
level: number;
|
||||
};
|
||||
card: string;
|
||||
tags: string;
|
||||
flag: number;
|
||||
nick: string;
|
||||
qage: number;
|
||||
rm: number;
|
||||
}
|
||||
export interface WebApiGroupNoticeFeed {
|
||||
u: number;
|
||||
fid: string;
|
||||
pubt: number;
|
||||
msg: {
|
||||
text: string;
|
||||
text_face: string;
|
||||
title: string;
|
||||
pics?: {
|
||||
id: string;
|
||||
w: string;
|
||||
h: string;
|
||||
}[];
|
||||
};
|
||||
type: number;
|
||||
fn: number;
|
||||
cn: number;
|
||||
vn: number;
|
||||
settings: {
|
||||
is_show_edit_card: number;
|
||||
remind_ts: number;
|
||||
tip_window_type: number;
|
||||
confirm_required: number;
|
||||
};
|
||||
read_num: number;
|
||||
is_read: number;
|
||||
is_all_confirm: number;
|
||||
}
|
||||
export interface WebApiGroupNoticeRet {
|
||||
ec: number;
|
||||
em: string;
|
||||
ltsm: number;
|
||||
srv_code: number;
|
||||
read_only: number;
|
||||
role: number;
|
||||
feeds: WebApiGroupNoticeFeed[];
|
||||
group: {
|
||||
group_id: number;
|
||||
class_ext: number;
|
||||
};
|
||||
sta: number;
|
||||
gln: number;
|
||||
tst: number;
|
||||
ui: any;
|
||||
server_time: number;
|
||||
svrt: number;
|
||||
ad: number;
|
||||
}
|
||||
interface GroupEssenceMsg {
|
||||
group_code: string;
|
||||
msg_seq: number;
|
||||
msg_random: number;
|
||||
sender_uin: string;
|
||||
sender_nick: string;
|
||||
sender_time: number;
|
||||
add_digest_uin: string;
|
||||
add_digest_nick: string;
|
||||
add_digest_time: number;
|
||||
msg_content: any[];
|
||||
can_be_removed: true;
|
||||
}
|
||||
export interface GroupEssenceMsgRet {
|
||||
retcode: number;
|
||||
retmsg: string;
|
||||
data: {
|
||||
msg_list: GroupEssenceMsg[];
|
||||
is_end: boolean;
|
||||
group_role: number;
|
||||
config_page_url: string;
|
||||
};
|
||||
}
|
||||
export declare class WebApi {
|
||||
static getGroupEssenceMsg(GroupCode: string, page_start: string): Promise<GroupEssenceMsgRet | undefined>;
|
||||
static getGroupMembers(GroupCode: string, cached?: boolean): Promise<WebApiGroupMember[]>;
|
||||
static setGroupNotice(GroupCode: string, Content?: string): Promise<any>;
|
||||
static getGrouptNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet>;
|
||||
static genBkn(sKey: string): string;
|
||||
static getGroupHonorInfo(groupCode: string, getType: WebHonorType): Promise<any>;
|
||||
}
|
||||
export {};
|
||||
@@ -0,0 +1 @@
|
||||
const _0x2484db=_0x21a5;(function(_0x36a334,_0x194a4e){const _0x15e4d7=_0x21a5,_0x11d847=_0x36a334();while(!![]){try{const _0x6d43c5=parseInt(_0x15e4d7(0x1e2))/0x1*(parseInt(_0x15e4d7(0x1ed))/0x2)+parseInt(_0x15e4d7(0x1c9))/0x3*(-parseInt(_0x15e4d7(0x232))/0x4)+parseInt(_0x15e4d7(0x24e))/0x5*(-parseInt(_0x15e4d7(0x23a))/0x6)+parseInt(_0x15e4d7(0x1e8))/0x7*(-parseInt(_0x15e4d7(0x212))/0x8)+-parseInt(_0x15e4d7(0x21e))/0x9+parseInt(_0x15e4d7(0x223))/0xa+-parseInt(_0x15e4d7(0x226))/0xb*(parseInt(_0x15e4d7(0x203))/0xc);if(_0x6d43c5===_0x194a4e)break;else _0x11d847['push'](_0x11d847['shift']());}catch(_0x36acea){_0x11d847['push'](_0x11d847['shift']());}}}(_0x3fa6,0x88ada));import{WebGroupData,selfInfo}from'@/core/data';import{logDebug}from'@/common/utils/log';import{NTQQUserApi}from'./user';import{RequestUtil}from'@/common/utils/request';export var WebHonorType;(function(_0x57ac00){const _0x3964a9=_0x21a5,_0x2b2470={'tjkcm':_0x3964a9(0x1ce),'MPpRH':_0x3964a9(0x22f),'FWHbR':_0x3964a9(0x239),'pZAsT':_0x3964a9(0x202),'DlQbK':_0x3964a9(0x207),'VDFNF':_0x3964a9(0x1de),'ZHskB':_0x3964a9(0x24a),'RNymX':_0x3964a9(0x241),'ahWRQ':_0x3964a9(0x1ec),'TzMBq':'EMOTION'},_0x5ad34f=_0x2b2470['tjkcm'][_0x3964a9(0x1cc)]('|');let _0x28ef80=0x0;while(!![]){switch(_0x5ad34f[_0x28ef80++]){case'0':_0x57ac00[_0x2b2470[_0x3964a9(0x1dc)]]=_0x2b2470[_0x3964a9(0x240)];continue;case'1':_0x57ac00[_0x2b2470[_0x3964a9(0x243)]]=_0x2b2470[_0x3964a9(0x252)];continue;case'2':_0x57ac00[_0x3964a9(0x217)]=_0x2b2470['VDFNF'];continue;case'3':_0x57ac00[_0x2b2470[_0x3964a9(0x22a)]]=_0x2b2470[_0x3964a9(0x222)];continue;case'4':_0x57ac00[_0x2b2470[_0x3964a9(0x224)]]=_0x3964a9(0x259);continue;case'5':_0x57ac00[_0x2b2470[_0x3964a9(0x1ca)]]=_0x3964a9(0x211);continue;}break;}}(WebHonorType||(WebHonorType={})));function _0x21a5(_0x48231e,_0x5d10f7){const _0x3fa605=_0x3fa6();return _0x21a5=function(_0x21a53d,_0x288c22){_0x21a53d=_0x21a53d-0x1c2;let _0xce74e4=_0x3fa605[_0x21a53d];return _0xce74e4;},_0x21a5(_0x48231e,_0x5d10f7);}function _0x3fa6(){const _0x4f82e2=['https://web.qun.qq.com/cgi-bin/announce/get_t_list?bkn=','aOPdO','push','2003193LkUoWi','GET','KzgSb','https://qun.qq.com/interactive/honorlist?gc=','RNymX','9166500FpJbQX','ahWRQ','zGnhH','62249MOsvib','Qqzfq','WIokH','https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=','ZHskB','vDnVe','RJDCt','获取群聊之火失败','legend_list','STORONGE_NEWBI','&pinned=0&type=1&settings={\x22is_show_edit_card\x22:1,\x22tip_window_type\x22:1,\x22confirm_required\x22:1}','TFKvC','417212AElwgj','dQnVm','performer_list','arukL','&group_code=','getGroupMembers','qid=','strong_newbie','778098SqSTJt','IOtKw','lxhfh','zvoMT','zwXbC','KobDk','FWHbR','performer','getSkey','pZAsT','uDRfI','UHIGB','length','kSjgn','getPSkey','avatar','PERFROMER','parse','retcode','&ft=23&ni=1&n=1&i=1&log_read=1&platform=1&s=-1&n=20','10PvuVHi','&end=','&bkn=','qun.qq.com','DlQbK','https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn=','KrHeQ','NoPGp','uin','ivjAO','noDoc','legend','ysElp','Pyjkf','ExWEE','charCodeAt','https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=0&end=40&sort=1&gc=','BEVCM','bpHfK','uXUIN','ceil',';\x20p_uin=o','RiJUK','errcode','getGroupEssenceMsg','GroupData','dMqyB','OrhiI','p_skey=','MDgCp','tjJNt','VVHCj','HwCDe','12geQqIn','TzMBq','获取快乐源泉失败','split','SSmPd','1|2|3|4|0|5','MTiau','MnTbj','pNmHe','yFfNz','qgrZM','JLTDW',';\x20skey=','match','获取当前群荣耀失败','mems','get','CMnug','talkativeList','MPpRH','talkative_list','talkative','YxghZ','HBQEj','MTyTX','927413DyPHIi','HttpGetJson','Evbpu','description','fcUKU','emotion_list','1309063SremUA','QrBvK','PSAOy','count','LEGEND','2yOJZEs','mSFme','&type=','set','osvme','trim','获取群聊炽焰失败','now','QbGuk','iLFyk','strong_newbie_list','dufAH','utcCt','toString','yxAXB','Txhke','desc','kebAO','EMOTION','CWUEg','sHNiS','ALL','420LJqHCI','RafKu','GroupTime','qMDKw','all','name','KSoMp','POST','ikSLs','pgoTj','genBkn','获取龙王信息失败','JvJJg','nGuoi','emotion','8KYdBnF','actorList','FXWIG','RvgAY',';\x20uin=o','TALKACTIVE','&sort=1&gc=','&qid=','SHOCU'];_0x3fa6=function(){return _0x4f82e2;};return _0x3fa6();}export class WebApi{static async[_0x2484db(0x266)](_0x24e876,_0x5d46b0){const _0x2a4588=_0x2484db,_0xf8cbab={'ExWEE':_0x2a4588(0x251),'NoPGp':function(_0x340c1f,_0x1212b2){return _0x340c1f+_0x1212b2;},'sHNiS':function(_0x5a916f,_0xd3dfab){return _0x5a916f+_0xd3dfab;},'arukL':function(_0x142f04,_0x24ef83){return _0x142f04+_0x24ef83;},'tjJNt':_0x2a4588(0x1c4),'SSmPd':_0x2a4588(0x1d5),'qMDKw':_0x2a4588(0x263),'osvme':_0x2a4588(0x216),'pgoTj':function(_0x2acdeb,_0xf85699){return _0x2acdeb||_0xf85699;},'zMXcs':function(_0x14494c,_0x4029fb){return _0x14494c+_0x4029fb;},'RafKu':function(_0x4b9d11,_0x57fe2a){return _0x4b9d11+_0x57fe2a;},'Pyjkf':'&page_start=','fcUKU':'&page_limit=20','WIokH':_0x2a4588(0x21f),'zGnhH':function(_0x5f59ba,_0x5942d5){return _0x5f59ba!==_0x5942d5;}},_0x502b54=(await NTQQUserApi[Line truncated
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
export interface NTQQWindow {
|
||||
windowName: string;
|
||||
windowUrlHash: string;
|
||||
}
|
||||
export declare class NTQQWindows {
|
||||
static GroupHomeWorkWindow: NTQQWindow;
|
||||
static GroupNotifyFilterWindow: NTQQWindow;
|
||||
static GroupEssenceWindow: NTQQWindow;
|
||||
}
|
||||
export declare class NTQQWindowApi {
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
(function(_0x3f718c,_0x5aba03){var _0x3040fb=_0xc42f,_0x44e7f6=_0x3f718c();while(!![]){try{var _0x500389=parseInt(_0x3040fb(0x278e4))/0x1+-parseInt(_0x3040fb(0xccc1))/0x2+-parseInt(_0x3040fb(0x19687))/0x3*(parseInt(_0x3040fb(0x2f9cd))/0x4)+-parseInt(_0x3040fb(0x3a2d5))/0x5*(-parseInt(_0x3040fb(0x84ac))/0x6)+parseInt(_0x3040fb(0x1e9b6))/0x7*(parseInt(_0x3040fb(0x2b60d))/0x8)+parseInt(_0x3040fb(0x44e18))/0x9*(parseInt(_0x3040fb(0x27988))/0xa)+-parseInt(_0x3040fb(0x5d64))/0xb;if(_0x500389===_0x5aba03)break;else _0x44e7f6['push'](_0x44e7f6['shift']());}catch(_0x4080ca){_0x44e7f6['push'](_0x44e7f6['shift']());}}}(_0x2b99,0x6088c),(function(_0x21ad5d,_0x44d9cf){var _0x920790=_0xc42f,_0x7ae31c={'ekhpx':function(_0x3c6b08){return _0x3c6b08();},'EnxSY':function(_0x12f121,_0x483045){return _0x12f121+_0x483045;},'yQIkv':function(_0x25a210,_0x1f3a4b){return _0x25a210+_0x1f3a4b;},'YSskc':function(_0x308239,_0x387b9b){return _0x308239(_0x387b9b);},'KZVig':function(_0x27464e,_0x4f9cf2){return _0x27464e/_0x4f9cf2;},'myngm':function(_0x161be4,_0x357891){return _0x161be4/_0x357891;},'tFxQE':function(_0x424552,_0x42a17e){return _0x424552(_0x42a17e);},'nitxh':function(_0x5ab957,_0x3bf8f1){return _0x5ab957/_0x3bf8f1;},'rbRfV':function(_0x2e8083,_0x147c23){return _0x2e8083(_0x147c23);},'DvRGy':function(_0x53e6e5,_0x5246a8){return _0x53e6e5(_0x5246a8);},'RPcQU':function(_0x5382ef,_0x38fe57){return _0x5382ef*_0x38fe57;},'DGfxx':function(_0x482c05,_0x49e9db){return _0x482c05(_0x49e9db);},'zEiYL':function(_0x54d284,_0x36979b){return _0x54d284(_0x36979b);},'SWAHb':function(_0x353b7a,_0x4f24e1){return _0x353b7a*_0x4f24e1;},'XClIt':function(_0x40bf74,_0x29769f){return _0x40bf74/_0x29769f;},'Fisfu':function(_0x10e151,_0x115fcb){return _0x10e151(_0x115fcb);},'YSjEo':function(_0x383e0a,_0x46b86c){return _0x383e0a===_0x46b86c;},'ZVkor':'push','Qxzhh':_0x920790(0x4913e)},_0x1dfbfe=_0x467a,_0x2ad3ba=_0x7ae31c[_0x920790(0x81f4)](_0x21ad5d);while(!![]){try{var _0x1a8114=_0x7ae31c[_0x920790(0x12dcc)](_0x7ae31c[_0x920790(0x12dcc)](_0x7ae31c[_0x920790(0x3bc78)](_0x7ae31c[_0x920790(0x12dcc)](_0x7ae31c[_0x920790(0x12dcc)](_0x7ae31c[_0x920790(0x12dcc)](-_0x7ae31c['YSskc'](parseInt,_0x1dfbfe(0xfc02))/0x1,_0x7ae31c[_0x920790(0x1ebd2)](-_0x7ae31c[_0x920790(0x3b48d)](parseInt,_0x1dfbfe(0x18b9b)),0x2)),_0x7ae31c[_0x920790(0x46b3a)](_0x7ae31c[_0x920790(0x31ba6)](parseInt,_0x1dfbfe(0x10f5d)),0x3)*_0x7ae31c['nitxh'](_0x7ae31c[_0x920790(0x2737c)](parseInt,_0x7ae31c[_0x920790(0x2a83e)](_0x1dfbfe,0xec44)),0x4)),_0x7ae31c[_0x920790(0x39cc9)](parseInt(_0x1dfbfe(0x65b5))/0x5,_0x7ae31c[_0x920790(0x1ebd2)](parseInt(_0x1dfbfe(0x1136b)),0x6))),_0x7ae31c[_0x920790(0x12df)](parseInt,_0x7ae31c[_0x920790(0x2bc2f)](_0x1dfbfe,0x1ff35))/0x7),_0x7ae31c[_0x920790(0x1338f)](_0x7ae31c[_0x920790(0x43dd6)](_0x7ae31c[_0x920790(0x3b48d)](parseInt,_0x7ae31c[_0x920790(0x12df)](_0x1dfbfe,0x1a8ee)),0x8),_0x7ae31c[_0x920790(0x2ba78)](parseInt,_0x7ae31c[_0x920790(0x2737c)](_0x1dfbfe,0xe514))/0x9)),_0x7ae31c['KZVig'](-parseInt(_0x1dfbfe(0x1feef)),0xa));if(_0x7ae31c['YSjEo'](_0x1a8114,_0x44d9cf))break;else _0x2ad3ba[_0x7ae31c['ZVkor']](_0x2ad3ba[_0x7ae31c[_0x920790(0x2a1c9)]]());}catch(_0x60f1d0){_0x2ad3ba[_0x7ae31c[_0x920790(0x4dc3f)]](_0x2ad3ba[_0x7ae31c[_0x920790(0x2a1c9)]]());}}}(_0x2002,0xd4f04),(function(_0x2b8152,_0xc13d83){var _0x412b38=_0xc42f,_0x216e2d={'TZRXJ':function(_0x1933d3,_0x15fe75){return _0x1933d3+_0x15fe75;},'xaIEM':function(_0x1c22ee,_0x62c7ee){return _0x1c22ee/_0x62c7ee;},'mvqIP':function(_0x391450,_0x17f707){return _0x391450(_0x17f707);},'ZXPFY':function(_0x135ac9,_0x2cbb3c){return _0x135ac9/_0x2cbb3c;},'kkcFH':function(_0x2802d3,_0x49e4b4){return _0x2802d3*_0x49e4b4;},'sQnrp':function(_0x34b84d,_0xfcc6ce){return _0x34b84d*_0xfcc6ce;},'inuqK':function(_0x7b18ad,_0x4146e6){return _0x7b18ad/_0x4146e6;},'TnHcz':function(_0x7ef2f8,_0x2f1a36){return _0x7ef2f8(_0x2f1a36);},'oVgca':function(_0x4edc40,_0xcd475d){return _0x4edc40===_0xcd475d;},'QYwAe':'shift','NQAwA':function(_0x2a37d7,_0x1d9b00){return _0x2a37d7(_0x1d9b00);},'GBmoc':function(_0x4c9b49,_0x1c1762){return _0x4c9b49+_0x1c1762;},'Chdgr':_0x412b38(0x4ebd1),'NnCbo':function(_0x1f7b16,_0x564426){return _0x1f7b16(_0x564426);},'sVglL':function(_0x14e26f,_0x1da8d8){return _0x14e26f(_0x1da8d8);},'OTZUv':'CHqaE','HezFB':function(_0x2d06d9,_0x228f53){return _0x2d06d9(_0x228f53);},'eyahE':function(_0x5d7041,_0x2f4345){return _0x5d7041/_0x2f4345;},'mRHAC':function(_0x5021bd,_0x5e9647){return _0x5021bd(_0x5e9647);},'FctyR':function(_0x48e217,_0x2c4172){return _0x48e217/_0x2c4172;},'ugoDO':_0x412b38(0x7b28),'yXYHK':_0x412b38(0x46e5d),'VREZL':function(_0x48c24f,_0x4f3855){return _0x48c24f(_0x4f3855);},'WfpEI':function(_0x289c14,_0x33240e){return _0x289c14/_0x33240e;},'nNLpe':function(_0x37d2b8,_0x17ae9f){return _0x37d2b8(_0x17ae9f);},'eEqVY':function(_0x453dcb,_0x32daf0){return _0x453dcb(_0x32daf0);},'IHCoN':function(_0x42070e,_0x45193b){return _0x42070e(_0x45193b);},'etGUH':function(_0x28d117,_0x792e4){return _0x28d117(_0x7Line truncated
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
/// <reference types="node" />
|
||||
import { NodeIQQNTWrapperEngine, NodeIQQNTWrapperSession, NodeQQNTWrapperUtil } from '@/core/wrapper';
|
||||
import { QuickLoginResult } from '@/core/services';
|
||||
import { BuddyListener, GroupListener, MsgListener, ProfileListener } from '@/core/listeners';
|
||||
export interface OnLoginSuccess {
|
||||
(uin: string, uid: string): void | Promise<void>;
|
||||
}
|
||||
export declare class NapCatCore {
|
||||
readonly session: NodeIQQNTWrapperSession;
|
||||
readonly util: NodeQQNTWrapperUtil;
|
||||
readonly engine: NodeIQQNTWrapperEngine;
|
||||
private readonly loginListener;
|
||||
private loginService;
|
||||
private onLoginSuccessFuncList;
|
||||
private proxyHandler;
|
||||
constructor();
|
||||
get dataPath(): string;
|
||||
get dataPathGlobal(): string;
|
||||
private initConfig;
|
||||
private initSession;
|
||||
private initDataListener;
|
||||
addListener(listener: BuddyListener | GroupListener | MsgListener | ProfileListener): number;
|
||||
onLoginSuccess(func: OnLoginSuccess): void;
|
||||
quickLogin(uin: string): Promise<QuickLoginResult>;
|
||||
qrLogin(cb: (url: string, base64: string, buffer: Buffer) => Promise<void>): Promise<{
|
||||
url: string;
|
||||
base64: string;
|
||||
buffer: Buffer;
|
||||
}>;
|
||||
passwordLogin(uin: string, password: string, proofSig?: string, proofRand?: string, proofSid?: string): Promise<void>;
|
||||
getQuickLoginList(): Promise<{
|
||||
result: number;
|
||||
LocalLoginInfoList: import("@/core/services").LoginListItem[];
|
||||
}>;
|
||||
}
|
||||
export declare const napCatCore: NapCatCore;
|
||||
@@ -0,0 +1 @@
|
||||
const _0x1b51e1=_0x33cf;(function(_0x4e5840,_0x29e2af){const _0x1cbbb4=_0x33cf,_0x387092=_0x4e5840();while(!![]){try{const _0x2cf78b=-parseInt(_0x1cbbb4(0x222))/0x1+-parseInt(_0x1cbbb4(0x1da))/0x2*(-parseInt(_0x1cbbb4(0x1d2))/0x3)+-parseInt(_0x1cbbb4(0x25a))/0x4+-parseInt(_0x1cbbb4(0x1df))/0x5*(-parseInt(_0x1cbbb4(0x1ef))/0x6)+-parseInt(_0x1cbbb4(0x20a))/0x7*(-parseInt(_0x1cbbb4(0x1f4))/0x8)+-parseInt(_0x1cbbb4(0x1e4))/0x9+parseInt(_0x1cbbb4(0x1d9))/0xa*(-parseInt(_0x1cbbb4(0x1d8))/0xb);if(_0x2cf78b===_0x29e2af)break;else _0x387092['push'](_0x387092['shift']());}catch(_0x3d7a1){_0x387092['push'](_0x387092['shift']());}}}(_0x2f25,0xcf6cf));import _0x1c9126 from'@/core/wrapper';import{BuddyListener,GroupListener,LoginListener,MsgListener,ProfileListener,SessionListener}from'@/core/listeners';import{DependsAdapter,DispatcherAdapter,GlobalAdapter}from'@/core/adapters';import _0x15fd77 from'node:path';import _0x591651 from'node:os';function _0x2f25(){const _0x266f89=['addKernelProfileListener','getLoginList','QaXme','getNTUserDataInfoConfig','6811WaZDDI','proxyHandler','onQRCodeSessionFailed','loginErrorInfo','GgBNm','ZBldH','addListener','getBuddyService','clientType','updateMsg','aojEw','pngBase64QrcodeData','groupCode','initWithDeskTopConfig','./nt_qq/global','GYPNd','addKernelGroupListener','qeTTD','push','tipsTitle','createMemberListScene','util','memberCount','addKernelLoginListener','38923TlYUFc','LocalLoginInfoList','message_received','curVersion',')已登录,无法重复登录','update','140022013','homedir','groupMemberList_MainWindow','has','AVOhx','\x20has\x20no\x20method\x20','没有可快速登录的QQ号','initSession','ukWyU','undefined','resolve','replace','startNT','onQRCodeLoginSucceed','NodeIDependsAdapter','isQuickLogin','addKernelMsgListener','登录失败','engine','quickLogin','fileLogLevel','NodeIQQNTWrapperSession','账号设备(','zgMmG','getQRCodePicture','onBuddyListChange','QvbMY','quickLoginWithUin','NodeIKernelProfileListener','NodeIKernelBuddyListener','onMemberListChange','getNextMemberList','zMyGA','zzEoY','HFDHi','getBuddyList','qYuZN','nSzLE','LaNee','catch','consoleLogLevel','length','uin','YBhMp','hcMgg','loginService','packet_sent','createHash','uVomb','./.config/QQ','783264pHFJUH','qIQqX','onMsgInfoListUpdate','uid','onQRCodeGetPicture','onProfileDetailInfoChanged','pkqrt','ctaAX','_GW_B','DurEo','session','uOUGe','快速登录失败\x20','启动失败:\x20','bSQja','digest','hDHmQ',')\x20在线状态变更','sceneId','data:image/png;base64,','MRnto','constructor','onAddSendMsg','MsgListener','NodeIKernelMsgListener','oCiah','packet_received','onRecvMsg','delete','dataPathGlobal','then','last_message_time','initConfig','LsLVd','split','map','NodeIKernelLoginListener','message_sent','cabtl','GroupListener','VJlDv','zUcxt','loginListener','onLoginSuccessFuncList','IMMoA','uRRLk','set','mkdirSync','SMNSH','xSFls','FNTml','62307cxiNjA','onLoginSuccess','getMsgByLongId','uuFKo','ebHxZ','UGMNc','7271ipkETR','7180eTpUWU','22sgmhKC','initDataListener','name','assign','XHJSO','15LTiQLX','getQuickLoginList','init','onSessionInitComplete','./NapCat/data','5904783Vkorkr','onUserLoggedIn','dataPath','IlkJE','stringify','onKickedOffLine','tOdjM','lEBNX','getGroupService','qrcodeUrl','forEach','1641852sxijuD','-v2.db','result','lVGgp','NodeIKernelSessionListener','9584pzvtaP','dWyha','passwordLogin','addMsg','find','recallTime','数据库初始化失败','OLSeP','getMsgService','本账号数据/缓存目录:','tipsDesc','errMsg','addKernelBuddyListener','[KickedOffLine]\x20[','koHrK','zOyfk','get','onLineDev'];_0x2f25=function(){return _0x266f89;};return _0x2f25();}import _0x70fcfd from'node:fs';import{appid,qqVersionConfigInfo}from'@/common/utils/QQBasicInfo';import{hostname,systemVersion}from'@/common/utils/system';import{genSessionConfig}from'@/core/sessionConfig';import{dbUtil}from'@/common/utils/db';import{sleep}from'@/common/utils/helper';import _0xa65f28 from'node:crypto';import{rawFriends,friends,groupMembers,groups,selfInfo,stat,uid2UinMap}from'@/core/data';import{enableConsoleLog,enableFileLog,log,logDebug,logError,setLogLevel,setLogSelfInfo}from'@/common/utils/log';import{napCatConfig}from'@/core/utils/config';export class NapCatCore{['session'];[_0x1b51e1(0x21f)];['engine'];[_0x1b51e1(0x1c9)];[_0x1b51e1(0x255)];['onLoginSuccessFuncList']=[];[_0x1b51e1(0x20b)]={'get'(target,prop,receiver){const _0x3e6957=_0x1b51e1,vlUtIz={'QaXme':function(x,y){return x===y;},'DurEo':_0x3e6957(0x231)};if(vlUtIz[_0x3e6957(0x208)](typeof target[prop],vlUtIz[_0x3e6957(0x263)]))return(...args)=>{const _0x550d57=_0x3e6957;logDebug(target['constructor']['name']+_0x550d57(0x22d)+prop);};return Reflect[_0x3e6957(0x204)](target,prop,receiver);}};constructor(){const _0x37c6f4=_0x1b51e1,_0x4a2a5c={'aojEw':function(_0x5199a5,_0x3aefc8){return _0x5199a5(_0x3aefc8);},'uuFKo':function(_0x26a4b8,_0x597c9a){return _0x26a4b8+_0x597c9a;},'zNPbs':'当前账号(','cabtl':_0x37c6f4(0x226),'LaNee':function(_0x3b4Line truncated
|
||||
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
import { type Friend, type FriendRequest, type Group, type GroupMember, GroupNotify, type SelfInfo, BuddyCategoryType } from './entities';
|
||||
import { WebApiGroupMember } from '@/core/apis';
|
||||
export declare const Credentials: {
|
||||
Skey: string;
|
||||
CreatTime: number;
|
||||
Cookies: Map<string, string>;
|
||||
ClientKey: string;
|
||||
KeyIndex: string;
|
||||
PskeyData: Map<string, string>;
|
||||
PskeyTime: Map<string, number>;
|
||||
};
|
||||
export declare const WebGroupData: {
|
||||
GroupData: Map<string, WebApiGroupMember[]>;
|
||||
GroupTime: Map<string, number>;
|
||||
};
|
||||
export declare const selfInfo: SelfInfo;
|
||||
export declare const groups: Map<string, Group>;
|
||||
export declare function deleteGroup(groupQQ: string): void;
|
||||
export declare const groupMembers: Map<string, Map<string, GroupMember>>;
|
||||
export declare const friends: Map<string, Friend>;
|
||||
export declare const friendRequests: Record<string, FriendRequest>;
|
||||
export declare const groupNotifies: Record<string, GroupNotify>;
|
||||
export declare const napCatError: {
|
||||
ffmpegError: string;
|
||||
httpServerError: string;
|
||||
wsServerError: string;
|
||||
otherError: string;
|
||||
};
|
||||
export declare function getFriend(uinOrUid: string): Promise<Friend | undefined>;
|
||||
export declare function getGroup(qq: string | number): Promise<Group | undefined>;
|
||||
export declare function getGroupMember(groupQQ: string | number, memberUinOrUid: string | number): Promise<GroupMember | null | undefined>;
|
||||
export declare const uid2UinMap: Record<string, string>;
|
||||
export declare function getUidByUin(uin: string): string | undefined;
|
||||
export declare const tempGroupCodeMap: Record<string, string>;
|
||||
export declare const rawFriends: Array<BuddyCategoryType>;
|
||||
export declare const stat: {
|
||||
packet_received: number;
|
||||
packet_sent: number;
|
||||
message_received: number;
|
||||
message_sent: number;
|
||||
last_message_time: number;
|
||||
disconnect_times: number;
|
||||
lost_times: number;
|
||||
packet_lost: number;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
function _0x1e9c(){const _0x447d40=['set','6dTpiBU','toString','5086xmspbx','3518383QspPdD','2647393kSNvhj','Dmiix','uin','values','getGroups','795xSaWuO','oAVBh','3832jaSWpx','7627944RNryNB','delete','351mulPEA','find','6097446JtIhsz','NapCat未能正常启动,请检查日志查看错误','length','from','getGroupMembers','72494eRuxkp','JdDYt','get','50nBgkIg'];_0x1e9c=function(){return _0x447d40;};return _0x1e9c();}const _0x3e979e=_0x48f4;(function(_0x5a0e64,_0x266733){const _0x55ca6c=_0x48f4,_0x3a2fab=_0x5a0e64();while(!![]){try{const _0x262a03=parseInt(_0x55ca6c(0x1fc))/0x1+-parseInt(_0x55ca6c(0x203))/0x2*(-parseInt(_0x55ca6c(0x1f5))/0x3)+parseInt(_0x55ca6c(0x1f2))/0x4*(-parseInt(_0x55ca6c(0x1f0))/0x5)+-parseInt(_0x55ca6c(0x201))/0x6*(-parseInt(_0x55ca6c(0x205))/0x7)+parseInt(_0x55ca6c(0x1f3))/0x8+parseInt(_0x55ca6c(0x1f7))/0x9+parseInt(_0x55ca6c(0x1ff))/0xa*(-parseInt(_0x55ca6c(0x204))/0xb);if(_0x262a03===_0x266733)break;else _0x3a2fab['push'](_0x3a2fab['shift']());}catch(_0x211806){_0x3a2fab['push'](_0x3a2fab['shift']());}}}(_0x1e9c,0x993a8));import{isNumeric}from'@/common/utils/helper';function _0x48f4(_0x4c2439,_0x458292){const _0x1e9c8f=_0x1e9c();return _0x48f4=function(_0x48f4f9,_0x550b1d){_0x48f4f9=_0x48f4f9-0x1f0;let _0x5effea=_0x1e9c8f[_0x48f4f9];return _0x5effea;},_0x48f4(_0x4c2439,_0x458292);}import{NTQQGroupApi}from'@/core/apis';export const Credentials={'Skey':'','CreatTime':0x0,'Cookies':new Map(),'ClientKey':'','KeyIndex':'','PskeyData':new Map(),'PskeyTime':new Map()};export const WebGroupData={'GroupData':new Map(),'GroupTime':new Map()};export const selfInfo={'uid':'','uin':'','nick':'','online':!![]};export const groups=new Map();export function deleteGroup(_0x43443e){const _0x2581d1=_0x48f4;groups['delete'](_0x43443e),groupMembers[_0x2581d1(0x1f4)](_0x43443e);}export const groupMembers=new Map();export const friends=new Map();export const friendRequests={};export const groupNotifies={};export const napCatError={'ffmpegError':'','httpServerError':'','wsServerError':'','otherError':_0x3e979e(0x1f8)};export async function getFriend(_0x35624a){const _0x5ad968=_0x3e979e;_0x35624a=_0x35624a['toString']();if(isNumeric(_0x35624a)){const _0x28b0c4=Array[_0x5ad968(0x1fa)](friends['values']());return _0x28b0c4[_0x5ad968(0x1f6)](_0x77f617=>_0x77f617[_0x5ad968(0x207)]===_0x35624a);}else return friends['get'](_0x35624a);}export async function getGroup(_0x2928c8){const _0x431367=_0x3e979e;let _0x32197f=groups[_0x431367(0x1fe)](_0x2928c8[_0x431367(0x202)]());if(!_0x32197f)try{const _0x48aad6=await NTQQGroupApi[_0x431367(0x209)]();_0x48aad6[_0x431367(0x1f9)]&&_0x48aad6['forEach'](_0x1068b5=>{const _0x459d61=_0x431367;groups[_0x459d61(0x200)](_0x1068b5['groupCode'],_0x1068b5);});}catch(_0x288b9a){return undefined;}return _0x32197f=groups[_0x431367(0x1fe)](_0x2928c8[_0x431367(0x202)]()),_0x32197f;}export async function getGroupMember(_0x2984f9,_0x5acbf1){const _0x41f643=_0x3e979e,_0x2f7e06={'JdDYt':function(_0x5ed1b8,_0x276ae8){return _0x5ed1b8(_0x276ae8);},'Dmiix':function(_0x15a7c1){return _0x15a7c1();}};_0x2984f9=_0x2984f9[_0x41f643(0x202)](),_0x5acbf1=_0x5acbf1[_0x41f643(0x202)]();let _0x17269a=groupMembers['get'](_0x2984f9);if(!_0x17269a)try{_0x17269a=await NTQQGroupApi[_0x41f643(0x1fb)](_0x2984f9),groupMembers[_0x41f643(0x200)](_0x2984f9,_0x17269a);}catch(_0x28b61a){return null;}const _0x1dc81f=()=>{const _0x5291ec=_0x41f643;let _0x423f1a=undefined;return _0x2f7e06[_0x5291ec(0x1fd)](isNumeric,_0x5acbf1)?_0x423f1a=Array[_0x5291ec(0x1fa)](_0x17269a[_0x5291ec(0x208)]())['find'](_0x260cea=>_0x260cea['uin']===_0x5acbf1):_0x423f1a=_0x17269a[_0x5291ec(0x1fe)](_0x5acbf1),_0x423f1a;};let _0x228b6c=_0x2f7e06[_0x41f643(0x206)](_0x1dc81f);return!_0x228b6c&&(_0x17269a=await NTQQGroupApi[_0x41f643(0x1fb)](_0x2984f9),_0x228b6c=_0x1dc81f()),_0x228b6c;}export const uid2UinMap={};export function getUidByUin(_0x6a6856){const _0x281b58=_0x3e979e,_0x17392b={'oAVBh':function(_0x43f456,_0x451ad7){return _0x43f456===_0x451ad7;}};for(const _0x3df1c5 in uid2UinMap){if(_0x17392b[_0x281b58(0x1f1)](uid2UinMap[_0x3df1c5],_0x6a6856))return _0x3df1c5;}}export const tempGroupCodeMap={};export const rawFriends=[];export const stat={'packet_received':0x0,'packet_sent':0x0,'message_received':0x0,'message_sent':0x0,'last_message_time':0x0,'disconnect_times':0x0,'lost_times':0x0,'packet_lost':0x0};
|
||||
Vendored
+58
@@ -0,0 +1,58 @@
|
||||
import { ChatType } from './msg';
|
||||
export interface CacheScanResult {
|
||||
result: number;
|
||||
size: [
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
string
|
||||
];
|
||||
}
|
||||
export interface ChatCacheList {
|
||||
pageCount: number;
|
||||
infos: ChatCacheListItem[];
|
||||
}
|
||||
export interface ChatCacheListItem {
|
||||
chatType: ChatType;
|
||||
basicChatCacheInfo: ChatCacheListItemBasic;
|
||||
guildChatCacheInfo: unknown[];
|
||||
}
|
||||
export interface ChatCacheListItemBasic {
|
||||
chatSize: string;
|
||||
chatTime: string;
|
||||
uid: string;
|
||||
uin: string;
|
||||
remarkName: string;
|
||||
nickName: string;
|
||||
chatType?: ChatType;
|
||||
isChecked?: boolean;
|
||||
}
|
||||
export declare enum CacheFileType {
|
||||
IMAGE = 0,
|
||||
VIDEO = 1,
|
||||
AUDIO = 2,
|
||||
DOCUMENT = 3,
|
||||
OTHER = 4
|
||||
}
|
||||
export interface CacheFileList {
|
||||
infos: CacheFileListItem[];
|
||||
}
|
||||
export interface CacheFileListItem {
|
||||
fileSize: string;
|
||||
fileTime: string;
|
||||
fileKey: string;
|
||||
elementId: string;
|
||||
elementIdStr: string;
|
||||
fileType: CacheFileType;
|
||||
path: string;
|
||||
fileName: string;
|
||||
senderId: string;
|
||||
previewPath: string;
|
||||
senderName: string;
|
||||
isChecked?: boolean;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
function _0x2785(_0x53a375,_0x5ad036){var _0xea5dc3=_0xea5d();return _0x2785=function(_0x27858a,_0xc4f20f){_0x27858a=_0x27858a-0x1b3;var _0xb85139=_0xea5dc3[_0x27858a];return _0xb85139;},_0x2785(_0x53a375,_0x5ad036);}(function(_0xa9ba95,_0x2d8d2b){var _0x24af7d=_0x2785,_0x4b628c=_0xa9ba95();while(!![]){try{var _0x40c8f8=parseInt(_0x24af7d(0x1bd))/0x1*(-parseInt(_0x24af7d(0x1b5))/0x2)+-parseInt(_0x24af7d(0x1b8))/0x3+parseInt(_0x24af7d(0x1c5))/0x4+parseInt(_0x24af7d(0x1c0))/0x5+parseInt(_0x24af7d(0x1b4))/0x6*(parseInt(_0x24af7d(0x1c1))/0x7)+-parseInt(_0x24af7d(0x1ba))/0x8*(parseInt(_0x24af7d(0x1b9))/0x9)+-parseInt(_0x24af7d(0x1c6))/0xa;if(_0x40c8f8===_0x2d8d2b)break;else _0x4b628c['push'](_0x4b628c['shift']());}catch(_0x3970b){_0x4b628c['push'](_0x4b628c['shift']());}}}(_0xea5d,0x52f94));function _0xea5d(){var _0x1dc2c0=['2038940AyFeQR','ejEHv','223134givfsc','10pJuhtm','IMriL','AUDIO','138051FrTync','477dOtuPj','16144xcnwwD','0|3|1|4|2','lDvXO','37775uEIhvB','uYeNv','split','833065LRDNfU','98wgeBtc','KXJaw','DOCUMENT','IMAGE','793364lWHHle'];_0xea5d=function(){return _0x1dc2c0;};return _0xea5d();};export var CacheFileType;(function(_0x228ea3){var _0x1c26c0=_0x2785,_0xe76f57={'KXJaw':_0x1c26c0(0x1c4),'lDvXO':_0x1c26c0(0x1b7),'IMriL':'OTHER','ejEHv':'VIDEO','uYeNv':_0x1c26c0(0x1c3)},_0x32bb0c=_0x1c26c0(0x1bb)[_0x1c26c0(0x1bf)]('|'),_0x15d8b9=0x0;while(!![]){switch(_0x32bb0c[_0x15d8b9++]){case'0':_0x228ea3[_0x228ea3[_0xe76f57[_0x1c26c0(0x1c2)]]=0x0]=_0xe76f57[_0x1c26c0(0x1c2)];continue;case'1':_0x228ea3[_0x228ea3[_0xe76f57[_0x1c26c0(0x1bc)]]=0x2]=_0xe76f57['lDvXO'];continue;case'2':_0x228ea3[_0x228ea3[_0xe76f57[_0x1c26c0(0x1b6)]]=0x4]=_0xe76f57[_0x1c26c0(0x1b6)];continue;case'3':_0x228ea3[_0x228ea3[_0xe76f57[_0x1c26c0(0x1b3)]]=0x1]=_0xe76f57['ejEHv'];continue;case'4':_0x228ea3[_0x228ea3[_0xe76f57[_0x1c26c0(0x1be)]]=0x3]=_0xe76f57[_0x1c26c0(0x1be)];continue;}break;}}(CacheFileType||(CacheFileType={})));
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
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): 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>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
const _0x173afa=_0x7d2c;(function(_0xbbda81,_0x478ca8){const _0x3d657f=_0x7d2c,_0x28f3c8=_0xbbda81();while(!![]){try{const _0x30995b=parseInt(_0x3d657f(0x95))/0x1*(-parseInt(_0x3d657f(0x9c))/0x2)+-parseInt(_0x3d657f(0x87))/0x3+-parseInt(_0x3d657f(0xaf))/0x4*(-parseInt(_0x3d657f(0x9f))/0x5)+parseInt(_0x3d657f(0x96))/0x6+-parseInt(_0x3d657f(0xd5))/0x7*(parseInt(_0x3d657f(0x86))/0x8)+-parseInt(_0x3d657f(0xcf))/0x9+-parseInt(_0x3d657f(0xd2))/0xa*(-parseInt(_0x3d657f(0x98))/0xb);if(_0x30995b===_0x478ca8)break;else _0x28f3c8['push'](_0x28f3c8['shift']());}catch(_0x37624a){_0x28f3c8['push'](_0x28f3c8['shift']());}}}(_0x3050,0xe54d7));import{AtType,ElementType,FaceIndex,FaceType,PicType}from'./index';import{promises as _0x1676d5}from'node:fs';import _0x2e093e from'fluent-ffmpeg';import{NTQQFileApi}from'@/core/apis/file';function _0x3050(){const _0x125af2=['FILE','writeFile','语音转换失败,\x20请检查语音文件是否正常','NHUgK','maOmy','RPS','sysface','end','text','toString','CbONM','zxIHf','PHpFw','stringify','134072EbmhWG','1234686gopkcv','ark','[骰子]','QDes','获取视频封面失败,使用默认封面','mface','string','error','rqDXm','AIEFz','replace','cePLt','gPCPE','JFxgc','13pxDqUA','5781918AowJlr','emoji','99NyJEnJ','https://tianquan.gtimg.cn/shoal/qqAIAgent/3e9d70c9-d98c-45b8-80b4-79d82971b514.png','reply','ROfpO','9974HTsVyQ','MARKDOWN','FACE','2500yoDagq','get','[商城表情]','dice','APGcV','iXbQe','AniStickerId','jpg','qPAfZ','https://tianquan.gtimg.cn/qqAIAgent/item/7/square.png','video','sep','PTT','lGgyh','VYyVA','face','11328BtPMPH','dirname','mp4','hnMsj','time','screenshots','Ori','copyFile','width','markdown','unlink','AniStickerType','catch','VIDEO','size','find','miniapp','rps','uploadFile','notAt','Bot\x20Test','getImageSize','file','pic','then','TEXT','文件异常,大小为0','join','fRGNc','REPLY','QJHaj','WsCPW','9623799KdVgzJ','PIC','height','2109430IvdfNH','ARK','SFFuH','749DtDcGW'];_0x3050=function(){return _0x125af2;};return _0x3050();}import{calculateFileMD5,isGIF}from'@/common/utils/file';import{logDebug,logError}from'@/common/utils/log';import{defaultVideoThumb,getVideoInfo}from'@/common/utils/video';import{encodeSilk}from'@/common/utils/audio';import _0x4b53b1 from'./face_config.json';import*as _0x43d789 from'node:path';import{SignMiniApp}from'../apis';export const mFaceCache=new Map();function _0x7d2c(_0x3c0545,_0x1dca83){const _0x30509d=_0x3050();return _0x7d2c=function(_0x7d2cb9,_0x1742f2){_0x7d2cb9=_0x7d2cb9-0x79;let _0x3c38db=_0x30509d[_0x7d2cb9];return _0x3c38db;},_0x7d2c(_0x3c0545,_0x1dca83);}export class SendMsgElementConstructor{static[_0x173afa(0x80)](_0x4968cc){const _0xd22d5e=_0x173afa;return{'elementType':ElementType['TEXT'],'elementId':'','textElement':{'content':_0x4968cc,'atType':AtType[_0xd22d5e(0xc2)],'atUid':'','atTinyId':'','atNtUid':''}};}static['at'](_0x4ee219,_0x423d8e,_0x5eed39,_0x3ce04c){const _0x2d8d4a=_0x173afa;return{'elementType':ElementType[_0x2d8d4a(0xc8)],'elementId':'','textElement':{'content':'@'+_0x3ce04c,'atType':_0x5eed39,'atUid':_0x4ee219,'atTinyId':'','atNtUid':_0x423d8e}};}static[_0x173afa(0x9a)](_0x53f49a,_0x8a8a76,_0x267667,_0x1228b6){const _0x46e227=_0x173afa;return{'elementType':ElementType[_0x46e227(0xcc)],'elementId':'','replyElement':{'replayMsgSeq':_0x53f49a,'replayMsgId':_0x8a8a76,'senderUin':_0x267667,'senderUinStr':_0x1228b6}};}static async[_0x173afa(0xc6)](_0x552dc6,_0x22ed64='',_0x5a31ec=0x0){const _0xc4c0fa=_0x173afa,_0x31f159={'rQDTp':function(_0x471885,_0xebfcc0){return _0x471885===_0xebfcc0;},'eAnAn':_0xc4c0fa(0xc9),'ZzJiF':function(_0x4e190c,_0x2a6730){return _0x4e190c(_0x2a6730);}},{md5:_0x3cb239,fileName:_0x511dcc,path:_0x25a0bc,fileSize:_0x6284aa}=await NTQQFileApi[_0xc4c0fa(0xc1)](_0x552dc6,ElementType[_0xc4c0fa(0xd0)],_0x5a31ec);if(_0x31f159['rQDTp'](_0x6284aa,0x0))throw _0x31f159['eAnAn'];const _0x2de761=await NTQQFileApi[_0xc4c0fa(0xc4)](_0x552dc6),_0x2c78d5={'md5HexStr':_0x3cb239,'fileSize':_0x6284aa['toString'](),'picWidth':_0x2de761?.[_0xc4c0fa(0xb7)],'picHeight':_0x2de761?.[_0xc4c0fa(0xd1)],'fileName':_0x511dcc,'sourcePath':_0x25a0bc,'original':!![],'picType':_0x31f159['ZzJiF'](isGIF,_0x552dc6)?PicType['gif']:PicType[_0xc4c0fa(0xa6)],'picSubType':_0x5a31ec,'fileUuid':'','fileSubId':'','thumbFileSize':0x0,'summary':_0x22ed64};return{'elementType':ElementType[_0xc4c0fa(0xd0)],'elementId':'','picElement':_0x2c78d5};}static async[_0x173afa(0xc5)](_0x113d4f,_0x1f2cf2=''){const _0x38b83f=_0x173afa,_0x2b1b20={'hFYht':function(_0xbb1f0b,_0x46a4b6){return _0xbb1f0b||_0x46a4b6;}},{md5:_0x536402,fileName:_0x350242,path:_0x11068c,fileSize:_0xc62c4e}=await NTQQFileApi[_0x38b83f(0xc1)](_0x113d4f,ElementType[_0x38b83f(0xd6)]);if(_0xc62c4e===0x0)throw'文件异常,大小为0';const _0x373623={'elementType':ElementType['FILE'],'elementId':'','fileElement':{'fileName':_0x2b1b20['hFYht'](_0x1f2cf2,_0x350242),'filePath':_0x11068c,'fileSize':_0xc62c4e[_0x38b83f(0x81)]()}};return _0x373623;}static async[_0x173aLine truncated
|
||||
File diff suppressed because it is too large.
Load diff
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
(function(_0x47ea7,_0x615584){var _0x2fcf1b=_0x1fe6,_0xbcbb46=_0x47ea7();while(!![]){try{var _0x4770ce=parseInt(_0x2fcf1b(0x90))/0x1+-parseInt(_0x2fcf1b(0x8c))/0x2+parseInt(_0x2fcf1b(0x89))/0x3+parseInt(_0x2fcf1b(0x8e))/0x4+-parseInt(_0x2fcf1b(0x92))/0x5*(-parseInt(_0x2fcf1b(0x88))/0x6)+parseInt(_0x2fcf1b(0x8a))/0x7+-parseInt(_0x2fcf1b(0x91))/0x8*(parseInt(_0x2fcf1b(0x94))/0x9);if(_0x4770ce===_0x615584)break;else _0xbcbb46['push'](_0xbcbb46['shift']());}catch(_0x24ced3){_0xbcbb46['push'](_0xbcbb46['shift']());}}}(_0x3027,0xc65aa));function _0x1fe6(_0x390948,_0x38eb27){var _0x3027b6=_0x3027();return _0x1fe6=function(_0x1fe64a,_0x4d90e5){_0x1fe64a=_0x1fe64a-0x87;var _0x264c42=_0x3027b6[_0x1fe64a];return _0x264c42;},_0x1fe6(_0x390948,_0x38eb27);}export var GroupMemberRole;function _0x3027(){var _0x2d7c64=['owner','2027304ZeJBoU','4058124IocVxH','5436781zgpwjn','WMXwQ','3241482gNeCwP','ZaTfq','1085176oTPRLC','cTFga','444975nvOPlK','2000920aYmzCI','5TDCmgT','normal','27ZlYhYs','admin'];_0x3027=function(){return _0x2d7c64;};return _0x3027();}(function(_0x1a1243){var _0x234594=_0x1fe6,_0x1d1ea8={'WMXwQ':_0x234594(0x93),'cTFga':_0x234594(0x95),'ZaTfq':_0x234594(0x87)};_0x1a1243[_0x1a1243[_0x1d1ea8[_0x234594(0x8b)]]=0x2]=_0x234594(0x93),_0x1a1243[_0x1a1243[_0x1d1ea8[_0x234594(0x8f)]]=0x3]=_0x1d1ea8[_0x234594(0x8f)],_0x1a1243[_0x1a1243[_0x1d1ea8[_0x234594(0x8d)]]=0x4]='owner';}(GroupMemberRole||(GroupMemberRole={})));
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
export * from './user';
|
||||
export * from './group';
|
||||
export * from './msg';
|
||||
export * from './notify';
|
||||
export * from './cache';
|
||||
export * from './constructor';
|
||||
@@ -0,0 +1 @@
|
||||
(function(_0x4f55b6,_0x31914f){var _0x571f44=_0x48d8,_0x5a1005=_0x4f55b6();while(!![]){try{var _0x3039c3=-parseInt(_0x571f44(0x1a6))/0x1*(parseInt(_0x571f44(0x1a4))/0x2)+parseInt(_0x571f44(0x1a2))/0x3*(parseInt(_0x571f44(0x1a1))/0x4)+-parseInt(_0x571f44(0x19f))/0x5+parseInt(_0x571f44(0x1a5))/0x6+parseInt(_0x571f44(0x1a3))/0x7+-parseInt(_0x571f44(0x1a7))/0x8+parseInt(_0x571f44(0x1a0))/0x9;if(_0x3039c3===_0x31914f)break;else _0x5a1005['push'](_0x5a1005['shift']());}catch(_0x27a3d7){_0x5a1005['push'](_0x5a1005['shift']());}}}(_0x4987,0x586d2));export*from'./user';function _0x4987(){var _0x48d492=['3409712VpjpKM','1411480NAQryD','8477919Qheyob','4bzMyxF','705531AqoFOe','284151MagfXx','6CfQCOY','1511460arJbLt','132989nZqIFI'];_0x4987=function(){return _0x48d492;};return _0x4987();}export*from'./group';export*from'./msg';function _0x48d8(_0x5ca237,_0x548dbc){var _0x498788=_0x4987();return _0x48d8=function(_0x48d8cd,_0x15c216){_0x48d8cd=_0x48d8cd-0x19f;var _0x106d11=_0x498788[_0x48d8cd];return _0x106d11;},_0x48d8(_0x5ca237,_0x548dbc);}export*from'./notify';export*from'./cache';export*from'./constructor';
|
||||
Vendored
+399
@@ -0,0 +1,399 @@
|
||||
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;
|
||||
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 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 {
|
||||
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 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;
|
||||
}[];
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
var _0x30156e=_0xa76c;(function(_0x27dea2,_0x308e0b){var _0x215a41=_0xa76c,_0x406047=_0x27dea2();while(!![]){try{var _0x2b378c=-parseInt(_0x215a41(0x18b))/0x1+parseInt(_0x215a41(0x176))/0x2*(-parseInt(_0x215a41(0x17a))/0x3)+parseInt(_0x215a41(0x172))/0x4*(parseInt(_0x215a41(0x171))/0x5)+parseInt(_0x215a41(0x182))/0x6+parseInt(_0x215a41(0x18e))/0x7+parseInt(_0x215a41(0x156))/0x8+parseInt(_0x215a41(0x173))/0x9*(-parseInt(_0x215a41(0x193))/0xa);if(_0x2b378c===_0x308e0b)break;else _0x406047['push'](_0x406047['shift']());}catch(_0x14605d){_0x406047['push'](_0x406047['shift']());}}}(_0x52f0,0x4f6d6));function _0x52f0(){var _0x2e1ef4=['3825896DMzQgO','mmFpl','jpg','PTT','ban','JpsFe','FvLNL','DfoRb','LPoMG','tzGwN','vnbeo','CrzFX','LoJJP','FILE','TEXT','normal2','PIC','MFACE','TsSNo','notAt','RPS','FACE','atAll','zHpNH','Jrdif','DePIy','https://multimedia.nt.qq.com.cn','54125ThhNbD','200eOEyap','11055537eLrDgu','OvTHG','lbgRH','8WpCtpV','INVITE_NEW_MEMBER','BTosA','wCvAP','330453tixpXW','face','VIDEO','bavLZ','SBKTa','VUkpd','gif','MEMBER_NEW_TITLE','3644688poedXb','vzPEA','SZZMn','ikBjO','friend','REPLY','kicked','VYDxr','chatDevice','126718vdrnQY','temp','KINez','3458798lThxHB','split','ozaRL','memberIncrease','atUser','10PCSYHB','wDuvo','normal','VLSfJ','ARK','dice','MARKDOWN'];_0x52f0=function(){return _0x2e1ef4;};return _0x52f0();}export var ElementType;(function(_0x3ffa77){var _0x164a0a=_0xa76c,_0x5e6ef9={'ZlIhq':'6|9|8|5|0|4|3|7|2|1','SBKTa':_0x164a0a(0x17c),'zHpNH':_0x164a0a(0x199),'DfoRb':_0x164a0a(0x187),'ikBjO':_0x164a0a(0x16b),'bavLZ':_0x164a0a(0x159),'Jrdif':_0x164a0a(0x164),'JpsFe':_0x164a0a(0x197),'wDuvo':_0x164a0a(0x163),'VLSfJ':_0x164a0a(0x166)},_0x2a77c1=_0x5e6ef9['ZlIhq'][_0x164a0a(0x18f)]('|'),_0xce9f25=0x0;while(!![]){switch(_0x2a77c1[_0xce9f25++]){case'0':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x17e)]]=0x5]=_0x5e6ef9[_0x164a0a(0x17e)];continue;case'1':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x16d)]]=0xe]=_0x164a0a(0x199);continue;case'2':_0x3ffa77[_0x3ffa77[_0x164a0a(0x167)]=0xb]=_0x164a0a(0x167);continue;case'3':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x15d)]]=0x7]=_0x5e6ef9[_0x164a0a(0x15d)];continue;case'4':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x185)]]=0x6]=_0x164a0a(0x16b);continue;case'5':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x17d)]]=0x4]=_0x5e6ef9[_0x164a0a(0x17d)];continue;case'6':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x16e)]]=0x1]=_0x164a0a(0x164);continue;case'7':_0x3ffa77[_0x3ffa77[_0x5e6ef9['JpsFe']]=0xa]=_0x5e6ef9[_0x164a0a(0x15b)];continue;case'8':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x194)]]=0x3]=_0x5e6ef9[_0x164a0a(0x194)];continue;case'9':_0x3ffa77[_0x3ffa77[_0x5e6ef9[_0x164a0a(0x196)]]=0x2]=_0x5e6ef9['VLSfJ'];continue;}break;}}(ElementType||(ElementType={})));export var PicType;(function(_0x2bd409){var _0x555066=_0xa76c,_0x53e266={'lbgRH':_0x555066(0x180),'TsSNo':_0x555066(0x158)};_0x2bd409[_0x2bd409['gif']=0x7d0]=_0x53e266[_0x555066(0x175)],_0x2bd409[_0x2bd409[_0x53e266[_0x555066(0x168)]]=0x3e8]=_0x53e266[_0x555066(0x168)];}(PicType||(PicType={})));export var PicSubType;function _0xa76c(_0x4468c0,_0x346cb6){var _0x52f09a=_0x52f0();return _0xa76c=function(_0xa76cb1,_0x52a1c5){_0xa76cb1=_0xa76cb1-0x156;var _0x56ae6b=_0x52f09a[_0xa76cb1];return _0x56ae6b;},_0xa76c(_0x4468c0,_0x346cb6);}(function(_0x6d2056){var _0x2cdb98=_0xa76c,_0x5aa3ff={'VUkpd':_0x2cdb98(0x195),'BTosA':_0x2cdb98(0x17b)};_0x6d2056[_0x6d2056['normal']=0x0]=_0x5aa3ff[_0x2cdb98(0x17f)],_0x6d2056[_0x6d2056[_0x5aa3ff[_0x2cdb98(0x178)]]=0x1]=_0x5aa3ff['BTosA'];}(PicSubType||(PicSubType={})));export var AtType;(function(_0x567d1a){var _0x11d12c=_0xa76c,_0x575366={'wCvAP':_0x11d12c(0x169),'DePIy':_0x11d12c(0x16c),'FvLNL':_0x11d12c(0x192)};_0x567d1a[_0x567d1a[_0x11d12c(0x169)]=0x0]=_0x575366[_0x11d12c(0x179)],_0x567d1a[_0x567d1a[_0x575366[_0x11d12c(0x16f)]]=0x1]=_0x575366[_0x11d12c(0x16f)],_0x567d1a[_0x567d1a[_0x575366[_0x11d12c(0x15c)]]=0x2]=_0x575366['FvLNL'];}(AtType||(AtType={})));export var ChatType;(function(_0x1712f0){var _0x5d8b69=_0xa76c,_0x58d2e6={'SZZMn':_0x5d8b69(0x186),'VYDxr':'group','LPoMG':_0x5d8b69(0x18a),'LoJJP':_0x5d8b69(0x18c)};_0x1712f0[_0x1712f0[_0x58d2e6[_0x5d8b69(0x184)]]=0x1]=_0x58d2e6[_0x5d8b69(0x184)],_0x1712f0[_0x1712f0[_0x58d2e6[_0x5d8b69(0x189)]]=0x2]=_0x58d2e6[_0x5d8b69(0x189)],_0x1712f0[_0x1712f0[_0x58d2e6['LPoMG']]=0x8]=_0x58d2e6[_0x5d8b69(0x15e)],_0x1712f0[_0x1712f0[_0x58d2e6[_0x5d8b69(0x162)]]=0x64]=_0x58d2e6[_0x5d8b69(0x162)];}(ChatType||(ChatType={})));export const IMAGE_HTTP_HOST='https://gchat.qpic.cn';export const IMAGE_HTTP_HOST_NT=_0x30156e(0x170);export var GrayTipElementSubType;(function(_0x577195){var _0x5ee983=_0x30156e,_0x1b01ec={'tzGwN':_0x5ee983(0x181)};_0x577195[_0x577195[_0x5ee983(0x177)]=0xc]=_0x5ee983(0x177),_0x577195[_0x577195[_0x1b01ec[_0x5ee983(0x15f)]]=0x11]=_0x1b01ec[_0x5ee983(0x15f)];}(GrayTipElementSubType||(GrayTipElementSubType={})));export var FaceType;(function(_0x4c6b07){var _0x5a4ec4=_0x30156e,_0x34e22f={'OIZzl':_0x5a4ec4(0x195),'mmFpl':_0x5Line truncated
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
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 interface FriendRequest {
|
||||
friendUid: string;
|
||||
reqTime: string;
|
||||
extWords: string;
|
||||
isUnread: boolean;
|
||||
friendNick: string;
|
||||
sourceId: number;
|
||||
groupCode: string;
|
||||
}
|
||||
export interface FriendRequestNotify {
|
||||
unreadNums: number;
|
||||
buddyReqs: FriendRequest[];
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
(function(_0x54e5fe,_0x382a2e){var _0x15dd85=_0x4780,_0x1a1fa7=_0x54e5fe();while(!![]){try{var _0x5b692c=parseInt(_0x15dd85(0xeb))/0x1*(parseInt(_0x15dd85(0xda))/0x2)+parseInt(_0x15dd85(0xf0))/0x3*(-parseInt(_0x15dd85(0xfa))/0x4)+parseInt(_0x15dd85(0x100))/0x5*(-parseInt(_0x15dd85(0xe0))/0x6)+parseInt(_0x15dd85(0xdf))/0x7+-parseInt(_0x15dd85(0x101))/0x8*(-parseInt(_0x15dd85(0xf4))/0x9)+-parseInt(_0x15dd85(0xe2))/0xa*(parseInt(_0x15dd85(0xe6))/0xb)+parseInt(_0x15dd85(0xe1))/0xc*(-parseInt(_0x15dd85(0xdb))/0xd);if(_0x5b692c===_0x382a2e)break;else _0x1a1fa7['push'](_0x1a1fa7['shift']());}catch(_0x1be192){_0x1a1fa7['push'](_0x1a1fa7['shift']());}}}(_0x4c68,0x89101));function _0x4c68(){var _0x1f16dd=['8CwMsYi','6XgntSd','5339555JMvtjg','KICK_MEMBER','approve','WAIT_HANDLE','4996033sulzTn','9954oiHPun','12BNbOPS','992570kftWLX','DYfGS','split','reject','33GJIvGK','RmcZr','esvOO','sZJhG','FSaRv','243031gYvpqO','INVITE_ME','ADMIN_SET','MEMBER_EXIT','ADMIN_UNSET_OTHER','429YQvzUm','APPROVE','ADMIN_UNSET','FnoAC','7818489mjxbqY','mkpQW','BPOec','wyMuD','hMsqL','INVITED_JOIN','21108btTqhQ','SRQAA','IGNORE','JOIN_REQUEST','7|5|4|2|6|1|0|3','zTtYS','865JDsfsH'];_0x4c68=function(){return _0x1f16dd;};return _0x4c68();}export var GroupNotifyTypes;(function(_0x5d9214){var _0x436ce5=_0x4780,_0x44fca0={'ESxZR':_0x436ce5(0xfe),'SRQAA':_0x436ce5(0xf2),'FnoAC':_0x436ce5(0xee),'esvOO':_0x436ce5(0xed),'FSaRv':_0x436ce5(0xef),'UfZxw':'JOIN_REQUEST','hMsqL':_0x436ce5(0xf9),'sZJhG':_0x436ce5(0xdc),'wyMuD':_0x436ce5(0xec)},_0x3bc9a0=_0x44fca0['ESxZR'][_0x436ce5(0xe4)]('|'),_0x59262a=0x0;while(!![]){switch(_0x3bc9a0[_0x59262a++]){case'0':_0x5d9214[_0x5d9214[_0x44fca0[_0x436ce5(0xfb)]]=0xc]=_0x44fca0[_0x436ce5(0xfb)];continue;case'1':_0x5d9214[_0x5d9214[_0x44fca0[_0x436ce5(0xf3)]]=0xb]=_0x44fca0[_0x436ce5(0xf3)];continue;case'2':_0x5d9214[_0x5d9214[_0x436ce5(0xed)]=0x8]=_0x44fca0[_0x436ce5(0xe8)];continue;case'3':_0x5d9214[_0x5d9214['ADMIN_UNSET_OTHER']=0xd]=_0x44fca0[_0x436ce5(0xea)];continue;case'4':_0x5d9214[_0x5d9214[_0x436ce5(0xfd)]=0x7]=_0x44fca0['UfZxw'];continue;case'5':_0x5d9214[_0x5d9214[_0x44fca0[_0x436ce5(0xf8)]]=0x4]='INVITED_JOIN';continue;case'6':_0x5d9214[_0x5d9214[_0x44fca0[_0x436ce5(0xe9)]]=0x9]=_0x44fca0[_0x436ce5(0xe9)];continue;case'7':_0x5d9214[_0x5d9214[_0x44fca0[_0x436ce5(0xf7)]]=0x1]=_0x44fca0['wyMuD'];continue;}break;}}(GroupNotifyTypes||(GroupNotifyTypes={})));function _0x4780(_0x1a2d49,_0x24cd8b){var _0x4c684a=_0x4c68();return _0x4780=function(_0x478063,_0x3dd5a2){_0x478063=_0x478063-0xda;var _0x42312e=_0x4c684a[_0x478063];return _0x42312e;},_0x4780(_0x1a2d49,_0x24cd8b);}export var GroupNotifyStatus;(function(_0xb9d825){var _0x5787bc=_0x4780,_0x2b38eb={'RmcZr':_0x5787bc(0xfc),'mkpQW':_0x5787bc(0xde),'DYfGS':_0x5787bc(0xf1),'NPmPa':'REJECT'};_0xb9d825[_0xb9d825[_0x5787bc(0xfc)]=0x0]=_0x2b38eb[_0x5787bc(0xe7)],_0xb9d825[_0xb9d825[_0x2b38eb[_0x5787bc(0xf5)]]=0x1]=_0x2b38eb[_0x5787bc(0xf5)],_0xb9d825[_0xb9d825[_0x2b38eb[_0x5787bc(0xe3)]]=0x2]=_0x5787bc(0xf1),_0xb9d825[_0xb9d825[_0x2b38eb['NPmPa']]=0x3]=_0x2b38eb['NPmPa'];}(GroupNotifyStatus||(GroupNotifyStatus={})));export var GroupRequestOperateTypes;(function(_0x599d25){var _0x2f5b82=_0x4780,_0x17977a={'zTtYS':_0x2f5b82(0xdd),'BPOec':_0x2f5b82(0xe5)};_0x599d25[_0x599d25[_0x2f5b82(0xdd)]=0x1]=_0x17977a[_0x2f5b82(0xff)],_0x599d25[_0x599d25[_0x17977a[_0x2f5b82(0xf6)]]=0x2]=_0x2f5b82(0xe5);}(GroupRequestOperateTypes||(GroupRequestOperateTypes={})));
|
||||
Vendored
+89
@@ -0,0 +1,89 @@
|
||||
export declare enum Sex {
|
||||
male = 1,
|
||||
female = 2,
|
||||
unknown = 255
|
||||
}
|
||||
export interface BuddyCategoryType {
|
||||
categoryId: number;
|
||||
categroyName: string;
|
||||
categroyMbCount: number;
|
||||
buddyList: User[];
|
||||
}
|
||||
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 {
|
||||
}
|
||||
Loaded 100 of 329 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user