mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
332 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a272feda6a | ||
![]() |
bc936a0ca7 | ||
![]() |
28030c2d13 | ||
![]() |
7fe9176286 | ||
![]() |
1105f9b8d6 | ||
![]() |
e4653defa8 | ||
![]() |
1c62a1e839 | ||
![]() |
3a3bbfe201 | ||
![]() |
1c38833998 | ||
![]() |
38894177ee | ||
![]() |
dce8416942 | ||
![]() |
14219e9b42 | ||
![]() |
7b459e7502 | ||
![]() |
31824c0504 | ||
![]() |
e203abae85 | ||
![]() |
faf83b680b | ||
![]() |
67dcbcb842 | ||
![]() |
6533a25404 | ||
![]() |
4dc760b0e9 | ||
![]() |
25933b9043 | ||
![]() |
a53aaa456e | ||
![]() |
e8a7ea07a5 | ||
![]() |
8817dc6b10 | ||
![]() |
491ec04b46 | ||
![]() |
8a5d4a683b | ||
![]() |
dfc7c7357a | ||
![]() |
690a2f7d34 | ||
![]() |
58f22b24e4 | ||
![]() |
3cce9f528b | ||
![]() |
20fd5ac8cb | ||
![]() |
9e05e086eb | ||
![]() |
056e0adddf | ||
![]() |
b36388200d | ||
![]() |
9793e5741a | ||
![]() |
143380c012 | ||
![]() |
4b92254945 | ||
![]() |
f9c1d8b4a6 | ||
![]() |
c0c469339b | ||
![]() |
0ca6343ed7 | ||
![]() |
3db74c3427 | ||
![]() |
48d5cb53bd | ||
![]() |
fd7d2dbf53 | ||
![]() |
6609697752 | ||
![]() |
dcd6e1973e | ||
![]() |
3614a6e932 | ||
![]() |
931a0210e5 | ||
![]() |
f9e7de4b42 | ||
![]() |
8e0b79594e | ||
![]() |
17122c4360 | ||
![]() |
154f7b6a30 | ||
![]() |
52e5543d0b | ||
![]() |
3c304bd2ae | ||
![]() |
26609bb8fd | ||
![]() |
de3fa9aaa4 | ||
![]() |
788665f84c | ||
![]() |
3943782971 | ||
![]() |
8f899c40f2 | ||
![]() |
a1f582399e | ||
![]() |
440b63f662 | ||
![]() |
7d2cc3b56b | ||
![]() |
5fe3422469 | ||
![]() |
6c02cedb1e | ||
![]() |
3cc2f1dcad | ||
![]() |
773cdc5877 | ||
![]() |
361a7329d7 | ||
![]() |
29910f1236 | ||
![]() |
4a164016f5 | ||
![]() |
cebd3e62a4 | ||
![]() |
2562a38fa1 | ||
![]() |
d46c922bbf | ||
![]() |
66b59982f7 | ||
![]() |
ad397ccf7f | ||
![]() |
bdef80ede7 | ||
![]() |
385dcbc75a | ||
![]() |
74cf501c8f | ||
![]() |
0c200d6748 | ||
![]() |
e65a36c517 | ||
![]() |
126b54ad40 | ||
![]() |
78637751af | ||
![]() |
f96526ee3a | ||
![]() |
b3c7a91f3d | ||
![]() |
b8daeef0c4 | ||
![]() |
2b662944cf | ||
![]() |
3d516df01e | ||
![]() |
26b4a9b15b | ||
![]() |
0f8af273ae | ||
![]() |
fa29a31da9 | ||
![]() |
9e0d2606d8 | ||
![]() |
338dedd6e0 | ||
![]() |
1f893b1393 | ||
![]() |
b783d6f928 | ||
![]() |
8ca0d40f05 | ||
![]() |
2f40a80434 | ||
![]() |
812d8eb5bb | ||
![]() |
bf5f548349 | ||
![]() |
ebf90e72b9 | ||
![]() |
31d7d42edf | ||
![]() |
833875b42f | ||
![]() |
b901c10f3c | ||
![]() |
8ab678bd97 | ||
![]() |
55d5072f46 | ||
![]() |
a379ffd0f2 | ||
![]() |
4501d73134 | ||
![]() |
5f15774ec7 | ||
![]() |
c9e057599e | ||
![]() |
66851f5625 | ||
![]() |
b33c235b4d | ||
![]() |
d6693b6114 | ||
![]() |
36b4d26c78 | ||
![]() |
617592d90a | ||
![]() |
15a77b8070 | ||
![]() |
606eccd22b | ||
![]() |
5613450313 | ||
![]() |
c59b5564af | ||
![]() |
330b086b8b | ||
![]() |
9837ef4f36 | ||
![]() |
add46b3251 | ||
![]() |
e169199107 | ||
![]() |
92fe654850 | ||
![]() |
b257486404 | ||
![]() |
bdf2e33f40 | ||
![]() |
224d361923 | ||
![]() |
3452fa56df | ||
![]() |
cd256235da | ||
![]() |
361a164f2a | ||
![]() |
0e60d4b198 | ||
![]() |
67b47e39b4 | ||
![]() |
8f54310f63 | ||
![]() |
c7a7494d7e | ||
![]() |
af88b3166d | ||
![]() |
b7837b2a14 | ||
![]() |
950ddc749e | ||
![]() |
df081ef0cf | ||
![]() |
7b24f90d9f | ||
![]() |
f2e4579fd8 | ||
![]() |
97cb351827 | ||
![]() |
c1ec53fdbb | ||
![]() |
98214aa429 | ||
![]() |
ce7deac2dd | ||
![]() |
612092b867 | ||
![]() |
92579d5949 | ||
![]() |
9ab07060ae | ||
![]() |
0d45125d79 | ||
![]() |
9ced152778 | ||
![]() |
3685ab2e3e | ||
![]() |
be605f11f2 | ||
![]() |
8cca8df976 | ||
![]() |
990a31e961 | ||
![]() |
5db201c342 | ||
![]() |
a625e30dd4 | ||
![]() |
b236cdd060 | ||
![]() |
2db9899184 | ||
![]() |
fe5d6db986 | ||
![]() |
7c7bf8fecf | ||
![]() |
76e3a46378 | ||
![]() |
16f3897fec | ||
![]() |
045e120854 | ||
![]() |
2b7fcce9b2 | ||
![]() |
9685931694 | ||
![]() |
1dc844435a | ||
![]() |
18892379de | ||
![]() |
620d61c8dc | ||
![]() |
9f91398875 | ||
![]() |
a29b1154a9 | ||
![]() |
34d19a471a | ||
![]() |
2ef6477d7c | ||
![]() |
26e6800836 | ||
![]() |
9dbbcf3872 | ||
![]() |
6b3343e1e4 | ||
![]() |
ef48f754a5 | ||
![]() |
3be1ede847 | ||
![]() |
7bff1b61e8 | ||
![]() |
6affd0eb68 | ||
![]() |
0a112d15e0 | ||
![]() |
4e03f582bb | ||
![]() |
8f186c1c5e | ||
![]() |
cd1bae9a1f | ||
![]() |
60796c26ca | ||
![]() |
28927f950d | ||
![]() |
95f16ebc8c | ||
![]() |
25bca8385d | ||
![]() |
965c7f23b4 | ||
![]() |
33082af9cc | ||
![]() |
1f7f3565b0 | ||
![]() |
f784363696 | ||
![]() |
37bd51e138 | ||
![]() |
c367728c43 | ||
![]() |
61f0f5d884 | ||
![]() |
5f2ebeead7 | ||
![]() |
7646037fc7 | ||
![]() |
eac6d285ff | ||
![]() |
b921d5e734 | ||
![]() |
831d808e63 | ||
![]() |
451b88d7e3 | ||
![]() |
f916682a71 | ||
![]() |
2d76bcf0cf | ||
![]() |
8db294efe6 | ||
![]() |
5cc5149aed | ||
![]() |
7ecb01dc9f | ||
![]() |
8bf1a545d9 | ||
![]() |
efb2be2f94 | ||
![]() |
bd2edda494 | ||
![]() |
991172eae4 | ||
![]() |
fc7631f9aa | ||
![]() |
a21efb7d2f | ||
![]() |
03bc844ad0 | ||
![]() |
f7bdc35ed6 | ||
![]() |
0efdffd857 | ||
![]() |
6a16a42d0c | ||
![]() |
e9c00c72b1 | ||
![]() |
ab22f36b8a | ||
![]() |
c57497cd91 | ||
![]() |
ba123236e5 | ||
![]() |
338b6e4607 | ||
![]() |
f88c717560 | ||
![]() |
f8ffc92db5 | ||
![]() |
98c23c172c | ||
![]() |
781c107d8c | ||
![]() |
186668c075 | ||
![]() |
cf9f785193 | ||
![]() |
72d2d3f224 | ||
![]() |
087c76b394 | ||
![]() |
4f9fb2c8c3 | ||
![]() |
334e43e764 | ||
![]() |
7843256402 | ||
![]() |
0522ba35fe | ||
![]() |
24d3b52e0b | ||
![]() |
3177110f0f | ||
![]() |
e1b8243a67 | ||
![]() |
b1c6ce3885 | ||
![]() |
0b4b25a11e | ||
![]() |
1176fe984a | ||
![]() |
6ca768c3ee | ||
![]() |
3da1659c8d | ||
![]() |
9aa4cd319c | ||
![]() |
5af866cdca | ||
![]() |
2b421fa447 | ||
![]() |
30ec964325 | ||
![]() |
714d7d72eb | ||
![]() |
687aa0f363 | ||
![]() |
8363ab07a7 | ||
![]() |
c46a757339 | ||
![]() |
557864395b | ||
![]() |
3f7a85d80b | ||
![]() |
8d18d2ce1f | ||
![]() |
7141ba1587 | ||
![]() |
44d350a225 | ||
![]() |
239b8e72d9 | ||
![]() |
279bdb6fb1 | ||
![]() |
a0cea819da | ||
![]() |
9ab7f60544 | ||
![]() |
aaf7191bf3 | ||
![]() |
628c9be0c8 | ||
![]() |
733052720c | ||
![]() |
a10f007194 | ||
![]() |
6fa50c58d3 | ||
![]() |
c54a58d6e4 | ||
![]() |
34cb1ea3fd | ||
![]() |
f640b0ca91 | ||
![]() |
60e16da42e | ||
![]() |
0cdceb95d6 | ||
![]() |
70bd22d925 | ||
![]() |
82462dd647 | ||
![]() |
c0466e943d | ||
![]() |
b187b4695d | ||
![]() |
b1956d2a37 | ||
![]() |
590b622e5f | ||
![]() |
3d8174396a | ||
![]() |
b8dc6e9bd9 | ||
![]() |
8ee99109dc | ||
![]() |
902041d4ee | ||
![]() |
cc34aef47e | ||
![]() |
0afbbe7c7a | ||
![]() |
8004553ba7 | ||
![]() |
0023b2846a | ||
![]() |
34775c1816 | ||
![]() |
e0759e704b | ||
![]() |
0aa225ca78 | ||
![]() |
b43b4ee5c0 | ||
![]() |
0cdb8cecbf | ||
![]() |
fd6a306742 | ||
![]() |
7f3b3d2277 | ||
![]() |
8be5b977bf | ||
![]() |
d7ddb15f9c | ||
![]() |
9a6a1798d0 | ||
![]() |
14196fd349 | ||
![]() |
941b89a523 | ||
![]() |
a5f9e5f8c0 | ||
![]() |
80c3356c8f | ||
![]() |
914136b750 | ||
![]() |
f9a60795f5 | ||
![]() |
19640927c7 | ||
![]() |
22faac7e36 | ||
![]() |
30d260ab32 | ||
![]() |
115120d066 | ||
![]() |
1327844736 | ||
![]() |
29904f3cb7 | ||
![]() |
50395594b7 | ||
![]() |
9360af88b3 | ||
![]() |
376370336c | ||
![]() |
70df6e3302 | ||
![]() |
0a1fc2dc12 | ||
![]() |
9857f6e437 | ||
![]() |
56d6ebe916 | ||
![]() |
81134ea2d4 | ||
![]() |
a9f3e7fc54 | ||
![]() |
eb84e2f8c9 | ||
![]() |
61cfa0e86d | ||
![]() |
0a01b8ade9 | ||
![]() |
1457efa9a4 | ||
![]() |
fa5c7add7a | ||
![]() |
d644eba4d1 | ||
![]() |
9c422c1a8f | ||
![]() |
b6db37202f | ||
![]() |
4ca3891089 | ||
![]() |
4c7ed01776 | ||
![]() |
45c922c377 | ||
![]() |
f854c258bd | ||
![]() |
a643fac073 | ||
![]() |
861f105bea | ||
![]() |
bf10ce9f1e | ||
![]() |
ccf521d0a8 | ||
![]() |
6075d98eaa | ||
![]() |
a3801fc243 | ||
![]() |
a1f0c05f3a | ||
![]() |
a568c96929 | ||
![]() |
d58bcf3c0e | ||
![]() |
985f2e6436 | ||
![]() |
ad441fa793 | ||
![]() |
316300cc86 | ||
![]() |
5c4f37b234 | ||
![]() |
77b51a072d |
@@ -1,21 +1,21 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf|crlf
|
||||
insert_final_newline = true
|
||||
|
||||
# Matches multiple files with brace expansion notation
|
||||
# Set default charset
|
||||
charset = utf-8
|
||||
|
||||
# 2 space indentation
|
||||
[*.{cjs,mjs,js,jsx,ts,tsx,css,scss,sass,html,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# Unfortunately, EditorConfig doesn't support space configuration inside import braces directly.
|
||||
# You'll need to rely on your linter/formatter like ESLint or Prettier for that.
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
# Unix-style newlines with a newline ending every file
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Matches multiple files with brace expansion notation
|
||||
# Set default charset
|
||||
charset = utf-8
|
||||
|
||||
# 2 space indentation
|
||||
[*.{cjs,mjs,js,jsx,ts,tsx,css,scss,sass,html,json}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
# Unfortunately, EditorConfig doesn't support space configuration inside import braces directly.
|
||||
# You'll need to rely on your linter/formatter like ESLint or Prettier for that.
|
||||
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: "Build"
|
||||
name: "Build Action"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
|
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: "release"
|
||||
name: "Build Release"
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -130,6 +130,7 @@ jobs:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
body_path: CHANGELOG.md
|
||||
files: |
|
||||
NapCat.win32.ia32.zip
|
||||
NapCat.win32.x64.zip
|
||||
NapCat.linux.x64.zip
|
||||
NapCat.linux.arm64.zip
|
||||
|
69
.github/workflows/test.yml
vendored
Normal file
69
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: "Build Test"
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: write-all
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target_platform: [win32]
|
||||
target_arch: [x64,ia32]
|
||||
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
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -14,4 +14,5 @@ dist/
|
||||
|
||||
# Build
|
||||
*.db
|
||||
checkVersion.sh
|
||||
checkVersion.sh
|
||||
bun.lockb
|
||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
||||
[submodule "src/core"]
|
||||
path = src/core
|
||||
url = https://github.com/NapNeko/core.git
|
||||
branch = master
|
386
LICENSE
386
LICENSE
@@ -1,21 +1,373 @@
|
||||
MIT License
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
Copyright (c) 2024 NapCatQQ
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
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:
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
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.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
|
12
docs/changelogs/CHANGELOG.v1.7.8.md
Normal file
12
docs/changelogs/CHANGELOG.v1.7.8.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# v1.7.8
|
||||
|
||||
QQ Version: Windows 9.9.15-26702 / Linux 3.2.12-26702
|
||||
|
||||
## 启动的方式
|
||||
Way03/Way05
|
||||
|
||||
## 新增与调整
|
||||
1. 彻底支持发言时间与入群时间 For 26702
|
||||
2. 修复转发接口异常问题
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
13
docs/changelogs/old/CHANGELOG.v1.6.2.md
Normal file
13
docs/changelogs/old/CHANGELOG.v1.6.2.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# v1.6.2
|
||||
|
||||
QQ Version: Windows 9.9.11-24815 / Linux 3.2.9-24815
|
||||
|
||||
## 修复与优化
|
||||
* 修复获取Cookies异常崩溃问题
|
||||
* 尝试修复成员退群缓存问题
|
||||
* 修复自身退群后群缓存清理问题
|
||||
|
||||
## 新增与调整
|
||||
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
13
docs/changelogs/old/CHANGELOG.v1.6.3.md
Normal file
13
docs/changelogs/old/CHANGELOG.v1.6.3.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# v1.6.3
|
||||
|
||||
QQ Version: Windows 9.9.11-24815 / Linux 3.2.9-24815
|
||||
|
||||
## 修复与优化
|
||||
* 修复带有groupid的私聊消息异常发送到群聊消息
|
||||
* 尝试修复rws热重载失效问题
|
||||
* 尝试修复进群事件无法正常获取uin
|
||||
|
||||
## 新增与调整
|
||||
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
18
docs/changelogs/old/CHANGELOG.v1.6.4.md
Normal file
18
docs/changelogs/old/CHANGELOG.v1.6.4.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# v1.6.4
|
||||
|
||||
QQ Version: Windows 9.9.12-26000 / Linux 3.2.9-26000
|
||||
## 使用前警告
|
||||
1. 在最近版本由于QQ本体大幅变动,为了保证NapCat可用性,NapCat近期启动与安装方式将将大幅变动,请关注文档和社群获取。
|
||||
2. 在Core上完全执行开源,请不要用于违法用途,如此可能造成NapCat完全停止更新。
|
||||
3. 针对原启动方式的围堵,NapCat研发了多种方式,除此其余理论与扩展的分析和思路将部分展示于Docs,以便各位参与开发与维护NapCat。
|
||||
## 其余·备注
|
||||
启动方式: WayBoot.03 (Electron Main进程为Node 直接注入代码 同理项目: LiteLoader)
|
||||
|
||||
## 修复与优化
|
||||
1. 支持Win平台 9.9.12
|
||||
2. 修复部分发送图片下载异常情况
|
||||
|
||||
## 新增与调整
|
||||
没有哦
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
18
docs/changelogs/old/CHANGELOG.v1.6.5.md
Normal file
18
docs/changelogs/old/CHANGELOG.v1.6.5.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# v1.6.5
|
||||
|
||||
QQ Version: Windows 9.9.12-26000 / Linux 3.2.9-26000
|
||||
## 使用前警告
|
||||
1. 在最近版本由于QQ本体大幅变动,为了保证NapCat可用性,NapCat近期启动与安装方式将将大幅变动,请关注文档和社群获取。
|
||||
2. 在Core上完全执行开源,请不要用于违法用途,如此可能造成NapCat完全停止更新。
|
||||
3. 针对原启动方式的围堵,NapCat研发了多种方式,除此其余理论与扩展的分析和思路将部分展示于Docs,以便各位参与开发与维护NapCat。
|
||||
## 其余·备注
|
||||
启动方式: WayBoot.03 (Electron Main进程为Node 直接注入代码 同理项目: LiteLoader)
|
||||
|
||||
## 修复与优化
|
||||
1. 优化了WrapperNative载入代码
|
||||
2. 优化缓存
|
||||
|
||||
## 新增与调整
|
||||
没有哦
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
17
docs/changelogs/old/CHANGELOG.v1.6.6.md
Normal file
17
docs/changelogs/old/CHANGELOG.v1.6.6.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# v1.6.6
|
||||
|
||||
QQ Version: Windows 9.9.12-26000 / Linux 3.2.9-26000
|
||||
## 使用前警告
|
||||
1. 在最近版本由于QQ本体大幅变动,为了保证NapCat可用性,NapCat近期启动与安装方式将将大幅变动,请关注文档和社群获取。
|
||||
2. 在Core上完全执行开源,请不要用于违法用途,如此可能造成NapCat完全停止更新。
|
||||
3. 针对原启动方式的围堵,NapCat研发了多种方式,除此其余理论与扩展的分析和思路将部分展示于Docs,以便各位参与开发与维护NapCat。
|
||||
## 其余·备注
|
||||
启动方式: WayBoot.03 (Electron Main进程为Node 直接注入代码 同理项目: LiteLoader)
|
||||
|
||||
## 修复与优化
|
||||
1. 修复了一些问题
|
||||
|
||||
## 新增与调整
|
||||
没有哦
|
||||
|
||||
新增的 API 详细见[API文档](https://napneko.github.io/zh-CN/develop/extends_api)
|
@@ -1,2 +0,0 @@
|
||||
# 开始
|
||||
jadx 跳转于 `com.tencent.qqnt.kernel.*`
|
@@ -1,42 +0,0 @@
|
||||
# Android
|
||||
```java
|
||||
GroupMemberExtReq groupMemberExtReq = new GroupMemberExtReq();
|
||||
groupMemberExtReq.sourceType = MemberExtSourceType.TITLETYPE.ordinal();
|
||||
groupMemberExtReq.groupCode = longOrNull.longValue();
|
||||
groupMemberExtReq.beginUin = "0";
|
||||
groupMemberExtReq.dataTime = "0";
|
||||
Long[] lArr = new Long[1];
|
||||
AppInterface a2 = dVar.a();
|
||||
lArr[0] = Long.valueOf(a2 != null ? a2.getLongAccountUin() : 0L);
|
||||
arrayListOf = CollectionsKt__CollectionsKt.arrayListOf(lArr);
|
||||
groupMemberExtReq.uinList = arrayListOf;
|
||||
MemberExtInfoFilter memberExtInfoFilter = new MemberExtInfoFilter();
|
||||
memberExtInfoFilter.memberLevelInfoUin = 1;
|
||||
memberExtInfoFilter.memberLevelInfoPoint = 1;
|
||||
memberExtInfoFilter.memberLevelInfoActiveDay = 1;
|
||||
memberExtInfoFilter.memberLevelInfoLevel = 1;
|
||||
memberExtInfoFilter.levelName = 1;
|
||||
memberExtInfoFilter.dataTime = 1;
|
||||
memberExtInfoFilter.sysShowFlag = 1;
|
||||
memberExtInfoFilter.userShowFlag = 1;
|
||||
memberExtInfoFilter.userShowFlagNew = 1;
|
||||
memberExtInfoFilter.levelNameNew = 1;
|
||||
Unit unit = Unit.INSTANCE;
|
||||
groupMemberExtReq.memberExtFilter = memberExtInfoFilter;
|
||||
troopLevelFrequencyControl.f(troopUin, new TroopListRepo$fetchTroopLevelInfo$2(b2, groupMemberExtReq, troopUin, new com.tencent.qqnt.troopmemberlist.report.c("fetchTroopLevelInfo")));
|
||||
```
|
||||
# Win
|
||||
参数解析位于 sub_181456A10(24108) -> wrapper.node(24108)+1456A10
|
||||
IGroupService.GetMemberExt(param: object);
|
||||
param展开如下
|
||||
```
|
||||
groupCode string
|
||||
beginUin string
|
||||
dataTime string
|
||||
uinList Array<string>
|
||||
uinNum string
|
||||
groupType string
|
||||
richCardNameVer string
|
||||
sourceType number
|
||||
memberExtFilter object// 参数解析位于 sub_18145A6D0(24108) -> wrapper.node(24108)+145A6D0
|
||||
```
|
@@ -1,3 +1,4 @@
|
||||
|
||||
public static final int C2C_PIC_DOWNLOAD = 1004;
|
||||
public static final String C2C_PIC_DOWNLOAD_DOMAIN = "c2cpicdw.qpic.cn";
|
||||
public static final String C2C_PIC_DOWNLOAD_QUIC_DOMAIN = "c2cpicdw.quic.qpic.cn";
|
||||
|
16
docs/develop/NC 1.6.X的计划.md
Normal file
16
docs/develop/NC 1.6.X的计划.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# 开发方向
|
||||
方向一 NativeCall/Hook:
|
||||
1. 崩溃检测机制的实现
|
||||
2. Api_Caller 的Hook 可以拿到Event/Handler 进一步提升NC 即时的拦截与处理一些事件比如ReCall拦截
|
||||
3. Node包装层 进一步分析,拿到脱离自带Listener/Adapter,可以拿到一些更加底层的数据变动 或许包括更多二进制数据
|
||||
|
||||
方向二 全新的无头启动 Way01
|
||||
1. 基于Node启动原理,借助导出符号获取函数地址 再次还原NodeMain
|
||||
|
||||
方向三 发包与收包
|
||||
1. 参考 方向一/3 大概可以收包
|
||||
2. 发包 (暂时没有计划)
|
||||
|
||||
方向四 版本控制
|
||||
1. 根据不同版本进行逻辑控制
|
||||
2. 某些参数的自动提取
|
@@ -1,24 +0,0 @@
|
||||
# 前排提示
|
||||
由于Core未处于开源,非组织人员无法参与Core开发,此处为Core开发提示
|
||||
|
||||
# 准备工具
|
||||
frida ida-pro jadx x64dbg ce 内部调试脚本
|
||||
|
||||
## ida-pro
|
||||
1. 用于快速分析入参和返回类型
|
||||
2. 通过静态QLog推测语义
|
||||
3. 提取Listener与Service (常用)
|
||||
## frida
|
||||
1. 用于动态获取QLog推测语义
|
||||
2. 捕捉Native函数 实际入参与数据 分析中间流程
|
||||
|
||||
## jadx
|
||||
1. 通过其它平台实现 静态获取QLog推测语义
|
||||
2. 提供部分未调用代码 参考
|
||||
|
||||
## x64dbg
|
||||
1. 验证IDA的Hook点
|
||||
|
||||
## 内部脚本
|
||||
1. 提取Listener与Service (不调用无类型 不推荐)
|
||||
2. 获取NT调用流程
|
8
docs/develop/碎碎的研究记录.md
Normal file
8
docs/develop/碎碎的研究记录.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Api方向
|
||||
## getMsgUniqueId √ 已应用
|
||||
getMsgUniqueId 传入时间 产出一个唯一ID 发送消息作为一个参数
|
||||
|
||||
# Native方向
|
||||
## magic_load
|
||||
## api_caller
|
||||
## NodeMain
|
14
package.json
14
package.json
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "1.6.1",
|
||||
"version": "1.7.8",
|
||||
"scripts": {
|
||||
"watch:dev": "vite --mode development",
|
||||
"watch:prod": "vite --mode production",
|
||||
@@ -19,10 +19,9 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.7",
|
||||
"@babel/preset-typescript": "^7.24.7",
|
||||
"vite-plugin-babel": "^1.2.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-proposal-decorators": "^7.24.7",
|
||||
"@babel/preset-typescript": "^7.24.7",
|
||||
"@log4js-node/log4js-api": "^1.0.2",
|
||||
"@protobuf-ts/plugin": "^2.9.4",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
@@ -31,9 +30,9 @@
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/figlet": "^1.5.8",
|
||||
"@types/fluent-ffmpeg": "^2.1.24",
|
||||
"@types/node": "^20.11.30",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/qrcode-terminal": "^0.12.2",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
||||
"@typescript-eslint/parser": "^7.4.0",
|
||||
@@ -47,6 +46,7 @@
|
||||
"rollup-plugin-obfuscator": "^1.1.0",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.2.6",
|
||||
"vite-plugin-babel": "^1.2.0",
|
||||
"vite-plugin-cp": "^4.0.8",
|
||||
"vite-plugin-dts": "^3.8.2",
|
||||
"vite-tsconfig-paths": "^4.3.2"
|
||||
@@ -64,9 +64,7 @@
|
||||
"json-schema-to-ts": "^3.1.0",
|
||||
"log4js": "^6.9.1",
|
||||
"qrcode-terminal": "^0.12.0",
|
||||
"silk-wasm": "^3.3.4",
|
||||
"sqlite3": "^5.1.7",
|
||||
"uuid": "^10.0.0",
|
||||
"silk-wasm": "^3.6.1",
|
||||
"ws": "^8.16.0"
|
||||
}
|
||||
}
|
||||
|
45
script/BootWay.03.ps1
Normal file
45
script/BootWay.03.ps1
Normal file
@@ -0,0 +1,45 @@
|
||||
# Dont Use This Script
|
||||
# 2024.7.3
|
||||
function Get-QQpath {
|
||||
try {
|
||||
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
|
||||
$uninstallString = $key.UninstallString
|
||||
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe"
|
||||
}
|
||||
catch {
|
||||
throw "get QQ path error: $_"
|
||||
}
|
||||
}
|
||||
function Select-QQPath {
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
[System.Windows.Forms.Application]::EnableVisualStyles()
|
||||
|
||||
$dialogTitle = "Select QQ.exe"
|
||||
|
||||
$filePicker = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$filePicker.Title = $dialogTitle
|
||||
$filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*"
|
||||
$filePicker.FilterIndex = 1
|
||||
$null = $filePicker.ShowDialog()
|
||||
if (-not ($filePicker.FileName)) {
|
||||
throw "User did not select an .exe file."
|
||||
}
|
||||
return $filePicker.FileName
|
||||
}
|
||||
|
||||
$params = $args -join " "
|
||||
Try {
|
||||
$QQpath = Get-QQpath
|
||||
}
|
||||
Catch {
|
||||
$QQpath = Select-QQPath
|
||||
}
|
||||
|
||||
if (!(Test-Path $QQpath)) {
|
||||
throw "provided QQ path is invalid: $QQpath"
|
||||
}
|
||||
|
||||
$Bootfile = Join-Path $PSScriptRoot "napcat.mjs"
|
||||
$env:ELECTRON_RUN_AS_NODE = 1
|
||||
$commandInfo = Get-Command $QQpath -ErrorAction Stop
|
||||
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& chcp 65001;& '$($commandInfo.Path)' --enable-logging }"
|
123
script/BootWay05.ps1
Normal file
123
script/BootWay05.ps1
Normal file
@@ -0,0 +1,123 @@
|
||||
# 检查当前会话是否具有管理员权限
|
||||
function Test-Administrator {
|
||||
$user = [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||
}
|
||||
|
||||
if (-not (Test-Administrator)) {
|
||||
# 如果不是管理员,则重新启动脚本以管理员模式运行
|
||||
$scriptPath = $myInvocation.MyCommand.Path
|
||||
if (-not $scriptPath) {
|
||||
$scriptPath = $PSCommandPath
|
||||
}
|
||||
$newProcess = New-Object System.Diagnostics.ProcessStartInfo "powershell";
|
||||
$newProcess.Arguments = "-File `"$scriptPath`" $args"
|
||||
$newProcess.Verb = "runas";
|
||||
[System.Diagnostics.Process]::Start($newProcess);
|
||||
exit
|
||||
}
|
||||
|
||||
function Get-QQpath {
|
||||
try {
|
||||
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
|
||||
$uninstallString = $key.UninstallString
|
||||
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\QQ.exe"
|
||||
}
|
||||
catch {
|
||||
throw "get QQ path error: $_"
|
||||
}
|
||||
}
|
||||
function Select-QQPath {
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
[System.Windows.Forms.Application]::EnableVisualStyles()
|
||||
|
||||
$dialogTitle = "Select QQ.exe"
|
||||
|
||||
$filePicker = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$filePicker.Title = $dialogTitle
|
||||
$filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*"
|
||||
$filePicker.FilterIndex = 1
|
||||
$null = $filePicker.ShowDialog()
|
||||
if (-not ($filePicker.FileName)) {
|
||||
throw "User did not select an .exe file."
|
||||
}
|
||||
return $filePicker.FileName
|
||||
}
|
||||
|
||||
# 设置当前工作目录
|
||||
$scriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
|
||||
Set-Location $scriptDirectory
|
||||
|
||||
# 获取当前目录路径
|
||||
$currentPath = Get-Location
|
||||
|
||||
# 替换\为/
|
||||
$currentPath = $currentPath -replace '\\', '/'
|
||||
|
||||
# 生成JavaScript代码
|
||||
$jsCode = @"
|
||||
(async () => {
|
||||
await import('file:///$currentPath/napcat.mjs');
|
||||
})();
|
||||
"@
|
||||
|
||||
# 将JavaScript代码保存到文件中
|
||||
$jsFilePath = Join-Path $currentPath "loadScript.js"
|
||||
$jsCode | Out-File -FilePath $jsFilePath -Encoding UTF8
|
||||
|
||||
Write-Output "JavaScript code has been generated and saved to $jsFilePath"
|
||||
# 设置NAPCAT_PATH环境变量为 当前目录的loadScript.js地址
|
||||
$env:NAPCAT_PATH = $jsFilePath
|
||||
|
||||
$params = $args -join " "
|
||||
Try {
|
||||
$QQpath = Get-QQpath
|
||||
}
|
||||
Catch {
|
||||
$QQpath = Select-QQPath
|
||||
}
|
||||
# 拿不到QQ路径则退出
|
||||
if (!(Test-Path $QQpath)) {
|
||||
Write-Output "provided QQ path is invalid: $QQpath"
|
||||
Read-Host "Press any key to continue..."
|
||||
exit
|
||||
}
|
||||
|
||||
$commandInfo = Get-Command $QQpath -ErrorAction Stop
|
||||
|
||||
# 收集dbghelp.dll路径和HASH信息
|
||||
$QQpath = Split-Path $QQpath
|
||||
$oldDllPath = Join-Path $QQpath "dbghelp.dll"
|
||||
$oldDllHash = Get-FileHash $oldDllPath -Algorithm MD5
|
||||
$newDllPath = Join-Path $currentPath "dbghelp.dll"
|
||||
$newDllHash = Get-FileHash $newDllPath -Algorithm MD5
|
||||
# 如果文件一致则跳过
|
||||
if ($oldDllHash.Hash -ne $newDllHash.Hash) {
|
||||
$processes = Get-Process -Name QQ -ErrorAction SilentlyContinue
|
||||
if ($processes) {
|
||||
# 文件占用则退出
|
||||
Write-Output "dbghelp.dll is in use by the following processes:"
|
||||
$processes | ForEach-Object { Write-Output "$($_.Id) $($_.Name) $($_.Path)" }
|
||||
Write-Output "dbghelp.dll is in use, cannot continue."
|
||||
Read-Host "Press any key to continue..."
|
||||
exit
|
||||
} else {
|
||||
# 文件未占用则尝试覆盖
|
||||
try {
|
||||
Copy-Item -Path "$newDllPath" -Destination "$oldDllPath" -Force
|
||||
Write-Output "dbghelp.dll has been copied to $QQpath"
|
||||
} catch {
|
||||
Write-Output "Failed to copy dbghelp.dll: $_"
|
||||
Read-Host "Press any key to continue..."
|
||||
exit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 带参数启动QQ
|
||||
try {
|
||||
Start-Process powershell -ArgumentList '-noexit', '-noprofile', "-command &{& chcp 65001;& '$($commandInfo.Path)' --enable-logging $params}" -NoNewWindow -ErrorAction Stop
|
||||
} catch {
|
||||
Write-Output "Failed to start process as administrator: $_"
|
||||
Read-Host "Press any key to continue..."
|
||||
}
|
28
script/NapCat.164.bat
Normal file
28
script/NapCat.164.bat
Normal file
@@ -0,0 +1,28 @@
|
||||
@echo off
|
||||
chcp 65001
|
||||
:: 检查是否有管理员权限
|
||||
net session >nul 2>&1
|
||||
if %errorlevel% neq 0 (
|
||||
echo 请求管理员权限...
|
||||
powershell -Command "Start-Process '%~f0' -Verb runAs"
|
||||
exit /b
|
||||
)
|
||||
:: 如果有管理员权限,继续执行
|
||||
setlocal enabledelayedexpansion
|
||||
:loop_read
|
||||
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
|
||||
set "RetString=%%b"
|
||||
goto :napcat_boot
|
||||
)
|
||||
|
||||
:napcat_boot
|
||||
for %%a in ("!RetString!") do (
|
||||
set "pathWithoutUninstall=%%~dpa"
|
||||
)
|
||||
|
||||
set "QQPath=!pathWithoutUninstall!QQ.exe"
|
||||
|
||||
echo !QQPath!
|
||||
"!QQPath!" --enable-logging %*
|
||||
|
||||
pause
|
3
script/NapCat.Way01.bat
Normal file
3
script/NapCat.Way01.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
REM 全新启动脚本 基于 Hook Native 预计版本1.6.0左右发布
|
||||
@echo off
|
||||
pause
|
BIN
script/dbghelp.dll
Normal file
BIN
script/dbghelp.dll
Normal file
Binary file not shown.
20
script/index.js
Normal file
20
script/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// --------------------
|
||||
// 2024.7.3 9.9.12 BootWay.03 其余方法暂不公开(此方案为临时方案 Win平台已验证)
|
||||
// 缺陷 (已知)
|
||||
// 1.与非入侵式不同 现在破坏本体代码
|
||||
// 2.重启代码与正常启动代码失效
|
||||
// 3.Win需要补丁
|
||||
// 4.更新后丢失内容 需要重写此文件
|
||||
// 5.安装难度上升与周围基础设施失效
|
||||
// --------------------
|
||||
|
||||
const path = require('path');
|
||||
const CurrentPath = path.dirname(__filename)
|
||||
const hasNapcatParam = process.argv.includes('--enable-logging');
|
||||
if (hasNapcatParam) {
|
||||
(async () => {
|
||||
await import("file://" + path.join(CurrentPath, './napcat/napcat.mjs'));
|
||||
})();
|
||||
} else {
|
||||
require('./launcher.node').load('external_index', module);
|
||||
}
|
18
script/napcat-9912-utf8.bat
Normal file
18
script/napcat-9912-utf8.bat
Normal file
@@ -0,0 +1,18 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
chcp 65001
|
||||
:loop_read
|
||||
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
|
||||
set "RetString=%%b"
|
||||
goto :napcat_boot
|
||||
)
|
||||
|
||||
:napcat_boot
|
||||
for %%a in ("!RetString!") do (
|
||||
set "pathWithoutUninstall=%%~dpa"
|
||||
)
|
||||
|
||||
set "QQPath=!pathWithoutUninstall!"
|
||||
cd /d !QQPath!
|
||||
echo !QQPath!
|
||||
QQ.exe --enable-logging %*
|
41
script/napcat-9912-utf8.ps1
Normal file
41
script/napcat-9912-utf8.ps1
Normal file
@@ -0,0 +1,41 @@
|
||||
function Get-QQpath {
|
||||
try {
|
||||
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
|
||||
$uninstallString = $key.UninstallString
|
||||
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\"
|
||||
}
|
||||
catch {
|
||||
throw "get QQ path error: $_"
|
||||
}
|
||||
}
|
||||
function Select-QQPath {
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
[System.Windows.Forms.Application]::EnableVisualStyles()
|
||||
|
||||
$dialogTitle = "Select QQ.exe"
|
||||
|
||||
$filePicker = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$filePicker.Title = $dialogTitle
|
||||
$filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*"
|
||||
$filePicker.FilterIndex = 1
|
||||
$null = $filePicker.ShowDialog()
|
||||
if (-not ($filePicker.FileName)) {
|
||||
throw "User did not select an .exe file."
|
||||
}
|
||||
return $filePicker.FileName
|
||||
}
|
||||
|
||||
$params = $args -join " "
|
||||
Try {
|
||||
$QQpath = Get-QQpath
|
||||
}
|
||||
Catch {
|
||||
$QQpath = Select-QQPath
|
||||
}
|
||||
|
||||
if (!(Test-Path $QQpath)) {
|
||||
throw "provided QQ path is invalid: $QQpath"
|
||||
}
|
||||
|
||||
Set-Location -Path $QQpath
|
||||
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& chcp 65001;& ./QQ.exe --enable-logging $params}"
|
17
script/napcat-9912.bat
Normal file
17
script/napcat-9912.bat
Normal file
@@ -0,0 +1,17 @@
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
:loop_read
|
||||
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
|
||||
set "RetString=%%b"
|
||||
goto :napcat_boot
|
||||
)
|
||||
|
||||
:napcat_boot
|
||||
for %%a in ("!RetString!") do (
|
||||
set "pathWithoutUninstall=%%~dpa"
|
||||
)
|
||||
|
||||
set QQPath=!pathWithoutUninstall!
|
||||
cd /d !QQPath!
|
||||
echo !QQPath!
|
||||
QQ.exe --enable-logging %*
|
41
script/napcat-9912.ps1
Normal file
41
script/napcat-9912.ps1
Normal file
@@ -0,0 +1,41 @@
|
||||
function Get-QQpath {
|
||||
try {
|
||||
$key = Get-ItemProperty -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ"
|
||||
$uninstallString = $key.UninstallString
|
||||
return [System.IO.Path]::GetDirectoryName($uninstallString) + "\"
|
||||
}
|
||||
catch {
|
||||
throw "get QQ path error: $_"
|
||||
}
|
||||
}
|
||||
function Select-QQPath {
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
[System.Windows.Forms.Application]::EnableVisualStyles()
|
||||
|
||||
$dialogTitle = "Select QQ.exe"
|
||||
|
||||
$filePicker = New-Object System.Windows.Forms.OpenFileDialog
|
||||
$filePicker.Title = $dialogTitle
|
||||
$filePicker.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*"
|
||||
$filePicker.FilterIndex = 1
|
||||
$null = $filePicker.ShowDialog()
|
||||
if (-not ($filePicker.FileName)) {
|
||||
throw "User did not select an .exe file."
|
||||
}
|
||||
return $filePicker.FileName
|
||||
}
|
||||
|
||||
$params = $args -join " "
|
||||
Try {
|
||||
$QQpath = Get-QQpath
|
||||
}
|
||||
Catch {
|
||||
$QQpath = Select-QQPath
|
||||
}
|
||||
|
||||
if (!(Test-Path $QQpath)) {
|
||||
throw "provided QQ path is invalid: $QQpath"
|
||||
}
|
||||
|
||||
Set-Location -Path $QQpath
|
||||
Start-Process powershell -ArgumentList "-noexit", "-noprofile", "-command &{& ./QQ.exe --enable-logging $params}"
|
@@ -9,7 +9,15 @@ type RegisterHandler = (res: Response, payload: any) => Promise<any>
|
||||
export abstract class HttpServerBase {
|
||||
name: string = 'NapCatQQ';
|
||||
private readonly expressAPP: Express;
|
||||
private server: http.Server | null = null;
|
||||
private _server: http.Server | null = null;
|
||||
|
||||
public get server(): http.Server | null {
|
||||
return this._server;
|
||||
}
|
||||
|
||||
private set server(value: http.Server | null) {
|
||||
this._server = value;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.expressAPP = express();
|
||||
@@ -78,7 +86,7 @@ export abstract class HttpServerBase {
|
||||
this.start(port, host);
|
||||
}
|
||||
|
||||
abstract handleFailed(res: Response, payload: any, err: any): void
|
||||
abstract handleFailed(res: Response, payload: any, err: Error): void
|
||||
|
||||
registerRouter(method: 'post' | 'get' | string, url: string, handler: RegisterHandler) {
|
||||
if (!url.startsWith('/')) {
|
||||
@@ -103,7 +111,7 @@ export abstract class HttpServerBase {
|
||||
try {
|
||||
res.send(await handler(res, payload));
|
||||
} catch (e: any) {
|
||||
this.handleFailed(res, payload, e.stack.toString());
|
||||
this.handleFailed(res, payload, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { WebSocket, WebSocketServer } from 'ws';
|
||||
import http from 'http';
|
||||
import urlParse from 'url';
|
||||
import { IncomingMessage } from 'node:http';
|
||||
import { log } from '@/common/utils/log';
|
||||
@@ -27,17 +28,36 @@ export class WebsocketServerBase {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
start(port: number, host: string = '') {
|
||||
try {
|
||||
this.ws = new WebSocketServer({
|
||||
port,
|
||||
host: '',
|
||||
maxPayload: 1024 * 1024 * 1024
|
||||
}).on('error', () => {
|
||||
});
|
||||
log(`ws服务启动成功, ${host}:${port}`);
|
||||
} catch (e: any) {
|
||||
throw Error('ws服务启动失败, 请检查监听的ip和端口' + e.toString());
|
||||
start(port: number | http.Server, host: string = '') {
|
||||
if (port instanceof http.Server) {
|
||||
try {
|
||||
const wss = new WebSocketServer({
|
||||
noServer: true,
|
||||
maxPayload: 1024 * 1024 * 1024
|
||||
}).on('error', () => {
|
||||
});
|
||||
this.ws = wss;
|
||||
port.on('upgrade', function upgrade(request, socket, head) {
|
||||
wss.handleUpgrade(request, socket, head, function done(ws) {
|
||||
wss.emit('connection', ws, request);
|
||||
});
|
||||
});
|
||||
log('ws服务启动成功, 绑定到HTTP服务');
|
||||
} catch (e: any) {
|
||||
throw Error('ws服务启动失败, 可能是绑定的HTTP服务异常' + e.toString());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
this.ws = new WebSocketServer({
|
||||
port,
|
||||
host: '',
|
||||
maxPayload: 1024 * 1024 * 1024
|
||||
}).on('error', () => {
|
||||
});
|
||||
log(`ws服务启动成功, ${host}:${port}`);
|
||||
} catch (e: any) {
|
||||
throw Error('ws服务启动失败, 请检查监听的ip和端口' + e.toString());
|
||||
}
|
||||
}
|
||||
this.ws.on('connection', (wsClient, req) => {
|
||||
const url: string = req.url!.split('?').shift() || '/';
|
||||
@@ -50,10 +70,12 @@ export class WebsocketServerBase {
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.ws && this.ws.close((err) => {
|
||||
log('ws server close failed!', err);
|
||||
});
|
||||
this.ws = null;
|
||||
if (this.ws) {
|
||||
this.ws.close((err) => {
|
||||
if (err) log('ws server close failed!', err);
|
||||
});
|
||||
this.ws = null;
|
||||
}
|
||||
}
|
||||
|
||||
restart(port: number) {
|
||||
|
@@ -1,36 +0,0 @@
|
||||
import { sleep } from '@/common/utils/helper';
|
||||
import { logError } from './log';
|
||||
type AsyncQueueTask = (() => void) | (()=>Promise<void>);
|
||||
|
||||
|
||||
export class AsyncQueue {
|
||||
private tasks: (AsyncQueueTask)[] = [];
|
||||
|
||||
public addTask(task: AsyncQueueTask) {
|
||||
this.tasks.push(task);
|
||||
// console.log('addTask', this.tasks.length);
|
||||
if (this.tasks.length === 1) {
|
||||
this.runQueue().then().catch(()=>{});
|
||||
}
|
||||
}
|
||||
|
||||
private async runQueue() {
|
||||
// console.log('runQueue', this.tasks.length);
|
||||
while (this.tasks.length > 0) {
|
||||
const task = this.tasks[0];
|
||||
// console.log('typeof task', typeof task);
|
||||
try {
|
||||
const taskRet = task();
|
||||
// console.log('type of taskRet', typeof taskRet, taskRet);
|
||||
if (taskRet instanceof Promise) {
|
||||
await taskRet;
|
||||
}
|
||||
} catch (e) {
|
||||
// console.error(e);
|
||||
logError(e);
|
||||
}
|
||||
this.tasks.shift();
|
||||
await sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@ import fs from 'node:fs';
|
||||
import { log, logDebug, logError } from '@/common/utils/log';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { selfInfo } from '@/core/data';
|
||||
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
@@ -12,8 +13,9 @@ const configDir = path.resolve(__dirname, 'config');
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
|
||||
|
||||
export class ConfigBase<T>{
|
||||
|
||||
export class ConfigBase<T> {
|
||||
public name: string = 'default_config';
|
||||
private pathName: string | null = null; // 本次读取的文件路径
|
||||
constructor() {
|
||||
}
|
||||
|
||||
@@ -22,19 +24,28 @@ export class ConfigBase<T>{
|
||||
return null;
|
||||
}
|
||||
|
||||
getConfigDir(){
|
||||
getConfigDir() {
|
||||
const configDir = path.resolve(__dirname, 'config');
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
return configDir;
|
||||
}
|
||||
getConfigPath(): string {
|
||||
throw new Error('Method not implemented.');
|
||||
getConfigPath(pathName: string | null): string {
|
||||
const suffix = pathName ? `_${pathName}` : '';
|
||||
const filename = `${this.name}${suffix}.json`;
|
||||
return path.join(this.getConfigDir(), filename);
|
||||
}
|
||||
|
||||
read() {
|
||||
const configPath = this.getConfigPath();
|
||||
// 尝试加载当前账号配置
|
||||
if (this.read_from_file(selfInfo.uin, false)) return this;
|
||||
// 尝试加载默认配置
|
||||
return this.read_from_file('', true);
|
||||
}
|
||||
read_from_file(pathName: string, createIfNotExist: boolean) {
|
||||
const configPath = this.getConfigPath(pathName);
|
||||
if (!fs.existsSync(configPath)) {
|
||||
try{
|
||||
if (!createIfNotExist) return null;
|
||||
this.pathName = pathName; // 记录有效的设置文件
|
||||
try {
|
||||
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
|
||||
log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`);
|
||||
}
|
||||
@@ -43,6 +54,7 @@ export class ConfigBase<T>{
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
try {
|
||||
const data = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
||||
logDebug(`配置文件${configPath}已加载`, data);
|
||||
@@ -61,9 +73,13 @@ export class ConfigBase<T>{
|
||||
}
|
||||
}
|
||||
|
||||
save(config: T) {
|
||||
save(config: T, overwrite: boolean = false) {
|
||||
Object.assign(this, config);
|
||||
const configPath = this.getConfigPath();
|
||||
if (overwrite) {
|
||||
// 用户要求强制写入,则变更当前文件为目标文件
|
||||
this.pathName = `${selfInfo.uin}`;
|
||||
}
|
||||
const configPath = this.getConfigPath(this.pathName);
|
||||
try {
|
||||
fs.writeFileSync(configPath, JSON.stringify(this, this.getKeys(), 2));
|
||||
} catch (e: any) {
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { NodeIKernelMsgListener } from '@/core';
|
||||
import { NodeIQQNTWrapperSession } from '@/core/wrapper';
|
||||
import { randomUUID } from 'crypto';
|
||||
|
||||
@@ -6,6 +5,7 @@ interface Internal_MapKey {
|
||||
timeout: number,
|
||||
createtime: number,
|
||||
func: (...arg: any[]) => any,
|
||||
checker: ((...args: any[]) => boolean) | undefined,
|
||||
}
|
||||
|
||||
export class ListenerClassBase {
|
||||
@@ -84,17 +84,19 @@ export class NTEventWrapper {
|
||||
}
|
||||
//统一回调清理事件
|
||||
async DispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) {
|
||||
//console.log(ListenerMainName, this.EventTask.get(ListenerMainName), ListenerSubName, this.EventTask.get(ListenerMainName)?.get(ListenerSubName));
|
||||
//console.log("[EventDispatcher]",ListenerMainName, ListenerSubName, ...args);
|
||||
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.forEach((task, uuid) => {
|
||||
//console.log(task.func, uuid, task.createtime, task.timeout);
|
||||
if (task.createtime + task.timeout < Date.now()) {
|
||||
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid);
|
||||
return;
|
||||
}
|
||||
task.func(...args);
|
||||
if (task.checker && task.checker(...args)) {
|
||||
task.func(...args);
|
||||
}
|
||||
});
|
||||
}
|
||||
async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any>,>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
|
||||
async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any> | any>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
|
||||
return new Promise<Awaited<ReturnType<EventType>>>(async (resolve, reject) => {
|
||||
const EventFunc = this.CreatEventFunction<EventType>(EventName);
|
||||
let complete = false;
|
||||
@@ -108,27 +110,71 @@ export class NTEventWrapper {
|
||||
resolve(retData);
|
||||
});
|
||||
}
|
||||
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, ...args: Parameters<EventType>) {
|
||||
async RegisterListen<ListenerType extends (...args: any[]) => void>(ListenerName = '', waitTimes = 1, timeout = 5000, checker: (...args: Parameters<ListenerType>) => boolean) {
|
||||
return new Promise<Parameters<ListenerType>>((resolve, reject) => {
|
||||
const ListenerNameList = ListenerName.split('/');
|
||||
const ListenerMainName = ListenerNameList[0];
|
||||
const ListenerSubName = ListenerNameList[1];
|
||||
const id = randomUUID();
|
||||
let complete = 0;
|
||||
let retData: Parameters<ListenerType> | undefined = undefined;
|
||||
const databack = () => {
|
||||
if (complete == 0) {
|
||||
reject(new Error(' ListenerName:' + ListenerName + ' timeout'));
|
||||
} else {
|
||||
resolve(retData!);
|
||||
}
|
||||
};
|
||||
const Timeouter = setTimeout(databack, timeout);
|
||||
const eventCallbak = {
|
||||
timeout: timeout,
|
||||
createtime: Date.now(),
|
||||
checker: checker,
|
||||
func: (...args: Parameters<ListenerType>) => {
|
||||
complete++;
|
||||
retData = args;
|
||||
if (complete >= waitTimes) {
|
||||
clearTimeout(Timeouter);
|
||||
databack();
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!this.EventTask.get(ListenerMainName)) {
|
||||
this.EventTask.set(ListenerMainName, new Map());
|
||||
}
|
||||
if (!(this.EventTask.get(ListenerMainName)?.get(ListenerSubName))) {
|
||||
this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map());
|
||||
}
|
||||
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak);
|
||||
this.CreatListenerFunction(ListenerMainName);
|
||||
});
|
||||
}
|
||||
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>
|
||||
(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, checker: (...args: Parameters<ListenerType>) => boolean, ...args: Parameters<EventType>) {
|
||||
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
|
||||
const id = randomUUID();
|
||||
let complete = 0;
|
||||
let retData: Parameters<ListenerType> | undefined = undefined;
|
||||
let retEvent: any = {};
|
||||
const databack = () => {
|
||||
if (complete < waitTimes) {
|
||||
reject(new Error('NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' timeout'));
|
||||
if (complete == 0) {
|
||||
reject(new Error('Timeout: NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' EventRet:\n' + JSON.stringify(retEvent, null, 4) + '\n'));
|
||||
} else {
|
||||
resolve([retEvent as Awaited<ReturnType<EventType>>, ...retData!]);
|
||||
}
|
||||
};
|
||||
const Timeouter = setTimeout(databack, timeout);
|
||||
|
||||
|
||||
const ListenerNameList = ListenerName.split('/');
|
||||
const ListenerMainName = ListenerNameList[0];
|
||||
const ListenerSubName = ListenerNameList[1];
|
||||
|
||||
const Timeouter = setTimeout(databack, timeout);
|
||||
|
||||
const eventCallbak = {
|
||||
timeout: timeout,
|
||||
createtime: Date.now(),
|
||||
checker: checker,
|
||||
func: (...args: any[]) => {
|
||||
complete++;
|
||||
//console.log('func', ...args);
|
||||
@@ -148,7 +194,6 @@ export class NTEventWrapper {
|
||||
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak);
|
||||
this.CreatListenerFunction(ListenerMainName);
|
||||
const EventFunc = this.CreatEventFunction<EventType>(EventName);
|
||||
//console.log("测试打点", args);
|
||||
retEvent = await EventFunc!(...(args as any[]));
|
||||
});
|
||||
}
|
||||
|
@@ -1,145 +0,0 @@
|
||||
import { logError, logDebug } from '@/common/utils/log';
|
||||
|
||||
type group_id = number;
|
||||
type user_id = number;
|
||||
|
||||
class cacheNode<T> {
|
||||
value: T;
|
||||
groupId: group_id;
|
||||
userId: user_id;
|
||||
prev: cacheNode<T> | null;
|
||||
next: cacheNode<T> | null;
|
||||
timestamp: number;
|
||||
|
||||
constructor(groupId: group_id, userId: user_id, value: T) {
|
||||
this.groupId = groupId;
|
||||
this.userId = userId;
|
||||
this.value = value;
|
||||
this.prev = null;
|
||||
this.next = null;
|
||||
this.timestamp = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
type cache<T> = { [key: group_id]: { [key: user_id]: cacheNode<T> } };
|
||||
class LRU<T> {
|
||||
private maxAge: number;
|
||||
private maxSize: number;
|
||||
private currentSize: number;
|
||||
private cache: cache<T>;
|
||||
private head: cacheNode<T> | null = null;
|
||||
private tail: cacheNode<T> | null = null;
|
||||
private onFuncs: ((node: cacheNode<T>) => void)[] = [];
|
||||
|
||||
constructor(maxAge: number = 2e4, maxSize: number = 5e3) {
|
||||
this.maxAge = maxAge;
|
||||
this.maxSize = maxSize;
|
||||
this.cache = Object.create(null);
|
||||
this.currentSize = 0;
|
||||
|
||||
if (maxSize == 0) return;
|
||||
setInterval(() => this.removeExpired(), this.maxAge);
|
||||
}
|
||||
|
||||
// 移除LRU节点
|
||||
private removeLRUNode(node: cacheNode<T>) {
|
||||
logDebug(
|
||||
'removeLRUNode',
|
||||
node.groupId,
|
||||
node.userId,
|
||||
node.value,
|
||||
this.currentSize
|
||||
);
|
||||
node.prev = node.next = null;
|
||||
delete this.cache[node.groupId][node.userId];
|
||||
this.removeNode(node);
|
||||
this.onFuncs.forEach((func) => func(node));
|
||||
this.currentSize--;
|
||||
}
|
||||
|
||||
public on(func: (node: cacheNode<T>) => void) {
|
||||
this.onFuncs.push(func);
|
||||
}
|
||||
|
||||
private removeExpired() {
|
||||
const now = Date.now();
|
||||
let current = this.tail;
|
||||
const nodesToRemove: cacheNode<T>[] = [];
|
||||
let removedCount = 0;
|
||||
|
||||
// 收集需要删除的节点
|
||||
while (current && now - current.timestamp > this.maxAge) {
|
||||
nodesToRemove.push(current);
|
||||
current = current.prev;
|
||||
removedCount++;
|
||||
if (removedCount >= 100) break;
|
||||
}
|
||||
|
||||
// 更新链表指向
|
||||
if (nodesToRemove.length > 0) {
|
||||
const newTail = nodesToRemove[nodesToRemove.length - 1].prev;
|
||||
if (newTail) {
|
||||
newTail.next = null;
|
||||
} else {
|
||||
this.head = null;
|
||||
}
|
||||
this.tail = newTail;
|
||||
}
|
||||
|
||||
nodesToRemove.forEach((node) => {
|
||||
node.prev = node.next = null;
|
||||
delete this.cache[node.groupId][node.userId];
|
||||
|
||||
this.currentSize--;
|
||||
this.onFuncs.forEach((func) => func(node));
|
||||
});
|
||||
}
|
||||
|
||||
private addNode(node: cacheNode<T>) {
|
||||
node.next = this.head;
|
||||
if (this.head) this.head.prev = node;
|
||||
if (!this.tail) this.tail = node;
|
||||
this.head = node;
|
||||
}
|
||||
|
||||
private removeNode(node: cacheNode<T>) {
|
||||
if (node.prev) node.prev.next = node.next;
|
||||
if (node.next) node.next.prev = node.prev;
|
||||
if (node === this.head) this.head = node.next;
|
||||
if (node === this.tail) this.tail = node.prev;
|
||||
}
|
||||
|
||||
private moveToHead(node: cacheNode<T>) {
|
||||
if (this.head === node) return;
|
||||
|
||||
this.removeNode(node);
|
||||
this.addNode(node);
|
||||
node.prev = null;
|
||||
}
|
||||
|
||||
public set(groupId: group_id, userId: user_id, value: T) {
|
||||
if (!this.cache[groupId]) {
|
||||
this.cache[groupId] = Object.create(null);
|
||||
}
|
||||
|
||||
const groupObject = this.cache[groupId];
|
||||
|
||||
if (groupObject[userId]) {
|
||||
const node = groupObject[userId];
|
||||
node.value = value;
|
||||
node.timestamp = Date.now();
|
||||
this.moveToHead(node);
|
||||
} else {
|
||||
const node = new cacheNode(groupId, userId, value);
|
||||
groupObject[userId] = node;
|
||||
this.currentSize++;
|
||||
this.addNode(node);
|
||||
if (this.currentSize > this.maxSize) {
|
||||
const tail = this.tail!;
|
||||
this.removeLRUNode(tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default LRU;
|
@@ -1,20 +1,40 @@
|
||||
import crypto from 'crypto';
|
||||
import { Peer } from '@/core';
|
||||
import crypto, { randomInt, randomUUID } from 'crypto';
|
||||
import { logError } from './log';
|
||||
|
||||
class LimitedHashTable<K, V> {
|
||||
export class LimitedHashTable<K, V> {
|
||||
private keyToValue: Map<K, V> = new Map();
|
||||
private valueToKey: Map<V, K> = new Map();
|
||||
private maxSize: number;
|
||||
private KeyQueneList: K[] = [];
|
||||
private ValueQueneList: V[] = [];
|
||||
|
||||
constructor(maxSize: number) {
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
resize(count: number) {
|
||||
this.maxSize = count;
|
||||
}
|
||||
|
||||
set(key: K, value: V): void {
|
||||
// const isExist = this.keyToValue.get(key);
|
||||
// if (isExist && isExist === value) {
|
||||
// return;
|
||||
// }
|
||||
this.keyToValue.set(key, value);
|
||||
this.valueToKey.set(value, key);
|
||||
if (this.KeyQueneList.length >= this.maxSize || this.ValueQueneList.length >= this.maxSize) {
|
||||
this.KeyQueneList.shift();
|
||||
this.ValueQueneList.shift();
|
||||
while (this.keyToValue.size !== this.valueToKey.size) {
|
||||
console.log('keyToValue.size !== valueToKey.size Error Atom');
|
||||
this.keyToValue.clear();
|
||||
this.valueToKey.clear();
|
||||
}
|
||||
// console.log('---------------');
|
||||
// console.log(this.keyToValue);
|
||||
// console.log(this.valueToKey);
|
||||
// console.log('---------------');
|
||||
while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) {
|
||||
//console.log(this.keyToValue.size > this.maxSize, this.valueToKey.size > this.maxSize);
|
||||
const oldestKey = this.keyToValue.keys().next().value;
|
||||
this.valueToKey.delete(this.keyToValue.get(oldestKey)!);
|
||||
this.keyToValue.delete(oldestKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,28 +46,97 @@ class LimitedHashTable<K, V> {
|
||||
return this.valueToKey.get(value);
|
||||
}
|
||||
|
||||
delete(key: K): void {
|
||||
deleteByValue(value: V): void {
|
||||
const key = this.valueToKey.get(value);
|
||||
if (key !== undefined) {
|
||||
this.keyToValue.delete(key);
|
||||
this.valueToKey.delete(value);
|
||||
}
|
||||
}
|
||||
|
||||
deleteByKey(key: K): void {
|
||||
const value = this.keyToValue.get(key);
|
||||
if (value !== undefined) {
|
||||
this.keyToValue.delete(key);
|
||||
this.valueToKey.delete(value);
|
||||
}
|
||||
}
|
||||
|
||||
getKeyList(): K[] {
|
||||
return Array.from(this.keyToValue.keys());
|
||||
}
|
||||
//获取最近刚写入的几个值
|
||||
getHeads(size: number): { key: K; value: V }[] | undefined {
|
||||
const keyList = this.getKeyList();
|
||||
if (keyList.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const result: { key: K; value: V }[] = [];
|
||||
const listSize = Math.min(size, keyList.length);
|
||||
for (let i = 0; i < listSize; i++) {
|
||||
const key = keyList[listSize - i];
|
||||
result.push({ key, value: this.keyToValue.get(key)! });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class MessageUniqueWrapper {
|
||||
private msgIdMap: LimitedHashTable<number, string> = new LimitedHashTable(1000);
|
||||
createMsg(MsgId: string) {
|
||||
const ShortId = parseInt(crypto.createHash('sha1').update('2345').digest('hex').slice(0, 8), 16);
|
||||
this.msgIdMap.set(ShortId, MsgId);
|
||||
return ShortId;
|
||||
private msgDataMap: LimitedHashTable<string, number>;
|
||||
private msgIdMap: LimitedHashTable<string, number>;
|
||||
constructor(maxMap: number = 1000) {
|
||||
this.msgIdMap = new LimitedHashTable<string, number>(maxMap);
|
||||
this.msgDataMap = new LimitedHashTable<string, number>(maxMap);
|
||||
}
|
||||
getMsgIdByShortId(ShortId: number) {
|
||||
return this.msgIdMap.getValue(ShortId);
|
||||
getRecentMsgIds(Peer: Peer, size: number): string[] {
|
||||
const heads = this.msgIdMap.getHeads(size);
|
||||
if (!heads) {
|
||||
return [];
|
||||
}
|
||||
const data = heads.map((t) => MessageUnique.getMsgIdAndPeerByShortId(t.value));
|
||||
const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid);
|
||||
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined);
|
||||
}
|
||||
getShortIdByMsgId(MsgId: string) {
|
||||
return this.msgIdMap.getKey(MsgId);
|
||||
createMsg(peer: Peer, msgId: string): number | undefined {
|
||||
const key = `${msgId}|${peer.chatType}|${peer.peerUid}`;
|
||||
const hash = crypto.createHash('md5').update(key);
|
||||
const shortId = hash.digest().readInt32BE(0);
|
||||
//减少性能损耗
|
||||
// const isExist = this.msgIdMap.getKey(shortId);
|
||||
// if (isExist && isExist === msgId) {
|
||||
// return shortId;
|
||||
// }
|
||||
this.msgIdMap.set(msgId, shortId);
|
||||
this.msgDataMap.set(key, shortId);
|
||||
return shortId;
|
||||
}
|
||||
|
||||
getMsgIdAndPeerByShortId(shortId: number): { MsgId: string; Peer: Peer } | undefined {
|
||||
const data = this.msgDataMap.getKey(shortId);
|
||||
if (data) {
|
||||
const [msgId, chatTypeStr, peerUid] = data.split('|');
|
||||
const peer: Peer = {
|
||||
chatType: parseInt(chatTypeStr),
|
||||
peerUid,
|
||||
guildId: '',
|
||||
};
|
||||
return { MsgId: msgId, Peer: peer };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getShortIdByMsgId(msgId: string): number | undefined {
|
||||
return this.msgIdMap.getValue(msgId);
|
||||
}
|
||||
getPeerByMsgId(msgId: string) {
|
||||
const shortId = this.msgIdMap.getValue(msgId);
|
||||
if (!shortId) return undefined;
|
||||
return this.getMsgIdAndPeerByShortId(shortId);
|
||||
}
|
||||
resize(maxSize: number): void {
|
||||
this.msgIdMap.resize(maxSize);
|
||||
this.msgDataMap.resize(maxSize);
|
||||
}
|
||||
}
|
||||
|
||||
export const MessageUnique = new MessageUniqueWrapper();
|
||||
export const MessageUnique: MessageUniqueWrapper = new MessageUniqueWrapper();
|
@@ -1,77 +1,56 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import { systemPlatform } from '@/common/utils/system';
|
||||
import { logError } from '@/common/utils/log';
|
||||
import { getDefaultQQVersionConfigInfo, getQQVersionConfigPath } from './helper';
|
||||
import AppidTable from '@/core/external/appid.json';
|
||||
import { log } from './log';
|
||||
|
||||
export const exePath = process.execPath;
|
||||
//基础目录获取
|
||||
export let QQMainPath = process.execPath;
|
||||
export let QQPackageInfoPath: string = path.join(path.dirname(QQMainPath), 'resources', 'app', 'package.json');
|
||||
export let QQVersionConfigPath: string | undefined = getQQVersionConfigPath(QQMainPath);
|
||||
|
||||
export const pkgInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'package.json');
|
||||
let configVersionInfoPath;
|
||||
//基础信息获取 无快更则启用默认模板填充
|
||||
export let isQuickUpdate: boolean = !!QQVersionConfigPath;
|
||||
export let QQVersionConfig: QQVersionConfigType = isQuickUpdate ? JSON.parse(fs.readFileSync(QQVersionConfigPath!).toString()) : getDefaultQQVersionConfigInfo();
|
||||
export let QQPackageInfo: QQPackageInfoType = JSON.parse(fs.readFileSync(QQPackageInfoPath).toString());
|
||||
export let { appid: QQVersionAppid, qua: QQVersionQua } = getAppidV2();
|
||||
|
||||
if (os.platform() !== 'linux') {
|
||||
configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json');
|
||||
} else {
|
||||
const userPath = os.homedir();
|
||||
const appDataPath = path.resolve(userPath, './.config/QQ');
|
||||
configVersionInfoPath = path.resolve(appDataPath, './versions/config.json');
|
||||
//基础函数
|
||||
export function getQQBuildStr() {
|
||||
return isQuickUpdate ? QQVersionConfig.buildId : QQPackageInfo.buildVersion;
|
||||
}
|
||||
|
||||
if (typeof configVersionInfoPath !== 'string') {
|
||||
throw new Error('Something went wrong when load QQ info path');
|
||||
export function getFullQQVesion() {
|
||||
return isQuickUpdate ? QQVersionConfig.curVersion : QQPackageInfo.version;
|
||||
}
|
||||
|
||||
export { configVersionInfoPath };
|
||||
|
||||
type QQPkgInfo = {
|
||||
version: string;
|
||||
buildVersion: string;
|
||||
platform: string;
|
||||
eleArch: string;
|
||||
export function requireMinNTQQBuild(buildStr: string) {
|
||||
return parseInt(getQQBuildStr()) >= parseInt(buildStr);
|
||||
}
|
||||
type QQVersionConfigInfo = {
|
||||
baseVersion: string;
|
||||
curVersion: string;
|
||||
prevVersion: string;
|
||||
onErrorVersions: Array<any>;
|
||||
buildId: string;
|
||||
//此方法不要直接使用
|
||||
export function getQUAInternal() {
|
||||
return systemPlatform === 'linux' ? `V1_LNX_NQ_${getFullQQVesion()}_${getQQBuildStr()}_GW_B` : `V1_WIN_NQ_${getFullQQVesion()}_${getQQBuildStr()}_GW_B`;
|
||||
}
|
||||
|
||||
let _qqVersionConfigInfo: QQVersionConfigInfo = {
|
||||
'baseVersion': '9.9.11-24568',
|
||||
'curVersion': '9.9.11-24568',
|
||||
'prevVersion': '',
|
||||
'onErrorVersions': [],
|
||||
'buildId': '24568'
|
||||
};
|
||||
|
||||
if (fs.existsSync(configVersionInfoPath)) {
|
||||
export function getAppidV2(): { appid: string, qua: string } {
|
||||
let appidTbale = AppidTable as unknown as QQAppidTableType;
|
||||
try {
|
||||
const _ =JSON.parse(fs.readFileSync(configVersionInfoPath).toString());
|
||||
_qqVersionConfigInfo = Object.assign(_qqVersionConfigInfo, _);
|
||||
} catch (e) {
|
||||
logError('Load QQ version config info failed, Use default version', e);
|
||||
let data = appidTbale[getFullQQVesion()];
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
log('[QQ版本兼容性检测] 版本兼容性不佳,可能会导致一些功能无法正常使用', e);
|
||||
}
|
||||
// 以下是兜底措施
|
||||
return { appid: systemPlatform === 'linux' ? '537237950' : '537237765', qua: getQUAInternal() };
|
||||
}
|
||||
|
||||
export const qqVersionConfigInfo: QQVersionConfigInfo = _qqVersionConfigInfo;
|
||||
//V1_WIN_NQ_9.9.11_24568_GW_B
|
||||
export const qqPkgInfo: QQPkgInfo = JSON.parse(fs.readFileSync(pkgInfoPath).toString());
|
||||
// platform_type: 3,
|
||||
// app_type: 4,
|
||||
// app_version: '9.9.9-23159',
|
||||
// qua: 'V1_WIN_NQ_9.9.9_23159_GW_B',
|
||||
// appid: '537213764',
|
||||
// app_version: '9.9.12-25765',
|
||||
// qua: 'V1_WIN_NQ_9.9.12_25765_GW_B',
|
||||
// appid: '537234702',
|
||||
// platVer: '10.0.26100',
|
||||
// clientVer: '9.9.9-23159',
|
||||
|
||||
// clientVer: '9.9.9-25765',
|
||||
// Linux
|
||||
// app_version: '3.2.9-24568',
|
||||
// qua: 'V1_LNX_NQ_3.2.9_24568_GW_B',
|
||||
|
||||
let _appid: string = '537226369'; // 默认为 Windows 平台的 appid
|
||||
if (systemPlatform === 'linux') {
|
||||
_appid = '537226441';
|
||||
}
|
||||
// todo: mac 平台的 appid
|
||||
export const appid = _appid;
|
||||
// app_version: '3.2.9-25765',
|
||||
// qua: 'V1_LNX_NQ_3.2.10_25765_GW_B',
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import fs from 'fs';
|
||||
import { encode, getDuration, getWavFileInfo, isWav } from 'silk-wasm';
|
||||
import { encode, getDuration, getWavFileInfo, isWav, isSilk } from 'silk-wasm';
|
||||
import fsPromise from 'fs/promises';
|
||||
import { log, logError } from './log';
|
||||
import path from 'node:path';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { getTempDir } from '@/common/utils/file';
|
||||
|
||||
@@ -63,10 +63,11 @@ export async function encodeSilk(filePath: string) {
|
||||
// }
|
||||
|
||||
try {
|
||||
const pttPath = path.join(TEMP_DIR, uuidv4());
|
||||
if (getFileHeader(filePath) !== '02232153494c4b') {
|
||||
const file = await fsPromise.readFile(filePath);
|
||||
const pttPath = path.join(TEMP_DIR, randomUUID());
|
||||
if (!isSilk(file)) {
|
||||
log(`语音文件${filePath}需要转换成silk`);
|
||||
const _isWav = await isWavFile(filePath);
|
||||
const _isWav = isWav(file);
|
||||
const pcmPath = pttPath + '.pcm';
|
||||
let sampleRate = 0;
|
||||
const convert = () => {
|
||||
@@ -96,7 +97,7 @@ export async function encodeSilk(filePath: string) {
|
||||
if (!_isWav) {
|
||||
input = await convert();
|
||||
} else {
|
||||
input = fs.readFileSync(filePath);
|
||||
input = file;
|
||||
const allowSampleRate = [8000, 12000, 16000, 24000, 32000, 44100, 48000];
|
||||
const { fmt } = getWavFileInfo(input);
|
||||
// log(`wav文件信息`, fmt)
|
||||
@@ -113,7 +114,7 @@ export async function encodeSilk(filePath: string) {
|
||||
duration: silk.duration / 1000
|
||||
};
|
||||
} else {
|
||||
const silk = fs.readFileSync(filePath);
|
||||
const silk = file;
|
||||
let duration = 0;
|
||||
try {
|
||||
duration = getDuration(silk) / 1000;
|
||||
|
@@ -1,449 +0,0 @@
|
||||
import { ElementType, FileElement, PicElement, PttElement, RawMessage, VideoElement } from '../../core/src/entities';
|
||||
|
||||
import sqlite3 from 'sqlite3';
|
||||
import { log, logDebug, logError } from '@/common/utils/log';
|
||||
import { NTQQMsgApi } from '@/core';
|
||||
import LRU from '@/common/utils/LRUCache';
|
||||
|
||||
export interface IRember {
|
||||
last_sent_time: number;
|
||||
join_time: number;
|
||||
user_id: number;
|
||||
}
|
||||
|
||||
|
||||
type DBMsg = {
|
||||
id: number,
|
||||
shortId: number,
|
||||
longId: string,
|
||||
seq: number,
|
||||
peerUid: string,
|
||||
chatType: number,
|
||||
}
|
||||
|
||||
type DBFile = {
|
||||
name: string; // 文件名
|
||||
path: string;
|
||||
url: string;
|
||||
size: number;
|
||||
uuid: string;
|
||||
msgId: string;
|
||||
elementId: string;
|
||||
element: PicElement | VideoElement | FileElement | PttElement;
|
||||
elementType: ElementType.PIC | ElementType.VIDEO | ElementType.FILE | ElementType.PTT;
|
||||
}
|
||||
|
||||
|
||||
class DBUtilBase {
|
||||
protected db: sqlite3.Database | undefined;
|
||||
|
||||
async init(dbPath: string) {
|
||||
if (this.db) {
|
||||
return;
|
||||
}
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
this.db = new sqlite3.Database(dbPath, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
|
||||
if (err) {
|
||||
logError('Could not connect to database', err);
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.createTable();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected createTable() {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
close() {
|
||||
this.db?.close();
|
||||
}
|
||||
}
|
||||
|
||||
class DBUtil extends DBUtilBase {
|
||||
private msgCache: Map<string | number, RawMessage> = new Map<string | number, RawMessage>();
|
||||
private globalMsgShortId = -2147483640;
|
||||
private groupIds: number[] = [];
|
||||
private LURCache = new LRU<number>();
|
||||
private LastSentCache = new (class {
|
||||
private cache: { gid: number; uid: number }[] = [];
|
||||
private maxSize: number;
|
||||
|
||||
constructor(maxSize: number = 5000) {
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
get(gid: number, uid: number): boolean {
|
||||
const exists = this.cache.some(
|
||||
(entry) => entry.gid === gid && entry.uid === uid
|
||||
);
|
||||
if (!exists) {
|
||||
this.cache.push({ gid, uid });
|
||||
if (this.cache.length > this.maxSize) {
|
||||
this.cache.shift();
|
||||
}
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
})();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const interval = 1000 * 60 * 10; // 10分钟清理一次缓存
|
||||
setInterval(() => {
|
||||
logDebug('清理消息缓存');
|
||||
this.msgCache.forEach((msg, key) => {
|
||||
if ((Date.now() - parseInt(msg.msgTime) * 1000) > interval) {
|
||||
this.msgCache.delete(key);
|
||||
}
|
||||
});
|
||||
}, interval);
|
||||
}
|
||||
|
||||
async init(dbPath: string) {
|
||||
await super.init(dbPath);
|
||||
this.globalMsgShortId = await this.getCurrentMaxShortId();
|
||||
|
||||
|
||||
// 初始化群缓存列表
|
||||
this.db!.serialize(() => {
|
||||
const sql = 'SELECT * FROM sqlite_master WHERE type=\'table\'';
|
||||
this.db!.all(sql, [], (err, rows: { name: string }[]) => {
|
||||
if (err) return logError(err);
|
||||
rows.forEach((row) => this.groupIds.push(parseInt(row.name)));
|
||||
//logDebug(`已加载 ${groupIds.length} 个群`);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
this.LURCache.on(async (node) => {
|
||||
const { value: time, groupId, userId } = node;
|
||||
|
||||
logDebug('插入发言时间', userId, groupId);
|
||||
await this.createGroupInfoTimeTableIfNotExist(groupId);
|
||||
|
||||
const method = await this.getDataSetMethod(groupId, userId);
|
||||
logDebug('插入发言时间方法判断', userId, groupId, method);
|
||||
|
||||
const sql =
|
||||
method == 'update'
|
||||
? `UPDATE "${groupId}" SET last_sent_time = ? WHERE user_id = ?`
|
||||
: `INSERT INTO "${groupId}" (last_sent_time, user_id) VALUES (?, ?)`;
|
||||
|
||||
this.db!.all(sql, [time, userId], (err) => {
|
||||
if (err) {
|
||||
return logError('插入/更新发言时间失败', userId, groupId);
|
||||
}
|
||||
logDebug('插入/更新发言时间成功', userId, groupId);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
async getDataSetMethod(groupId: number, userId: number) {
|
||||
// 缓存记录
|
||||
if (this.LastSentCache.get(groupId, userId)) {
|
||||
logDebug('缓存命中', userId, groupId);
|
||||
return 'update';
|
||||
}
|
||||
|
||||
// 数据库判断
|
||||
return new Promise<'insert' | 'update'>((resolve, reject) => {
|
||||
this.db!.all(
|
||||
`SELECT * FROM "${groupId}" WHERE user_id = ?`,
|
||||
[userId],
|
||||
(err, rows) => {
|
||||
if (err) {
|
||||
logError('查询发言时间存在失败', userId, groupId, err);
|
||||
return logError('插入发言时间失败', userId, groupId, err);
|
||||
}
|
||||
|
||||
if (rows.length === 0) {
|
||||
logDebug('查询发言时间不存在', userId, groupId);
|
||||
return resolve('insert');
|
||||
}
|
||||
|
||||
logDebug('查询发言时间存在', userId, groupId);
|
||||
resolve('update');
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
async createGroupInfoTimeTableIfNotExist(groupId: number) {
|
||||
const createTableSQL = (groupId: number) =>
|
||||
`CREATE TABLE IF NOT EXISTS "${groupId}" (
|
||||
user_id INTEGER,
|
||||
last_sent_time INTEGER,
|
||||
join_time INTEGER,
|
||||
PRIMARY KEY (user_id)
|
||||
);`;
|
||||
|
||||
if (this.groupIds.includes(groupId)) {
|
||||
return;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const sql = createTableSQL(groupId);
|
||||
this.db!.all(sql, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
this.groupIds.push(groupId);
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
protected createTable() {
|
||||
// 消息记录
|
||||
const createTableSQL = `
|
||||
CREATE TABLE IF NOT EXISTS msgs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
shortId INTEGER NOT NULL UNIQUE,
|
||||
longId TEXT NOT NULL UNIQUE,
|
||||
seq INTEGER NOT NULL,
|
||||
peerUid TEXT NOT NULL,
|
||||
chatType INTEGER NOT NULL
|
||||
)`;
|
||||
this.db!.run(createTableSQL, function (err) {
|
||||
if (err) {
|
||||
logError('Could not create table msgs', err.stack);
|
||||
}
|
||||
});
|
||||
|
||||
// 文件缓存
|
||||
const createFileTableSQL = `
|
||||
CREATE TABLE IF NOT EXISTS files (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
path TEXT NOT NULL,
|
||||
url TEXT,
|
||||
size INTEGER NOT NULL,
|
||||
uuid TEXT,
|
||||
elementType INTEGER,
|
||||
element TEXT NOT NULL,
|
||||
elementId TEXT NOT NULL,
|
||||
msgId TEXT NOT NULL
|
||||
)`;
|
||||
this.db!.run(createFileTableSQL, function (err) {
|
||||
if (err) {
|
||||
logError('Could not create table files', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async getCurrentMaxShortId() {
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
this.db!.get('SELECT MAX(shortId) as maxId FROM msgs', (err, row: { maxId: number }) => {
|
||||
if (err) {
|
||||
logDebug('Could not get max short id, Use default -2147483640', err);
|
||||
return resolve(-2147483640);
|
||||
}
|
||||
logDebug('数据库中消息最大短id', row?.maxId);
|
||||
resolve(row?.maxId ?? -2147483640);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async getMsg(query: string, params: any[]) {
|
||||
const stmt = this.db!.prepare(query);
|
||||
return new Promise<RawMessage | null>((resolve, reject) => {
|
||||
stmt.get(...params, (err: any, row: DBMsg) => {
|
||||
// log("getMsg", row, err);
|
||||
if (err) {
|
||||
logError('Could not get msg', err, query, params);
|
||||
return resolve(null);
|
||||
}
|
||||
if (!row) {
|
||||
// logDebug('不存在数据库中的消息,不进行处理', query, params);
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
const msgId = row.longId;
|
||||
NTQQMsgApi.getMsgsByMsgId({ peerUid: row.peerUid, chatType: row.chatType }, [msgId]).then(res => {
|
||||
const msg = res.msgList[0];
|
||||
if (!msg) {
|
||||
resolve(null);
|
||||
return;
|
||||
}
|
||||
msg.id = row.shortId;
|
||||
resolve(msg);
|
||||
}).catch(e => {
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async getMsgByShortId(shortId: number): Promise<RawMessage | null> {
|
||||
if (this.msgCache.has(shortId)) {
|
||||
return this.msgCache.get(shortId)!;
|
||||
}
|
||||
const getStmt = 'SELECT * FROM msgs WHERE shortId = ?';
|
||||
return this.getMsg(getStmt, [shortId]);
|
||||
}
|
||||
|
||||
async getMsgByLongId(longId: string): Promise<RawMessage | null> {
|
||||
if (this.msgCache.has(longId)) {
|
||||
return this.msgCache.get(longId)!;
|
||||
}
|
||||
return this.getMsg('SELECT * FROM msgs WHERE longId = ?', [longId]);
|
||||
}
|
||||
|
||||
async getMsgBySeq(peerUid: string, seq: string): Promise<RawMessage | null> {
|
||||
const stmt = 'SELECT * FROM msgs WHERE peerUid = ? AND seq = ?';
|
||||
return this.getMsg(stmt, [peerUid, seq]);
|
||||
}
|
||||
|
||||
async addMsg(msg: RawMessage, update = true): Promise<number> {
|
||||
const existMsg = await this.getMsgByLongId(msg.msgId);
|
||||
if (existMsg) {
|
||||
// logDebug('消息已存在,更新数据库', msg.msgId);
|
||||
if (update) this.updateMsg(msg).then();
|
||||
return existMsg.id!;
|
||||
}
|
||||
const stmt = this.db!.prepare('INSERT INTO msgs (shortId, longId, seq, peerUid, chatType) VALUES (?, ?, ?, ?, ?)');
|
||||
// const runAsync = promisify(stmt.run.bind(stmt));
|
||||
const shortId = ++this.globalMsgShortId;
|
||||
msg.id = shortId;
|
||||
//logDebug(`记录消息到数据库, 消息长id: ${msg.msgId}, 短id: ${msg.id}`);
|
||||
this.msgCache.set(shortId, msg);
|
||||
this.msgCache.set(msg.msgId, msg);
|
||||
stmt.run(this.globalMsgShortId, msg.msgId, msg.msgSeq.toString(), msg.peerUid, msg.chatType, (err: any) => {
|
||||
if (err) {
|
||||
if (err.errno === 19) {
|
||||
this.getMsgByLongId(msg.msgId).then((msg: RawMessage | null) => {
|
||||
if (msg) {
|
||||
this.msgCache.set(shortId, msg);
|
||||
this.msgCache.set(msg.msgId, msg);
|
||||
// logDebug('获取消息短id成功', msg.id);
|
||||
} else {
|
||||
logError('db could not get msg by long id', err);
|
||||
}
|
||||
}).catch(e => logError('db getMsgByLongId error', e));
|
||||
} else {
|
||||
logError('db could not add msg', err);
|
||||
}
|
||||
}
|
||||
});
|
||||
return shortId;
|
||||
}
|
||||
|
||||
async updateMsg(msg: RawMessage) {
|
||||
const existMsg = this.msgCache.get(msg.msgId);
|
||||
if (existMsg) {
|
||||
Object.assign(existMsg, msg);
|
||||
}
|
||||
//logDebug(`更新消息, shortId:${msg.id}, seq: ${msg.msgSeq}, msgId: ${msg.msgId}`);
|
||||
const stmt = this.db!.prepare('UPDATE msgs SET seq=? WHERE longId=?');
|
||||
stmt.run(msg.msgSeq, msg.msgId, (err: any) => {
|
||||
if (err) {
|
||||
logError('updateMsg db error', err);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async addFileCache(file: DBFile) {
|
||||
const stmt = this.db!.prepare('INSERT INTO files (name, path, url, size, uuid, elementType ,element, elementId, msgId) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
||||
return new Promise((resolve, reject) => {
|
||||
stmt.run(file.name, file.path, file.url, file.size, file.uuid,
|
||||
file.elementType,
|
||||
JSON.stringify(file.element),
|
||||
file.elementId,
|
||||
file.msgId,
|
||||
function (err: any) {
|
||||
if (err) {
|
||||
logError('db could not add file', err);
|
||||
reject(err);
|
||||
}
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async getFileCache(query: string, params: any[]) {
|
||||
const stmt = this.db!.prepare(query);
|
||||
return new Promise<DBFile | null>((resolve, reject) => {
|
||||
stmt.get(...params, (err: any, row: DBFile & { element: string }) => {
|
||||
if (err) {
|
||||
logError('db could not get file cache', err);
|
||||
reject(err);
|
||||
}
|
||||
if (row) {
|
||||
row.element = JSON.parse(row.element);
|
||||
}
|
||||
resolve(row);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async getFileCacheByName(name: string): Promise<DBFile | null> {
|
||||
return this.getFileCache('SELECT * FROM files WHERE name = ?', [name]);
|
||||
}
|
||||
|
||||
async getFileCacheByUuid(uuid: string): Promise<DBFile | null> {
|
||||
return this.getFileCache('SELECT * FROM files WHERE uuid = ?', [uuid]);
|
||||
}
|
||||
|
||||
// todo: 是否所有的文件都有uuid?语音消息有没有uuid?
|
||||
async updateFileCache(file: DBFile) {
|
||||
const stmt = this.db!.prepare('UPDATE files SET path = ?, url = ? WHERE uuid = ?');
|
||||
return new Promise((resolve, reject) => {
|
||||
stmt.run(file.path, file.url, file.uuid, function (err: any) {
|
||||
if (err) {
|
||||
logError('db could not update file cache', err);
|
||||
reject(err);
|
||||
}
|
||||
resolve(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async getLastSentTimeAndJoinTime(
|
||||
groupId: number
|
||||
): Promise<IRember[]> {
|
||||
logDebug('读取发言时间', groupId);
|
||||
return new Promise<IRember[]>((resolve, reject) => {
|
||||
this.db!.all(`SELECT * FROM "${groupId}" `, (err, rows: IRember[]) => {
|
||||
if (err) {
|
||||
logError('查询发言时间失败', groupId);
|
||||
return resolve([]);
|
||||
}
|
||||
logDebug('查询发言时间成功', groupId, rows);
|
||||
resolve(rows);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
insertLastSentTime(
|
||||
groupId: number,
|
||||
userId: number,
|
||||
time: number
|
||||
) {
|
||||
this.LURCache.set(groupId, userId, time);
|
||||
}
|
||||
async insertJoinTime(
|
||||
groupId: number,
|
||||
userId: number,
|
||||
time: number
|
||||
) {
|
||||
await this.createGroupInfoTimeTableIfNotExist(groupId);
|
||||
this.db!.all(
|
||||
`INSERT OR REPLACE INTO "${groupId}" (user_id, last_sent_time, join_time) VALUES (?,?,?)`,
|
||||
[userId, time, time],
|
||||
(err) => {
|
||||
if (err)
|
||||
logError(err),
|
||||
Promise.reject(),
|
||||
logError('插入入群时间失败', userId, groupId);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const dbUtil = new DBUtil();
|
@@ -4,9 +4,8 @@ import crypto from 'crypto';
|
||||
import util from 'util';
|
||||
import path from 'node:path';
|
||||
import { log, logError } from './log';
|
||||
import { dbUtil } from '@/common/utils/db';
|
||||
import * as fileType from 'file-type';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { napCatCore } from '@/core';
|
||||
|
||||
export const getNapCatDir = () => {
|
||||
@@ -148,6 +147,8 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
|
||||
};
|
||||
if (typeof options === 'string') {
|
||||
url = options;
|
||||
const host = new URL(url).hostname;
|
||||
headers['Host'] = host;
|
||||
} else {
|
||||
url = options.url;
|
||||
if (options.headers) {
|
||||
@@ -158,7 +159,12 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
|
||||
}
|
||||
}
|
||||
}
|
||||
const fetchRes = await fetch(url, { headers });
|
||||
const fetchRes = await fetch(url, { headers }).catch((err) => {
|
||||
if (err.cause) {
|
||||
throw err.cause;
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
if (!fetchRes.ok) throw new Error(`下载文件失败: ${fetchRes.statusText}`);
|
||||
|
||||
const blob = await fetchRes.blob();
|
||||
@@ -185,7 +191,7 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
|
||||
isLocal: false
|
||||
};
|
||||
if (!fileName) {
|
||||
fileName = uuidv4();
|
||||
fileName = randomUUID();
|
||||
}
|
||||
let filePath = path.join(getTempDir(), fileName);
|
||||
let url = null;
|
||||
@@ -228,7 +234,7 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
|
||||
}
|
||||
fileName = fileName.replace(/[/\\:*?"<>|]/g, '_');
|
||||
res.fileName = fileName;
|
||||
filePath = path.join(getTempDir(), uuidv4() + fileName);
|
||||
filePath = path.join(getTempDir(), randomUUID() + fileName);
|
||||
fs.writeFileSync(filePath, buffer);
|
||||
} catch (e: any) {
|
||||
res.errMsg = `${url}下载失败,` + e.toString();
|
||||
@@ -244,13 +250,14 @@ export async function uri2local(uri: string, fileName: string | null = null): Pr
|
||||
} else {
|
||||
filePath = pathname;
|
||||
}
|
||||
} else {
|
||||
const cache = await dbUtil.getFileCacheByName(uri);
|
||||
if (cache) {
|
||||
filePath = cache.path;
|
||||
} else {
|
||||
filePath = uri;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// const cache = await dbUtil.getFileCacheByName(uri);
|
||||
// if (cache) {
|
||||
// filePath = cache.path;
|
||||
// } else {
|
||||
// filePath = uri;
|
||||
// }
|
||||
}
|
||||
|
||||
res.isLocal = true;
|
||||
|
@@ -1,17 +1,58 @@
|
||||
import crypto from 'node:crypto';
|
||||
import path from 'node:path';
|
||||
import fs from 'fs/promises';
|
||||
import fs from 'fs';
|
||||
import { log, logDebug } from './log';
|
||||
import { dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import * as fsPromise from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
//下面这个类是用于将uid+msgid合并的类
|
||||
export class UUIDConverter {
|
||||
static encode(highStr: string, lowStr: string): string {
|
||||
const high = BigInt(highStr);
|
||||
const low = BigInt(lowStr);
|
||||
const highHex = high.toString(16).padStart(16, '0');
|
||||
const lowHex = low.toString(16).padStart(16, '0');
|
||||
const combinedHex = highHex + lowHex;
|
||||
const uuid = `${combinedHex.substring(0, 8)}-${combinedHex.substring(8, 12)}-${combinedHex.substring(12, 16)}-${combinedHex.substring(16, 20)}-${combinedHex.substring(20)}`;
|
||||
return uuid;
|
||||
}
|
||||
static decode(uuid: string): { high: string, low: string } {
|
||||
const hex = uuid.replace(/-/g, '');
|
||||
const high = BigInt('0x' + hex.substring(0, 16));
|
||||
const low = BigInt('0x' + hex.substring(16));
|
||||
return { high: high.toString(), low: low.toString() };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function sleep(ms: number): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export function PromiseTimer<T>(promise: Promise<T>, ms: number): Promise<T> {
|
||||
const timeoutPromise = new Promise<T>((_, reject) =>
|
||||
setTimeout(() => reject(new Error('PromiseTimer: Operation timed out')), ms)
|
||||
);
|
||||
return Promise.race([promise, timeoutPromise]);
|
||||
}
|
||||
export async function runAllWithTimeout<T>(tasks: Promise<T>[], timeout: number): Promise<T[]> {
|
||||
const wrappedTasks = tasks.map(task =>
|
||||
PromiseTimer(task, timeout).then(
|
||||
result => ({ status: 'fulfilled', value: result }),
|
||||
error => ({ status: 'rejected', reason: error })
|
||||
)
|
||||
);
|
||||
const results = await Promise.all(wrappedTasks);
|
||||
return results
|
||||
.filter(result => result.status === 'fulfilled')
|
||||
.map(result => (result as { status: 'fulfilled'; value: T }).value);
|
||||
}
|
||||
|
||||
export function getMd5(s: string) {
|
||||
|
||||
const h = crypto.createHash('md5');
|
||||
@@ -89,7 +130,36 @@ export function CacheClassFuncAsync(ttl: number = 3600 * 1000, customKey: string
|
||||
}
|
||||
return logExecutionTime;
|
||||
}
|
||||
|
||||
export function CacheClassFuncAsyncExtend(ttl: number = 3600 * 1000, customKey: string = '', checker: any = (...data: any[]) => { return true; }) {
|
||||
//console.log('CacheClassFuncAsync', ttl, customKey);
|
||||
function logExecutionTime(target: any, methodName: string, descriptor: PropertyDescriptor) {
|
||||
//console.log('logExecutionTime', target, methodName, descriptor);
|
||||
const cache = new Map<string, { expiry: number; value: any }>();
|
||||
const originalMethod = descriptor.value;
|
||||
descriptor.value = async function (...args: any[]) {
|
||||
const key = `${customKey}${String(methodName)}.(${args.map(arg => JSON.stringify(arg)).join(', ')})`;
|
||||
cache.forEach((value, key) => {
|
||||
if (value.expiry < Date.now()) {
|
||||
cache.delete(key);
|
||||
}
|
||||
});
|
||||
const cachedValue = cache.get(key);
|
||||
if (cachedValue && cachedValue.expiry > Date.now()) {
|
||||
return cachedValue.value;
|
||||
}
|
||||
// const start = Date.now();
|
||||
const result = await originalMethod.apply(this, args);
|
||||
if (!checker(...args, result)) {
|
||||
return result;//丢弃缓存
|
||||
}
|
||||
// const end = Date.now();
|
||||
// console.log(`Method ${methodName} executed in ${end - start} ms.`);
|
||||
cache.set(key, { expiry: Date.now() + ttl, value: result });
|
||||
return result;
|
||||
};
|
||||
}
|
||||
return logExecutionTime;
|
||||
}
|
||||
// export function CacheClassFuncAsync(ttl: number = 3600 * 1000, customKey: string = ''): any {
|
||||
// const cache = new Map<string, { expiry: number; value: any }>();
|
||||
|
||||
@@ -235,14 +305,14 @@ export function migrateConfig(oldConfig: any) {
|
||||
}
|
||||
// 升级旧的配置到新的
|
||||
export async function UpdateConfig() {
|
||||
const configFiles = await fs.readdir(path.join(__dirname, 'config'));
|
||||
const configFiles = await fsPromise.readdir(path.join(__dirname, 'config'));
|
||||
for (const file of configFiles) {
|
||||
if (file.match(/^onebot11_\d+.json$/)) {
|
||||
const CurrentConfig = JSON.parse(await fs.readFile(path.join(__dirname, 'config', file), 'utf8'));
|
||||
const CurrentConfig = JSON.parse(await fsPromise.readFile(path.join(__dirname, 'config', file), 'utf8'));
|
||||
if (isValidOldConfig(CurrentConfig)) {
|
||||
log('正在迁移旧配置到新配置 File:', file);
|
||||
const NewConfig = migrateConfig(CurrentConfig);
|
||||
await fs.writeFile(path.join(__dirname, 'config', file), JSON.stringify(NewConfig, null, 2));
|
||||
await fsPromise.writeFile(path.join(__dirname, 'config', file), JSON.stringify(NewConfig, null, 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,7 +332,56 @@ export function isEqual(obj1: any, obj2: any) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
|
||||
if (os.platform() === 'linux') {
|
||||
return {
|
||||
baseVersion: '3.2.12-26702',
|
||||
curVersion: '3.2.12-26702',
|
||||
prevVersion: '',
|
||||
onErrorVersions: [],
|
||||
buildId: '26702'
|
||||
};
|
||||
}
|
||||
return {
|
||||
baseVersion: '9.9.15-26702',
|
||||
curVersion: '9.9.15-26702',
|
||||
prevVersion: '',
|
||||
onErrorVersions: [],
|
||||
buildId: '26702'
|
||||
};
|
||||
}
|
||||
export async function promisePipeline(promises: Promise<any>[], callback: (result: any) => boolean): Promise<void> {
|
||||
let callbackCalled = false;
|
||||
for (const promise of promises) {
|
||||
if (callbackCalled) break;
|
||||
try {
|
||||
const result = await promise;
|
||||
if (!callbackCalled) {
|
||||
callbackCalled = callback(result);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in promise pipeline:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getQQVersionConfigPath(exePath: string = ""): string | undefined {
|
||||
let configVersionInfoPath;
|
||||
if (os.platform() !== 'linux') {
|
||||
configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json');
|
||||
} else {
|
||||
const userPath = os.homedir();
|
||||
const appDataPath = path.resolve(userPath, './.config/QQ');
|
||||
configVersionInfoPath = path.resolve(appDataPath, './versions/config.json');
|
||||
}
|
||||
if (typeof configVersionInfoPath !== 'string') {
|
||||
return undefined;
|
||||
}
|
||||
if (!fs.existsSync(configVersionInfoPath)) {
|
||||
return undefined;
|
||||
}
|
||||
return configVersionInfoPath;
|
||||
}
|
||||
export async function deleteOldFiles(directoryPath: string, daysThreshold: number) {
|
||||
try {
|
||||
const files = await fsPromise.readdir(directoryPath);
|
||||
|
@@ -91,8 +91,10 @@ export function enableConsoleLog(enable: boolean) {
|
||||
function formatMsg(msg: any[]) {
|
||||
let logMsg = '';
|
||||
for (const msgItem of msg) {
|
||||
// 判断是否是对象
|
||||
if (typeof msgItem === 'object') {
|
||||
if (msgItem instanceof Error) { // 判断是否是错误
|
||||
logMsg += msgItem.stack + ' ';
|
||||
continue;
|
||||
} else if (typeof msgItem === 'object') { // 判断是否是对象
|
||||
const obj = JSON.parse(JSON.stringify(msgItem, null, 2));
|
||||
logMsg += JSON.stringify(truncateString(obj)) + ' ';
|
||||
continue;
|
||||
|
@@ -1,15 +1,13 @@
|
||||
import https from 'node:https';
|
||||
import http from 'node:http';
|
||||
import fs, { readFileSync } from 'node:fs';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { NTQQUserApi } from '@/core';
|
||||
import path from 'node:path';
|
||||
import { request } 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) => {
|
||||
const req = client.get(url, (res) => {
|
||||
let cookies: { [key: string]: string } = {};
|
||||
const handleRedirect = (res: http.IncomingMessage) => {
|
||||
//console.log(res.headers.location);
|
||||
@@ -20,6 +18,8 @@ export class RequestUtil {
|
||||
// 合并重定向过程中的cookies
|
||||
cookies = { ...cookies, ...redirectCookies };
|
||||
resolve(cookies);
|
||||
}).catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
resolve(cookies);
|
||||
@@ -43,9 +43,10 @@ export class RequestUtil {
|
||||
}
|
||||
});
|
||||
}
|
||||
}).on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
req.on('error', (error: any) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -173,6 +174,7 @@ export class RequestUtil {
|
||||
});
|
||||
|
||||
req.on('error', (error) => {
|
||||
reject(error);
|
||||
console.error('Error during upload:', error);
|
||||
});
|
||||
|
||||
@@ -188,4 +190,4 @@ export class RequestUtil {
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { networkInterfaces } from 'os';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { randomUUID } from 'crypto';
|
||||
|
||||
// 缓解Win7设备兼容性问题
|
||||
let osName: string;
|
||||
@@ -30,7 +30,7 @@ export async function getMachineId(): Promise<string> {
|
||||
if (!machineId) {
|
||||
machineId = (async () => {
|
||||
const id = await getMacMachineId();
|
||||
return id || uuidv4(); // fallback, generate a UUID
|
||||
return id || randomUUID(); // fallback, generate a UUID
|
||||
})();
|
||||
}
|
||||
|
||||
|
@@ -1,31 +1,17 @@
|
||||
/**
|
||||
* 运行时类型转换与检查类
|
||||
*/
|
||||
export class TypeCheck {
|
||||
static isEmpty(value: any): boolean {
|
||||
return value === null || value === undefined || value === '' ||
|
||||
(Array.isArray(value) && value.length === 0) || (typeof value === 'object' && Object.keys(value).length === 0);
|
||||
}
|
||||
//QQVersionType
|
||||
type QQPackageInfoType = {
|
||||
version: string;
|
||||
buildVersion: string;
|
||||
platform: string;
|
||||
eleArch: string;
|
||||
}
|
||||
|
||||
export class TypeConvert {
|
||||
static toNumber(value: any): number {
|
||||
const num = Number(value);
|
||||
if (isNaN(num)) {
|
||||
throw new Error(`无法将输入转换为数字: ${value}`);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
static toString(value: any): string {
|
||||
return String(value);
|
||||
}
|
||||
|
||||
static toBoolean(value: any): boolean {
|
||||
return Boolean(value);
|
||||
}
|
||||
|
||||
static toArray(value: any): any[] {
|
||||
return Array.isArray(value) ? value : [value];
|
||||
}
|
||||
type QQVersionConfigType = {
|
||||
baseVersion: string;
|
||||
curVersion: string;
|
||||
prevVersion: string;
|
||||
onErrorVersions: Array<any>;
|
||||
buildId: string;
|
||||
}
|
||||
type QQAppidTableType = {
|
||||
[key: string]: { appid: string, qua: string };
|
||||
}
|
@@ -4,10 +4,10 @@ export async function checkVersion(): Promise<string> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const MirrorList =
|
||||
[
|
||||
'https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json',
|
||||
'https://fastly.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
|
||||
'https://gcore.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json',
|
||||
'https://cdn.jsdelivr.us/gh/NapNeko/NapCatQQ@main/package.json',
|
||||
'https://jsd.cdn.zzko.cn/gh/NapNeko/NapCatQQ@main/package.json'
|
||||
'https://cdn.jsdelivr.net/gh/NapNeko/NapCatQQ@main/package.json'
|
||||
];
|
||||
let version = undefined;
|
||||
for (const url of MirrorList) {
|
||||
|
File diff suppressed because one or more lines are too long
1
src/core
1
src/core
Submodule src/core deleted from eec6f2a5c0
@@ -1,14 +0,0 @@
|
||||
interface IDependsAdapter {
|
||||
onMSFStatusChange(arg1: number, arg2: number): void;
|
||||
onMSFSsoError(args: unknown): void;
|
||||
getGroupCode(args: unknown): void;
|
||||
}
|
||||
export interface NodeIDependsAdapter extends IDependsAdapter {
|
||||
new (adapter: IDependsAdapter): NodeIDependsAdapter;
|
||||
}
|
||||
export declare class DependsAdapter implements IDependsAdapter {
|
||||
onMSFStatusChange(arg1: number, arg2: number): void;
|
||||
onMSFSsoError(args: unknown): void;
|
||||
getGroupCode(args: unknown): void;
|
||||
}
|
||||
export {};
|
@@ -1 +0,0 @@
|
||||
var _0xcc391f=_0x1dbc;function _0x52b6(){var _0x415ac1=['getGroupCode','688761AQTgdS','onMSFStatusChange','4780153elzsdz','104jUCcYC','335227uPPfBg','976830pbzGRQ','5625055eKGJTT','5073624gTujzP','6DxfcvM','5630040LsNiIa'];_0x52b6=function(){return _0x415ac1;};return _0x52b6();}function _0x1dbc(_0x2e7338,_0x3c3487){var _0x52b69c=_0x52b6();return _0x1dbc=function(_0x1dbc94,_0x5792b5){_0x1dbc94=_0x1dbc94-0xbe;var _0x2be02b=_0x52b69c[_0x1dbc94];return _0x2be02b;},_0x1dbc(_0x2e7338,_0x3c3487);}(function(_0x1457cf,_0x101874){var _0x174c51=_0x1dbc,_0x5a350c=_0x1457cf();while(!![]){try{var _0x4060d=parseInt(_0x174c51(0xc4))/0x1+parseInt(_0x174c51(0xc5))/0x2*(parseInt(_0x174c51(0xc8))/0x3)+parseInt(_0x174c51(0xc7))/0x4+-parseInt(_0x174c51(0xc6))/0x5+-parseInt(_0x174c51(0xbe))/0x6+-parseInt(_0x174c51(0xc2))/0x7+parseInt(_0x174c51(0xc3))/0x8*(parseInt(_0x174c51(0xc0))/0x9);if(_0x4060d===_0x101874)break;else _0x5a350c['push'](_0x5a350c['shift']());}catch(_0x33aafc){_0x5a350c['push'](_0x5a350c['shift']());}}}(_0x52b6,0xca6b6));export class DependsAdapter{[_0xcc391f(0xc1)](_0x160645,_0x5838f1){}['onMSFSsoError'](_0x502d99){}[_0xcc391f(0xbf)](_0x45bdb6){}}
|
@@ -1,14 +0,0 @@
|
||||
interface IDispatcherAdapter {
|
||||
dispatchRequest(arg: unknown): void;
|
||||
dispatchCall(arg: unknown): void;
|
||||
dispatchCallWithJson(arg: unknown): void;
|
||||
}
|
||||
export interface NodeIDispatcherAdapter extends IDispatcherAdapter {
|
||||
new (adapter: IDispatcherAdapter): NodeIDispatcherAdapter;
|
||||
}
|
||||
export declare class DispatcherAdapter implements IDispatcherAdapter {
|
||||
dispatchRequest(arg: unknown): void;
|
||||
dispatchCall(arg: unknown): void;
|
||||
dispatchCallWithJson(arg: unknown): void;
|
||||
}
|
||||
export {};
|
@@ -1 +0,0 @@
|
||||
var _0x24dc95=_0x585a;function _0x585a(_0x98cee9,_0x215212){var _0x1e1827=_0x1e18();return _0x585a=function(_0x585a22,_0x290a2f){_0x585a22=_0x585a22-0x146;var _0x206eae=_0x1e1827[_0x585a22];return _0x206eae;},_0x585a(_0x98cee9,_0x215212);}(function(_0x2602b9,_0x23ed1f){var _0x29821b=_0x585a,_0xf0f43=_0x2602b9();while(!![]){try{var _0x39040d=parseInt(_0x29821b(0x14b))/0x1+parseInt(_0x29821b(0x149))/0x2+-parseInt(_0x29821b(0x150))/0x3*(-parseInt(_0x29821b(0x14f))/0x4)+-parseInt(_0x29821b(0x14d))/0x5+-parseInt(_0x29821b(0x146))/0x6+parseInt(_0x29821b(0x147))/0x7+-parseInt(_0x29821b(0x148))/0x8;if(_0x39040d===_0x23ed1f)break;else _0xf0f43['push'](_0xf0f43['shift']());}catch(_0x4448d5){_0xf0f43['push'](_0xf0f43['shift']());}}}(_0x1e18,0x9a7c0));function _0x1e18(){var _0x1859c2=['1072386zxkYvO','1702120yxKQxg','594584YdGdNa','584644jnxrqu','dispatchCallWithJson','197388uWeHvx','dispatchRequest','1250350nrYfbC','dispatchCall','8gExNtR','604533fSuWEr'];_0x1e18=function(){return _0x1859c2;};return _0x1e18();}export class DispatcherAdapter{[_0x24dc95(0x14c)](_0x251321){}[_0x24dc95(0x14e)](_0x525c84){}[_0x24dc95(0x14a)](_0x222c8d){}}
|
@@ -1,24 +0,0 @@
|
||||
interface IGlobalAdapter {
|
||||
onLog(...args: unknown[]): void;
|
||||
onGetSrvCalTime(...args: unknown[]): void;
|
||||
onShowErrUITips(...args: unknown[]): void;
|
||||
fixPicImgType(...args: unknown[]): void;
|
||||
getAppSetting(...args: unknown[]): void;
|
||||
onInstallFinished(...args: unknown[]): void;
|
||||
onUpdateGeneralFlag(...args: unknown[]): void;
|
||||
onGetOfflineMsg(...args: unknown[]): void;
|
||||
}
|
||||
export interface NodeIGlobalAdapter extends IGlobalAdapter {
|
||||
new (adapter: IGlobalAdapter): NodeIGlobalAdapter;
|
||||
}
|
||||
export declare class GlobalAdapter implements IGlobalAdapter {
|
||||
onLog(...args: unknown[]): void;
|
||||
onGetSrvCalTime(...args: unknown[]): void;
|
||||
onShowErrUITips(...args: unknown[]): void;
|
||||
fixPicImgType(...args: unknown[]): void;
|
||||
getAppSetting(...args: unknown[]): void;
|
||||
onInstallFinished(...args: unknown[]): void;
|
||||
onUpdateGeneralFlag(...args: unknown[]): void;
|
||||
onGetOfflineMsg(...args: unknown[]): void;
|
||||
}
|
||||
export {};
|
@@ -1 +0,0 @@
|
||||
function _0x5cfc(_0x1a414e,_0x2b6945){var _0x4561bc=_0x4561();return _0x5cfc=function(_0x5cfc0a,_0x39f2fa){_0x5cfc0a=_0x5cfc0a-0xdc;var _0x29bccb=_0x4561bc[_0x5cfc0a];return _0x29bccb;},_0x5cfc(_0x1a414e,_0x2b6945);}var _0x13ad04=_0x5cfc;(function(_0x39368b,_0x1c4f7a){var _0x240e55=_0x5cfc,_0xa55402=_0x39368b();while(!![]){try{var _0x19ea16=parseInt(_0x240e55(0xe7))/0x1+parseInt(_0x240e55(0xe1))/0x2+-parseInt(_0x240e55(0xe4))/0x3*(-parseInt(_0x240e55(0xe6))/0x4)+parseInt(_0x240e55(0xdf))/0x5+-parseInt(_0x240e55(0xdc))/0x6+-parseInt(_0x240e55(0xe2))/0x7+parseInt(_0x240e55(0xe3))/0x8;if(_0x19ea16===_0x1c4f7a)break;else _0xa55402['push'](_0xa55402['shift']());}catch(_0x1e89fd){_0xa55402['push'](_0xa55402['shift']());}}}(_0x4561,0x3ebcd));function _0x4561(){var _0x4c7d39=['1071210VcxehC','818592ZGlgqp','126aNfYQt','onUpdateGeneralFlag','47692ndSNHo','178420OjINhX','2616834RVkoeU','onLog','onShowErrUITips','303535qZPoZF','onGetOfflineMsg','7850wMzNtw'];_0x4561=function(){return _0x4c7d39;};return _0x4561();}export class GlobalAdapter{[_0x13ad04(0xdd)](..._0x3e119a){}['onGetSrvCalTime'](..._0x18ecc5){}[_0x13ad04(0xde)](..._0x100e62){}['fixPicImgType'](..._0x2cde61){}['getAppSetting'](..._0x33e2eb){}['onInstallFinished'](..._0x223f3d){}[_0x13ad04(0xe5)](..._0x43f8e2){}[_0x13ad04(0xe0)](..._0x907c35){}}
|
@@ -1 +0,0 @@
|
||||
(function(_0x3bd320,_0x59cad1){var _0x5b8350=_0x2e39,_0x5f2fbc=_0x3bd320();while(!![]){try{var _0x48276f=-parseInt(_0x5b8350(0x129))/0x1+parseInt(_0x5b8350(0x12a))/0x2+-parseInt(_0x5b8350(0x12c))/0x3+-parseInt(_0x5b8350(0x12b))/0x4*(parseInt(_0x5b8350(0x12f))/0x5)+parseInt(_0x5b8350(0x127))/0x6*(parseInt(_0x5b8350(0x12d))/0x7)+parseInt(_0x5b8350(0x126))/0x8+-parseInt(_0x5b8350(0x12e))/0x9*(-parseInt(_0x5b8350(0x128))/0xa);if(_0x48276f===_0x59cad1)break;else _0x5f2fbc['push'](_0x5f2fbc['shift']());}catch(_0x5c216f){_0x5f2fbc['push'](_0x5f2fbc['shift']());}}}(_0xf9fd,0xae9e1));function _0x2e39(_0x4fe14e,_0x2ce9ef){var _0xf9fd06=_0xf9fd();return _0x2e39=function(_0x2e3985,_0x1300b5){_0x2e3985=_0x2e3985-0x126;var _0x458d58=_0xf9fd06[_0x2e3985];return _0x458d58;},_0x2e39(_0x4fe14e,_0x2ce9ef);}export*from'./NodeIDependsAdapter';export*from'./NodeIDispatcherAdapter';function _0xf9fd(){var _0x113674=['9Psfnwm','1255gvGSSW','8940456QkCTfV','546MtNrzV','3069540AuWaws','149260sAWoZS','472274vEalJO','14696sQGKES','3882108rVTCKd','109235UStmLQ'];_0xf9fd=function(){return _0x113674;};return _0xf9fd();}export*from'./NodeIGlobalAdapter';
|
41
src/core.lib/src/apis/collection.d.ts
vendored
41
src/core.lib/src/apis/collection.d.ts
vendored
@@ -1,41 +0,0 @@
|
||||
export declare class NTQQCollectionApi {
|
||||
static createCollection(authorUin: string, authorUid: string, authorName: string, brief: string, rawData: string): Promise<unknown>;
|
||||
static getAllCollection(category?: number, count?: number): Promise<import("..").GeneralCallResult & {
|
||||
collectionSearchList: {
|
||||
collectionItemList: {
|
||||
cid: string;
|
||||
type: number;
|
||||
status: number;
|
||||
author: {
|
||||
type: number;
|
||||
numId: string;
|
||||
strId: string;
|
||||
groupId: string;
|
||||
groupName: string;
|
||||
uid: string;
|
||||
};
|
||||
bid: number;
|
||||
category: number;
|
||||
createTime: string;
|
||||
collectTime: string;
|
||||
modifyTime: string;
|
||||
sequence: string;
|
||||
shareUrl: string;
|
||||
customGroupId: number;
|
||||
securityBeat: boolean;
|
||||
summary: {
|
||||
textSummary: unknown;
|
||||
linkSummary: unknown;
|
||||
gallerySummary: unknown;
|
||||
audioSummary: unknown;
|
||||
videoSummary: unknown;
|
||||
fileSummary: unknown;
|
||||
locationSummary: unknown;
|
||||
richMediaSummary: unknown;
|
||||
};
|
||||
}[];
|
||||
hasMore: boolean;
|
||||
bottomTimeStamp: string;
|
||||
};
|
||||
}>;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
const _0xb3b733=_0x45ad;(function(_0x4bffd0,_0x176a97){const _0x5ae4cb=_0x45ad,_0x19227e=_0x4bffd0();while(!![]){try{const _0x232a10=parseInt(_0x5ae4cb(0x9e))/0x1*(-parseInt(_0x5ae4cb(0xa3))/0x2)+parseInt(_0x5ae4cb(0x9f))/0x3+-parseInt(_0x5ae4cb(0x98))/0x4+-parseInt(_0x5ae4cb(0xa4))/0x5*(parseInt(_0x5ae4cb(0xa1))/0x6)+parseInt(_0x5ae4cb(0x9a))/0x7+-parseInt(_0x5ae4cb(0x9c))/0x8+-parseInt(_0x5ae4cb(0x9b))/0x9*(-parseInt(_0x5ae4cb(0xa2))/0xa);if(_0x232a10===_0x176a97)break;else _0x19227e['push'](_0x19227e['shift']());}catch(_0x5a2898){_0x19227e['push'](_0x19227e['shift']());}}}(_0x3563,0x5c34e));function _0x3563(){const _0x2b00dc=['now','483126HtoXls','9LnNbBO','3145248lVakQe','getCollectionItemList','1GKTnyB','1666581DNwykv','getCollectionService','24QkRxvQ','10785410wJqEAX','34634zixcbT','782685ybfoFF','createCollection','toString','session','1155148LpPQiB'];_0x3563=function(){return _0x2b00dc;};return _0x3563();}function _0x45ad(_0x1f4c0f,_0x339836){const _0x356308=_0x3563();return _0x45ad=function(_0x45ad53,_0x31dee2){_0x45ad53=_0x45ad53-0x96;let _0x9ded03=_0x356308[_0x45ad53];return _0x9ded03;},_0x45ad(_0x1f4c0f,_0x339836);}import{napCatCore}from'..';export class NTQQCollectionApi{static async[_0xb3b733(0xa5)](_0xc13a04,_0x336a77,_0xa0ed04,_0x57ade0,_0x49485d){const _0x1b5d4d=_0xb3b733;let _0x57b825={'commInfo':{'bid':0x1,'category':0x2,'author':{'type':0x1,'numId':_0xc13a04,'strId':_0xa0ed04,'groupId':'0','groupName':'','uid':_0x336a77},'customGroupId':'0','createTime':Date[_0x1b5d4d(0x99)]()['toString'](),'sequence':Date['now']()[_0x1b5d4d(0x96)]()},'richMediaSummary':{'originalUri':'','publisher':'','richMediaVersion':0x0,'subTitle':'','title':'','brief':_0x57ade0,'picList':[],'contentType':0x1},'richMediaContent':{'rawData':_0x49485d,'bizDataList':[],'picList':[],'fileList':[]},'need_share_url':![]};return napCatCore[_0x1b5d4d(0x97)]['getCollectionService']()['createNewCollectionItem'](_0x57b825);}static async['getAllCollection'](_0x258049=0x0,_0x39c346=0x32){const _0x2dbee4=_0xb3b733;let _0x497dec={'category':_0x258049,'groupId':-0x1,'forceSync':!![],'forceFromDb':![],'timeStamp':'0','count':_0x39c346,'searchDown':!![]};return napCatCore[_0x2dbee4(0x97)][_0x2dbee4(0xa0)]()[_0x2dbee4(0x9d)](_0x497dec);}}
|
38
src/core.lib/src/apis/file.d.ts
vendored
38
src/core.lib/src/apis/file.d.ts
vendored
@@ -1,38 +0,0 @@
|
||||
import { CacheFileListItem, CacheFileType, ChatCacheListItemBasic, ChatType, ElementType, RawMessage } from '@/core/entities';
|
||||
import { GeneralCallResult } from '@/core';
|
||||
import * as fileType from 'file-type';
|
||||
import { ISizeCalculationResult } from 'image-size/dist/types/interface';
|
||||
export declare class NTQQFileApi {
|
||||
static getFileType(filePath: string): Promise<fileType.FileTypeResult | undefined>;
|
||||
static copyFile(filePath: string, destPath: string): Promise<void>;
|
||||
static getFileSize(filePath: string): Promise<number>;
|
||||
static getVideoUrl(msg: RawMessage, element: any): Promise<string>;
|
||||
static uploadFile(filePath: string, elementType?: ElementType, elementSubType?: number): Promise<{
|
||||
md5: string;
|
||||
fileName: string;
|
||||
path: string;
|
||||
fileSize: number;
|
||||
ext: string;
|
||||
}>;
|
||||
static downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout?: number, force?: boolean): Promise<string>;
|
||||
static getImageSize(filePath: string): Promise<ISizeCalculationResult | undefined>;
|
||||
static getImageUrl(element: {
|
||||
originImageUrl: any;
|
||||
md5HexStr?: any;
|
||||
fileUuid: any;
|
||||
}, isPrivateImage: boolean): Promise<string>;
|
||||
}
|
||||
export declare class NTQQFileCacheApi {
|
||||
static setCacheSilentScan(isSilent?: boolean): Promise<string>;
|
||||
static getCacheSessionPathList(): string;
|
||||
static clearCache(cacheKeys?: Array<string>): unknown;
|
||||
static addCacheScannedPaths(pathMap?: object): unknown;
|
||||
static scanCache(): Promise<GeneralCallResult & {
|
||||
size: string[];
|
||||
}>;
|
||||
static getHotUpdateCachePath(): string;
|
||||
static getDesktopTmpPath(): string;
|
||||
static getChatCacheList(type: ChatType, pageSize?: number, pageIndex?: number): unknown;
|
||||
static getFileCacheInfo(fileType: CacheFileType, pageSize?: number, lastRecord?: CacheFileListItem): void;
|
||||
static clearChatCache(chats?: ChatCacheListItemBasic[], fileKeys?: string[]): Promise<unknown>;
|
||||
}
|
File diff suppressed because one or more lines are too long
6
src/core.lib/src/apis/friend.d.ts
vendored
6
src/core.lib/src/apis/friend.d.ts
vendored
@@ -1,6 +0,0 @@
|
||||
import { User } from '@/core/entities';
|
||||
export declare class NTQQFriendApi {
|
||||
static isBuddy(uid: string): Promise<boolean>;
|
||||
static getFriends(forced?: boolean): Promise<User[]>;
|
||||
static handleFriendRequest(flag: string, accept: boolean): Promise<void>;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
function _0x572e(){const _0x148979=['1156458bEJCcO','zhkSh','isBuddy','4883408mjKJUx','NodeIKernelBuddyListener/onBuddyListChange','4923304MUIyrf','push','getBuddyService','CallNormalEvent','session','NodeIKernelBuddyService/getBuddyList','2128800couLCr','10xtggtF','getFriends','3019086EwvboM','3531879AMsxZr','siGMJ','split','length','1CiZNwY','LkFJX','3QCxwZb','2281635HvFgDb'];_0x572e=function(){return _0x148979;};return _0x572e();}const _0x52bfd4=_0x7c45;function _0x7c45(_0x56d024,_0x107e94){const _0x572ed3=_0x572e();return _0x7c45=function(_0x7c4507,_0xf08bc4){_0x7c4507=_0x7c4507-0x179;let _0x4657f2=_0x572ed3[_0x7c4507];return _0x4657f2;},_0x7c45(_0x56d024,_0x107e94);}(function(_0x33f803,_0x59681e){const _0x2c8e3a=_0x7c45,_0x4c1f51=_0x33f803();while(!![]){try{const _0x9751db=-parseInt(_0x2c8e3a(0x186))/0x1*(parseInt(_0x2c8e3a(0x18a))/0x2)+parseInt(_0x2c8e3a(0x188))/0x3*(parseInt(_0x2c8e3a(0x18f))/0x4)+parseInt(_0x2c8e3a(0x189))/0x5+parseInt(_0x2c8e3a(0x17e))/0x6+parseInt(_0x2c8e3a(0x181))/0x7+-parseInt(_0x2c8e3a(0x18d))/0x8+parseInt(_0x2c8e3a(0x182))/0x9*(-parseInt(_0x2c8e3a(0x17f))/0xa);if(_0x9751db===_0x59681e)break;else _0x4c1f51['push'](_0x4c1f51['shift']());}catch(_0x53ed90){_0x4c1f51['push'](_0x4c1f51['shift']());}}}(_0x572e,0xd9d05));import{napCatCore}from'@/core';import{NTEventDispatch}from'@/common/utils/EventTask';export class NTQQFriendApi{static async[_0x52bfd4(0x18c)](_0x567d71){const _0xffd032=_0x52bfd4;return napCatCore[_0xffd032(0x17c)]['getBuddyService']()[_0xffd032(0x18c)](_0x567d71);}static async[_0x52bfd4(0x180)](_0x447f3a=![]){const _0x2dfee7=_0x52bfd4,_0x278a6e={'LkFJX':_0x2dfee7(0x17d),'zhkSh':_0x2dfee7(0x18e)};let [_0x583242,_0x58cd69]=await NTEventDispatch[_0x2dfee7(0x17b)](_0x278a6e[_0x2dfee7(0x187)],_0x278a6e[_0x2dfee7(0x18b)],0x1,0x1388,_0x447f3a);const _0x2fc3f0=[];for(const _0x1fbe49 of _0x58cd69){for(const _0x27baef of _0x1fbe49['buddyList']){_0x2fc3f0[_0x2dfee7(0x179)](_0x27baef);}}return _0x2fc3f0;}static async['handleFriendRequest'](_0x538183,_0x52f244){const _0x125cc8=_0x52bfd4,_0x51590b={'siGMJ':function(_0x100047,_0x97eb59){return _0x100047<_0x97eb59;}};let _0x4d8606=_0x538183[_0x125cc8(0x184)]('|');if(_0x51590b[_0x125cc8(0x183)](_0x4d8606[_0x125cc8(0x185)],0x2))return;let _0x49e576=_0x4d8606[0x0],_0x1b4e84=_0x4d8606[0x1];napCatCore[_0x125cc8(0x17c)][_0x125cc8(0x17a)]()?.['approvalFriendRequest']({'friendUid':_0x49e576,'reqTime':_0x1b4e84,'accept':_0x52f244});}}
|
62
src/core.lib/src/apis/group.d.ts
vendored
62
src/core.lib/src/apis/group.d.ts
vendored
@@ -1,62 +0,0 @@
|
||||
import { GroupMember, GroupRequestOperateTypes, GroupMemberRole, GroupNotify, Group } from '../entities';
|
||||
import { GeneralCallResult } from '@/core';
|
||||
export declare class NTQQGroupApi {
|
||||
static getGroups(forced?: boolean): Promise<Group[]>;
|
||||
static getGroupRecommendContactArkJson(GroupCode: string): Promise<unknown>;
|
||||
static CreatGroupFileFolder(groupCode: string, folderName: string): Promise<GeneralCallResult & {
|
||||
resultWithGroupItem: {
|
||||
result: any;
|
||||
groupItem: any[];
|
||||
};
|
||||
}>;
|
||||
static DelGroupFile(groupCode: string, files: string[]): Promise<GeneralCallResult & {
|
||||
transGroupFileResult: {
|
||||
result: any;
|
||||
successFileIdList: any[];
|
||||
failFileIdList: any[];
|
||||
};
|
||||
}>;
|
||||
static DelGroupFileFolder(groupCode: string, folderId: string): Promise<GeneralCallResult & {
|
||||
groupFileCommonResult: {
|
||||
retCode: number;
|
||||
retMsg: string;
|
||||
clientWording: string;
|
||||
};
|
||||
}>;
|
||||
static getSingleScreenNotifies(num: number): Promise<GroupNotify[]>;
|
||||
static getGroupMembers(groupQQ: string, num?: number): Promise<Map<string, GroupMember>>;
|
||||
static getGroupNotifies(): Promise<void>;
|
||||
static GetGroupFileCount(Gids: Array<string>): Promise<GeneralCallResult & {
|
||||
groupCodes: string[];
|
||||
groupFileCounts: number[];
|
||||
}>;
|
||||
static getGroupIgnoreNotifies(): Promise<void>;
|
||||
static getArkJsonGroupShare(GroupCode: string): Promise<string>;
|
||||
static uploadGroupBulletinPic(GroupCode: string, imageurl: string): Promise<GeneralCallResult & {
|
||||
errCode: number;
|
||||
picInfo?: {
|
||||
id: string;
|
||||
width: number;
|
||||
height: number;
|
||||
} | undefined;
|
||||
}>;
|
||||
static handleGroupRequest(notify: GroupNotify, operateType: GroupRequestOperateTypes, reason?: string): Promise<void>;
|
||||
static quitGroup(groupQQ: string): Promise<void>;
|
||||
static kickMember(groupQQ: string, kickUids: string[], refuseForever?: boolean, kickReason?: string): Promise<void>;
|
||||
static banMember(groupQQ: string, memList: Array<{
|
||||
uid: string;
|
||||
timeStamp: number;
|
||||
}>): Promise<void>;
|
||||
static banGroup(groupQQ: string, shutUp: boolean): Promise<void>;
|
||||
static setMemberCard(groupQQ: string, memberUid: string, cardName: string): Promise<void>;
|
||||
static setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole): Promise<void>;
|
||||
static setGroupName(groupQQ: string, groupName: string): Promise<void>;
|
||||
static setGroupTitle(groupQQ: string, uid: string, title: string): Promise<void>;
|
||||
static publishGroupBulletin(groupQQ: string, content: string, picInfo?: {
|
||||
id: string;
|
||||
width: number;
|
||||
height: number;
|
||||
} | undefined, pinned?: number, confirmRequired?: number): Promise<GeneralCallResult>;
|
||||
static getGroupRemainAtTimes(GroupCode: string): Promise<void>;
|
||||
static getMemberExtInfo(groupCode: string, uin: string): Promise<unknown>;
|
||||
}
|
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
(function(_0x15ce39,_0x13199b){var _0x4c22b3=_0xadf5,_0x2951c6=_0x15ce39();while(!![]){try{var _0x273778=parseInt(_0x4c22b3(0x15d))/0x1*(-parseInt(_0x4c22b3(0x160))/0x2)+-parseInt(_0x4c22b3(0x15f))/0x3+-parseInt(_0x4c22b3(0x162))/0x4+-parseInt(_0x4c22b3(0x15a))/0x5*(-parseInt(_0x4c22b3(0x15b))/0x6)+parseInt(_0x4c22b3(0x159))/0x7+parseInt(_0x4c22b3(0x15c))/0x8*(parseInt(_0x4c22b3(0x161))/0x9)+parseInt(_0x4c22b3(0x158))/0xa*(-parseInt(_0x4c22b3(0x15e))/0xb);if(_0x273778===_0x13199b)break;else _0x2951c6['push'](_0x2951c6['shift']());}catch(_0x4a9e88){_0x2951c6['push'](_0x2951c6['shift']());}}}(_0x6b56,0x1d080));export*from'./file';export*from'./friend';function _0xadf5(_0xe85888,_0x18b3b9){var _0x6b56db=_0x6b56();return _0xadf5=function(_0xadf584,_0x15ac02){_0xadf584=_0xadf584-0x158;var _0xbb2ac2=_0x6b56db[_0xadf584];return _0xbb2ac2;},_0xadf5(_0xe85888,_0x18b3b9);}function _0x6b56(){var _0x4e2e8e=['3930fQOinP','407064cMrPYp','15fUHMJF','355902nohPBG','32oIFdwa','9457vpjIhu','99gBukQY','556590KGOdrS','2bzftJU','498429htphvM','560764TpbQoN'];_0x6b56=function(){return _0x4e2e8e;};return _0x6b56();}export*from'./group';export*from'./msg';export*from'./user';export*from'./webapi';export*from'./sign';export*from'./system';
|
26
src/core.lib/src/apis/msg.d.ts
vendored
26
src/core.lib/src/apis/msg.d.ts
vendored
@@ -1,26 +0,0 @@
|
||||
import { GetFileListParam, Peer, RawMessage, SendMessageElement } from '@/core/entities';
|
||||
import { GeneralCallResult } from '@/core/services/common';
|
||||
export declare class NTQQMsgApi {
|
||||
static setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, set?: boolean): Promise<unknown>;
|
||||
static getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & {
|
||||
msgList: RawMessage[];
|
||||
} | undefined>;
|
||||
static getMsgsByMsgId(peer: Peer, msgIds: string[]): Promise<GeneralCallResult & {
|
||||
msgList: RawMessage[];
|
||||
}>;
|
||||
static getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean): Promise<GeneralCallResult & {
|
||||
msgList: RawMessage[];
|
||||
}>;
|
||||
static activateChat(peer: Peer): Promise<void>;
|
||||
static activateChatAndGetHistory(peer: Peer): Promise<void>;
|
||||
static setMsgRead(peer: Peer): Promise<GeneralCallResult>;
|
||||
static getGroupFileList(GroupCode: string, params: GetFileListParam): Promise<any[]>;
|
||||
static getMsgHistory(peer: Peer, msgId: string, count: number): Promise<GeneralCallResult & {
|
||||
msgList: RawMessage[];
|
||||
}>;
|
||||
static fetchRecentContact(): Promise<void>;
|
||||
static recallMsg(peer: Peer, msgIds: string[]): Promise<void>;
|
||||
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete?: boolean, timeout?: number): Promise<RawMessage>;
|
||||
static forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
|
||||
static multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage>;
|
||||
}
|
File diff suppressed because one or more lines are too long
43
src/core.lib/src/apis/sign.d.ts
vendored
43
src/core.lib/src/apis/sign.d.ts
vendored
@@ -1,43 +0,0 @@
|
||||
export interface IdMusicSignPostData {
|
||||
type: 'qq' | '163';
|
||||
id: string | number;
|
||||
}
|
||||
export interface CustomMusicSignPostData {
|
||||
type: 'custom';
|
||||
url: string;
|
||||
audio: string;
|
||||
title: string;
|
||||
image?: string;
|
||||
singer?: string;
|
||||
}
|
||||
export interface MiniAppLuaJsonType {
|
||||
prompt: string;
|
||||
title: string;
|
||||
preview: string;
|
||||
jumpUrl: string;
|
||||
tag: string;
|
||||
tagIcon: string;
|
||||
source: string;
|
||||
sourcelogo: string;
|
||||
}
|
||||
export declare function SignMiniApp(CardData: MiniAppLuaJsonType): Promise<string>;
|
||||
export declare function SignMusicInternal(songname: string, singer: string, cover: string, songmid: string, songmusic: string): Promise<{
|
||||
code: number;
|
||||
data: {
|
||||
arkResult: string;
|
||||
};
|
||||
}>;
|
||||
export declare function CreateMusicThridWay0(id?: string, mid?: string): Promise<{
|
||||
mid: string;
|
||||
name?: string | undefined;
|
||||
singer?: string | undefined;
|
||||
url?: string | undefined;
|
||||
cover?: string | undefined;
|
||||
}>;
|
||||
export declare function CreateMusicThridWay1(id?: string, mid?: string): Promise<void>;
|
||||
export declare function SignMusicWrapper(id?: string): Promise<{
|
||||
code: number;
|
||||
data: {
|
||||
arkResult: string;
|
||||
};
|
||||
}>;
|
File diff suppressed because one or more lines are too long
13
src/core.lib/src/apis/system.d.ts
vendored
13
src/core.lib/src/apis/system.d.ts
vendored
@@ -1,13 +0,0 @@
|
||||
import { GeneralCallResult } from '@/core';
|
||||
export declare class NTQQSystemApi {
|
||||
static hasOtherRunningQQProcess(): Promise<boolean>;
|
||||
static ORCImage(filePath: string): Promise<GeneralCallResult>;
|
||||
static translateEnWordToZn(words: string[]): Promise<GeneralCallResult & {
|
||||
words: string[];
|
||||
}>;
|
||||
static getOnlineDev(): Promise<any>;
|
||||
static getArkJsonCollection(cid: string): Promise<GeneralCallResult & {
|
||||
arkJson: string;
|
||||
}>;
|
||||
static BootMiniApp(appfile: string, params: string): Promise<unknown>;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
const _0xd859fc=_0x27c0;(function(_0x19ec60,_0x1340d9){const _0x53807a=_0x27c0,_0x589f6a=_0x19ec60();while(!![]){try{const _0x450fe3=parseInt(_0x53807a(0x1d3))/0x1+-parseInt(_0x53807a(0x1dc))/0x2*(parseInt(_0x53807a(0x1d5))/0x3)+parseInt(_0x53807a(0x1d1))/0x4*(-parseInt(_0x53807a(0x1ce))/0x5)+parseInt(_0x53807a(0x1e0))/0x6+-parseInt(_0x53807a(0x1df))/0x7*(-parseInt(_0x53807a(0x1d2))/0x8)+parseInt(_0x53807a(0x1d0))/0x9+-parseInt(_0x53807a(0x1e2))/0xa;if(_0x450fe3===_0x1340d9)break;else _0x589f6a['push'](_0x589f6a['shift']());}catch(_0x5d2186){_0x589f6a['push'](_0x589f6a['shift']());}}}(_0x1cd5,0x8e049));import{NTEventDispatch}from'@/common/utils/EventTask';import{napCatCore}from'@/core';function _0x27c0(_0xdb50cc,_0x3c6ddd){const _0x1cd504=_0x1cd5();return _0x27c0=function(_0x27c07a,_0x338a39){_0x27c07a=_0x27c07a-0x1c9;let _0x1d8fdd=_0x1cd504[_0x27c07a];return _0x1d8fdd;},_0x27c0(_0xdb50cc,_0x3c6ddd);}function _0x1cd5(){const _0x44d371=['getNodeMiscService','util','80521wpTPdK','5307684DwKiXT','getRichMediaService','15344410wBAEVs','getOnLineDev','aaWSB','NodeIKernelCollectionService/collectionArkShare','wantWinScreenOCR','hasOtherRunningQQProcess','235qqyPQJ','session','5299326IZjbvb','31412fPwsGq','704fgVNNV','386427cRltiW','2.16.4','580323gWozXc','CallNoListenerEvent','startNewMiniApp','setMiniAppVersion','getOnlineDev','BootMiniApp','translateEnWordToZn','4DxeBNp'];_0x1cd5=function(){return _0x44d371;};return _0x1cd5();}export class NTQQSystemApi{static async[_0xd859fc(0x1cd)](){const _0x28feba=_0xd859fc;return napCatCore[_0x28feba(0x1de)][_0x28feba(0x1cd)]();}static async['ORCImage'](_0x10fcc3){const _0x5bd5e6=_0xd859fc;return napCatCore['session'][_0x5bd5e6(0x1dd)]()[_0x5bd5e6(0x1cc)](_0x10fcc3);}static async[_0xd859fc(0x1db)](_0x8c6ade){const _0x176f7b=_0xd859fc;return napCatCore['session'][_0x176f7b(0x1e1)]()['translateEnWordToZn'](_0x8c6ade);}static async[_0xd859fc(0x1d9)](){const _0x33a331=_0xd859fc;return napCatCore[_0x33a331(0x1cf)]['getMsgService']()[_0x33a331(0x1c9)]();}static async['getArkJsonCollection'](_0x1683d5){const _0x168187=_0xd859fc,_0x22487d={'aaWSB':_0x168187(0x1cb),'ToPFw':'1717662698058'};let _0x31b204=await NTEventDispatch[_0x168187(0x1d6)](_0x22487d[_0x168187(0x1ca)],0x1388,_0x22487d['ToPFw']);return _0x31b204;}static async[_0xd859fc(0x1da)](_0x50e076,_0xe84000){const _0x1f5c3d=_0xd859fc;await napCatCore['session'][_0x1f5c3d(0x1dd)]()[_0x1f5c3d(0x1d8)](_0x1f5c3d(0x1d4));let _0x2133c5=await napCatCore[_0x1f5c3d(0x1cf)][_0x1f5c3d(0x1dd)]()['getMiniAppPath']();return console['log'](_0x2133c5),napCatCore['session'][_0x1f5c3d(0x1dd)]()[_0x1f5c3d(0x1d7)](_0x50e076,_0xe84000);}}
|
35
src/core.lib/src/apis/user.d.ts
vendored
35
src/core.lib/src/apis/user.d.ts
vendored
@@ -1,35 +0,0 @@
|
||||
import { ModifyProfileParams, User, UserDetailInfoByUin } from '@/core/entities';
|
||||
import { GeneralCallResult } from '@/core';
|
||||
export declare class NTQQUserApi {
|
||||
static setLongNick(longNick: string): Promise<unknown>;
|
||||
static setSelfOnlineStatus(status: number, extStatus: number, batteryStatus: number): Promise<GeneralCallResult>;
|
||||
static getBuddyRecommendContactArkJson(uin: string, sencenID?: string): Promise<unknown>;
|
||||
static like(uid: string, count?: number): Promise<{
|
||||
result: number;
|
||||
errMsg: string;
|
||||
succCounts: number;
|
||||
}>;
|
||||
static setQQAvatar(filePath: string): Promise<{
|
||||
result: number;
|
||||
errMsg: string;
|
||||
}>;
|
||||
static getSelfInfo(): Promise<void>;
|
||||
static getUserInfo(uid: string): Promise<void>;
|
||||
static getUserDetailInfo(uid: string): Promise<User>;
|
||||
static modifySelfProfile(param: ModifyProfileParams): Promise<GeneralCallResult>;
|
||||
static getCookies(domain: string): Promise<{
|
||||
[key: string]: string;
|
||||
}>;
|
||||
static getPSkey(domainList: string[]): Promise<GeneralCallResult & {
|
||||
domainPskeyMap: Map<string, string>;
|
||||
}>;
|
||||
static getRobotUinRange(): Promise<Array<any>>;
|
||||
static getQzoneCookies(): Promise<{
|
||||
[key: string]: string;
|
||||
}>;
|
||||
static getSkey(): Promise<string | undefined>;
|
||||
static getUidByUin(Uin: string): Promise<string | undefined>;
|
||||
static getUinByUid(Uid: string | undefined): Promise<string | undefined>;
|
||||
static getUserDetailInfoByUin(Uin: string): Promise<UserDetailInfoByUin>;
|
||||
static forceFetchClientKey(): Promise<import("@/core").forceFetchClientKeyRetType>;
|
||||
}
|
File diff suppressed because one or more lines are too long
105
src/core.lib/src/apis/webapi.d.ts
vendored
105
src/core.lib/src/apis/webapi.d.ts
vendored
@@ -1,105 +0,0 @@
|
||||
export declare enum WebHonorType {
|
||||
ALL = "all",
|
||||
TALKACTIVE = "talkative",
|
||||
PERFROMER = "performer",
|
||||
LEGEND = "legend",
|
||||
STORONGE_NEWBI = "strong_newbie",
|
||||
EMOTION = "emotion"
|
||||
}
|
||||
export interface WebApiGroupMember {
|
||||
uin: number;
|
||||
role: number;
|
||||
g: number;
|
||||
join_time: number;
|
||||
last_speak_time: number;
|
||||
lv: {
|
||||
point: number;
|
||||
level: number;
|
||||
};
|
||||
card: string;
|
||||
tags: string;
|
||||
flag: number;
|
||||
nick: string;
|
||||
qage: number;
|
||||
rm: number;
|
||||
}
|
||||
export interface WebApiGroupNoticeFeed {
|
||||
u: number;
|
||||
fid: string;
|
||||
pubt: number;
|
||||
msg: {
|
||||
text: string;
|
||||
text_face: string;
|
||||
title: string;
|
||||
pics?: {
|
||||
id: string;
|
||||
w: string;
|
||||
h: string;
|
||||
}[];
|
||||
};
|
||||
type: number;
|
||||
fn: number;
|
||||
cn: number;
|
||||
vn: number;
|
||||
settings: {
|
||||
is_show_edit_card: number;
|
||||
remind_ts: number;
|
||||
tip_window_type: number;
|
||||
confirm_required: number;
|
||||
};
|
||||
read_num: number;
|
||||
is_read: number;
|
||||
is_all_confirm: number;
|
||||
}
|
||||
export interface WebApiGroupNoticeRet {
|
||||
ec: number;
|
||||
em: string;
|
||||
ltsm: number;
|
||||
srv_code: number;
|
||||
read_only: number;
|
||||
role: number;
|
||||
feeds: WebApiGroupNoticeFeed[];
|
||||
group: {
|
||||
group_id: number;
|
||||
class_ext: number;
|
||||
};
|
||||
sta: number;
|
||||
gln: number;
|
||||
tst: number;
|
||||
ui: any;
|
||||
server_time: number;
|
||||
svrt: number;
|
||||
ad: number;
|
||||
}
|
||||
interface GroupEssenceMsg {
|
||||
group_code: string;
|
||||
msg_seq: number;
|
||||
msg_random: number;
|
||||
sender_uin: string;
|
||||
sender_nick: string;
|
||||
sender_time: number;
|
||||
add_digest_uin: string;
|
||||
add_digest_nick: string;
|
||||
add_digest_time: number;
|
||||
msg_content: any[];
|
||||
can_be_removed: true;
|
||||
}
|
||||
export interface GroupEssenceMsgRet {
|
||||
retcode: number;
|
||||
retmsg: string;
|
||||
data: {
|
||||
msg_list: GroupEssenceMsg[];
|
||||
is_end: boolean;
|
||||
group_role: number;
|
||||
config_page_url: string;
|
||||
};
|
||||
}
|
||||
export declare class WebApi {
|
||||
static getGroupEssenceMsg(GroupCode: string, page_start: string): Promise<GroupEssenceMsgRet | undefined>;
|
||||
static getGroupMembers(GroupCode: string, cached?: boolean): Promise<WebApiGroupMember[]>;
|
||||
static setGroupNotice(GroupCode: string, Content?: string): Promise<any>;
|
||||
static getGrouptNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet>;
|
||||
static genBkn(sKey: string): string;
|
||||
static getGroupHonorInfo(groupCode: string, getType: WebHonorType): Promise<any>;
|
||||
}
|
||||
export {};
|
File diff suppressed because one or more lines are too long
36
src/core.lib/src/core.d.ts
vendored
36
src/core.lib/src/core.d.ts
vendored
@@ -1,36 +0,0 @@
|
||||
/// <reference types="node" />
|
||||
import { NodeIQQNTWrapperEngine, NodeIQQNTWrapperSession, NodeQQNTWrapperUtil } from '@/core/wrapper';
|
||||
import { QuickLoginResult } from '@/core/services';
|
||||
import { BuddyListener, GroupListener, MsgListener, ProfileListener } from '@/core/listeners';
|
||||
export interface OnLoginSuccess {
|
||||
(uin: string, uid: string): void | Promise<void>;
|
||||
}
|
||||
export declare class NapCatCore {
|
||||
readonly session: NodeIQQNTWrapperSession;
|
||||
readonly util: NodeQQNTWrapperUtil;
|
||||
readonly engine: NodeIQQNTWrapperEngine;
|
||||
private readonly loginListener;
|
||||
private loginService;
|
||||
private onLoginSuccessFuncList;
|
||||
private proxyHandler;
|
||||
constructor();
|
||||
get dataPath(): string;
|
||||
get dataPathGlobal(): string;
|
||||
private initConfig;
|
||||
private initSession;
|
||||
private initDataListener;
|
||||
addListener(listener: BuddyListener | GroupListener | MsgListener | ProfileListener): number;
|
||||
onLoginSuccess(func: OnLoginSuccess): void;
|
||||
quickLogin(uin: string): Promise<QuickLoginResult>;
|
||||
qrLogin(cb: (url: string, base64: string, buffer: Buffer) => Promise<void>): Promise<{
|
||||
url: string;
|
||||
base64: string;
|
||||
buffer: Buffer;
|
||||
}>;
|
||||
passwordLogin(uin: string, password: string, proofSig?: string, proofRand?: string, proofSid?: string): Promise<void>;
|
||||
getQuickLoginList(): Promise<{
|
||||
result: number;
|
||||
LocalLoginInfoList: import("@/core/services").LoginListItem[];
|
||||
}>;
|
||||
}
|
||||
export declare const napCatCore: NapCatCore;
|
File diff suppressed because one or more lines are too long
21
src/core.lib/src/data.d.ts
vendored
21
src/core.lib/src/data.d.ts
vendored
@@ -1,21 +0,0 @@
|
||||
import { type Friend, type Group, type GroupMember, GroupNotify, type SelfInfo, BuddyCategoryType } from './entities';
|
||||
export declare const selfInfo: SelfInfo;
|
||||
export declare const groups: Map<string, Group>;
|
||||
export declare function deleteGroup(groupQQ: string): void;
|
||||
export declare const groupMembers: Map<string, Map<string, GroupMember>>;
|
||||
export declare const friends: Map<string, Friend>;
|
||||
export declare const rawFriends: Array<BuddyCategoryType>;
|
||||
export declare const groupNotifies: Record<string, GroupNotify>;
|
||||
export declare function getGroup(qq: string | number): Promise<Group | undefined>;
|
||||
export declare function getGroupMember(groupQQ: string | number, memberUinOrUid: string | number): Promise<GroupMember | null | undefined>;
|
||||
export declare const tempGroupCodeMap: Record<string, string>;
|
||||
export declare const stat: {
|
||||
packet_received: number;
|
||||
packet_sent: number;
|
||||
message_received: number;
|
||||
message_sent: number;
|
||||
last_message_time: number;
|
||||
disconnect_times: number;
|
||||
lost_times: number;
|
||||
packet_lost: number;
|
||||
};
|
@@ -1 +0,0 @@
|
||||
(function(_0x2ae82b,_0x5521a2){const _0x107c37=_0x8034,_0x583285=_0x2ae82b();while(!![]){try{const _0x441003=-parseInt(_0x107c37(0x193))/0x1*(-parseInt(_0x107c37(0x195))/0x2)+-parseInt(_0x107c37(0x18c))/0x3+-parseInt(_0x107c37(0x18f))/0x4+parseInt(_0x107c37(0x190))/0x5*(parseInt(_0x107c37(0x18e))/0x6)+parseInt(_0x107c37(0x1a2))/0x7+parseInt(_0x107c37(0x199))/0x8+parseInt(_0x107c37(0x1a1))/0x9*(-parseInt(_0x107c37(0x194))/0xa);if(_0x441003===_0x5521a2)break;else _0x583285['push'](_0x583285['shift']());}catch(_0x16a888){_0x583285['push'](_0x583285['shift']());}}}(_0x5f43,0x6b13e));import{isNumeric}from'@/common/utils/helper';import{NTQQGroupApi}from'@/core/apis';export const selfInfo={'uid':'','uin':'','nick':'','online':!![]};function _0x5f43(){const _0x57ef38=['get','YJEXc','toString','set','81MnQDvY','1836569ZqKSOM','756921UNdvFm','uin','58860YSbBqy','1859392EGleDH','270MAuyLq','pAbUj','values','360947KMQzes','395400ZgYaIP','2ifZRGe','getGroupMembers','from','getGroups','2868408yqQbTT','delete','groupCode','forEach'];_0x5f43=function(){return _0x57ef38;};return _0x5f43();}function _0x8034(_0x56584a,_0x3d3593){const _0x5f43e8=_0x5f43();return _0x8034=function(_0x8034f4,_0x4b0b7e){_0x8034f4=_0x8034f4-0x18c;let _0x49dcd4=_0x5f43e8[_0x8034f4];return _0x49dcd4;},_0x8034(_0x56584a,_0x3d3593);}export const groups=new Map();export function deleteGroup(_0x192627){const _0x6a813d=_0x8034;groups[_0x6a813d(0x19a)](_0x192627),groupMembers['delete'](_0x192627);}export const groupMembers=new Map();export const friends=new Map();export const rawFriends=[];export const groupNotifies={};export async function getGroup(_0x4f6104){const _0x5e163b=_0x8034;let _0x12e5a5=groups[_0x5e163b(0x19d)](_0x4f6104['toString']());if(!_0x12e5a5)try{const _0x4748f1=await NTQQGroupApi[_0x5e163b(0x198)]();_0x4748f1['length']&&_0x4748f1[_0x5e163b(0x19c)](_0x426239=>{const _0x3345e8=_0x5e163b;groups[_0x3345e8(0x1a0)](_0x426239[_0x3345e8(0x19b)],_0x426239);});}catch(_0x250269){return undefined;}return _0x12e5a5=groups[_0x5e163b(0x19d)](_0x4f6104[_0x5e163b(0x19f)]()),_0x12e5a5;}export async function getGroupMember(_0x4a2b82,_0x531ed4){const _0x2e3cb3=_0x8034,_0x50e18c={'WFUIc':function(_0x31bbd2,_0x3f9435){return _0x31bbd2(_0x3f9435);},'YJEXc':function(_0x517da1){return _0x517da1();},'pAbUj':function(_0xa6df48){return _0xa6df48();}};_0x4a2b82=_0x4a2b82[_0x2e3cb3(0x19f)](),_0x531ed4=_0x531ed4[_0x2e3cb3(0x19f)]();let _0x5d565b=groupMembers[_0x2e3cb3(0x19d)](_0x4a2b82);if(!_0x5d565b)try{_0x5d565b=await NTQQGroupApi[_0x2e3cb3(0x196)](_0x4a2b82),groupMembers[_0x2e3cb3(0x1a0)](_0x4a2b82,_0x5d565b);}catch(_0x46da0b){return null;}const _0x265a9d=()=>{const _0x58c04d=_0x2e3cb3;let _0x5d2e2a=undefined;return _0x50e18c['WFUIc'](isNumeric,_0x531ed4)?_0x5d2e2a=Array[_0x58c04d(0x197)](_0x5d565b[_0x58c04d(0x192)]())['find'](_0x5ba709=>_0x5ba709[_0x58c04d(0x18d)]===_0x531ed4):_0x5d2e2a=_0x5d565b['get'](_0x531ed4),_0x5d2e2a;};let _0x44ca6b=_0x50e18c[_0x2e3cb3(0x19e)](_0x265a9d);return!_0x44ca6b&&(_0x5d565b=await NTQQGroupApi[_0x2e3cb3(0x196)](_0x4a2b82),_0x44ca6b=_0x50e18c[_0x2e3cb3(0x191)](_0x265a9d)),_0x44ca6b;}export const tempGroupCodeMap={};export const stat={'packet_received':0x0,'packet_sent':0x0,'message_received':0x0,'message_sent':0x0,'last_message_time':0x0,'disconnect_times':0x0,'lost_times':0x0,'packet_lost':0x0};
|
@@ -1 +0,0 @@
|
||||
(function(_0x82d6f1,_0x1dd832){var _0x578224=_0xb5e2,_0x5d6ee2=_0x82d6f1();while(!![]){try{var _0x5a4f51=-parseInt(_0x578224(0x8b))/0x1+parseInt(_0x578224(0x7a))/0x2*(-parseInt(_0x578224(0x82))/0x3)+-parseInt(_0x578224(0x85))/0x4+parseInt(_0x578224(0x84))/0x5+parseInt(_0x578224(0x83))/0x6*(-parseInt(_0x578224(0x8d))/0x7)+parseInt(_0x578224(0x89))/0x8*(-parseInt(_0x578224(0x8a))/0x9)+parseInt(_0x578224(0x7f))/0xa;if(_0x5a4f51===_0x1dd832)break;else _0x5d6ee2['push'](_0x5d6ee2['shift']());}catch(_0x29c7cd){_0x5d6ee2['push'](_0x5d6ee2['shift']());}}}(_0x417c,0x6d6e3));function _0xb5e2(_0xd26eab,_0x500603){var _0x417c9e=_0x417c();return _0xb5e2=function(_0xb5e207,_0x5d8616){_0xb5e207=_0xb5e207-0x7a;var _0x22ff59=_0x417c9e[_0xb5e207];return _0x22ff59;},_0xb5e2(_0xd26eab,_0x500603);}function _0x417c(){var _0x486dd0=['OTHER','14TrooVz','12BZLawf','VIDEO','HDWWn','UArdR','IUVtg','18480360VermPA','Azfyv','IMAGE','233463BjJIDs','2351802mVesbi','4145165JLnXil','699244MmGstQ','AUDIO','split','wVMeJ','8PuLgMm','2616192heGAjK','512483nlRulV'];_0x417c=function(){return _0x486dd0;};return _0x417c();};export var CacheFileType;(function(_0x836b1d){var _0x4f7cc8=_0xb5e2,_0x1dc981={'IUVtg':_0x4f7cc8(0x7b),'wVMeJ':'OTHER','Azfyv':'DOCUMENT','HDWWn':_0x4f7cc8(0x86),'UArdR':'IMAGE'},_0x2e4ac1='4|0|3|2|1'[_0x4f7cc8(0x87)]('|'),_0xf1ac3b=0x0;while(!![]){switch(_0x2e4ac1[_0xf1ac3b++]){case'0':_0x836b1d[_0x836b1d[_0x1dc981[_0x4f7cc8(0x7e)]]=0x1]=_0x1dc981[_0x4f7cc8(0x7e)];continue;case'1':_0x836b1d[_0x836b1d[_0x4f7cc8(0x8c)]=0x4]=_0x1dc981[_0x4f7cc8(0x88)];continue;case'2':_0x836b1d[_0x836b1d[_0x1dc981['Azfyv']]=0x3]=_0x1dc981[_0x4f7cc8(0x80)];continue;case'3':_0x836b1d[_0x836b1d[_0x1dc981[_0x4f7cc8(0x7c)]]=0x2]=_0x1dc981[_0x4f7cc8(0x7c)];continue;case'4':_0x836b1d[_0x836b1d[_0x1dc981[_0x4f7cc8(0x7d)]]=0x0]=_0x4f7cc8(0x81);continue;}break;}}(CacheFileType||(CacheFileType={})));
|
18
src/core.lib/src/entities/constructor.d.ts
vendored
18
src/core.lib/src/entities/constructor.d.ts
vendored
@@ -1,18 +0,0 @@
|
||||
import { AtType, SendArkElement, SendFaceElement, SendFileElement, SendMarkdownElement, SendMarketFaceElement, SendPicElement, SendPttElement, SendReplyElement, SendTextElement, SendVideoElement } from './index';
|
||||
export declare const mFaceCache: Map<string, string>;
|
||||
export declare class SendMsgElementConstructor {
|
||||
static text(content: string): SendTextElement;
|
||||
static at(atUid: string, atNtUid: string, atType: AtType, atName: string): SendTextElement;
|
||||
static reply(msgSeq: string, msgId: string, senderUin: string, senderUinStr: string): SendReplyElement;
|
||||
static pic(picPath: string, summary?: string, subType?: 0 | 1): Promise<SendPicElement>;
|
||||
static file(filePath: string, fileName?: string, folderId?: string): Promise<SendFileElement>;
|
||||
static video(filePath: string, fileName?: string, diyThumbPath?: string): Promise<SendVideoElement>;
|
||||
static ptt(pttPath: string): Promise<SendPttElement>;
|
||||
static face(faceId: number): SendFaceElement;
|
||||
static mface(emojiPackageId: number, emojiId: string, key: string, faceName: string): SendMarketFaceElement;
|
||||
static dice(resultId: number | null): SendFaceElement;
|
||||
static rps(resultId: number | null): SendFaceElement;
|
||||
static ark(data: any): SendArkElement;
|
||||
static markdown(content: string): SendMarkdownElement;
|
||||
static miniapp(): Promise<SendArkElement>;
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
52
src/core.lib/src/entities/group.d.ts
vendored
52
src/core.lib/src/entities/group.d.ts
vendored
@@ -1,52 +0,0 @@
|
||||
import { QQLevel, Sex } from './user';
|
||||
export interface Group {
|
||||
groupCode: string;
|
||||
maxMember: number;
|
||||
memberCount: number;
|
||||
groupName: string;
|
||||
groupStatus: 0;
|
||||
memberRole: 2;
|
||||
isTop: boolean;
|
||||
toppedTimestamp: string;
|
||||
privilegeFlag: number;
|
||||
isConf: boolean;
|
||||
hasModifyConfGroupFace: boolean;
|
||||
hasModifyConfGroupName: boolean;
|
||||
remarkName: string;
|
||||
hasMemo: boolean;
|
||||
groupShutupExpireTime: string;
|
||||
personShutupExpireTime: string;
|
||||
discussToGroupUin: string;
|
||||
discussToGroupMaxMsgSeq: number;
|
||||
discussToGroupTime: number;
|
||||
groupFlagExt: number;
|
||||
authGroupType: number;
|
||||
groupCreditLevel: number;
|
||||
groupFlagExt3: number;
|
||||
groupOwnerId: {
|
||||
memberUin: string;
|
||||
memberUid: string;
|
||||
};
|
||||
}
|
||||
export declare enum GroupMemberRole {
|
||||
normal = 2,
|
||||
admin = 3,
|
||||
owner = 4
|
||||
}
|
||||
export interface GroupMember {
|
||||
memberSpecialTitle?: string;
|
||||
avatarPath: string;
|
||||
cardName: string;
|
||||
cardType: number;
|
||||
isDelete: boolean;
|
||||
nick: string;
|
||||
qid: string;
|
||||
remark: string;
|
||||
role: GroupMemberRole;
|
||||
shutUpTime: number;
|
||||
uid: string;
|
||||
uin: string;
|
||||
isRobot: boolean;
|
||||
sex?: Sex;
|
||||
qqLevel?: QQLevel;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
(function(_0x3dced5,_0x2c485b){var _0x281449=_0x490f,_0x1845dc=_0x3dced5();while(!![]){try{var _0x280f18=parseInt(_0x281449(0x1f9))/0x1+parseInt(_0x281449(0x1fc))/0x2*(-parseInt(_0x281449(0x1ef))/0x3)+parseInt(_0x281449(0x1f1))/0x4+parseInt(_0x281449(0x1f2))/0x5+parseInt(_0x281449(0x1f8))/0x6*(parseInt(_0x281449(0x1f7))/0x7)+-parseInt(_0x281449(0x1f0))/0x8*(parseInt(_0x281449(0x1fb))/0x9)+-parseInt(_0x281449(0x1f3))/0xa;if(_0x280f18===_0x2c485b)break;else _0x1845dc['push'](_0x1845dc['shift']());}catch(_0x2218a4){_0x1845dc['push'](_0x1845dc['shift']());}}}(_0x16e1,0xed685));function _0x16e1(){var _0x351aeb=['8834FZxmdg','5178fSiXKj','852105DqaKVI','ZxGYB','9xcRocm','8530brQQwl','582kRxwhY','2242008fVhKMy','655756IUMRdV','7581785RzWlWM','15414250dicBGg','owner','admin','MQuiD'];_0x16e1=function(){return _0x351aeb;};return _0x16e1();}function _0x490f(_0x2673cc,_0x41ddd2){var _0x16e1e0=_0x16e1();return _0x490f=function(_0x490f37,_0x3fe4d6){_0x490f37=_0x490f37-0x1ef;var _0xcce750=_0x16e1e0[_0x490f37];return _0xcce750;},_0x490f(_0x2673cc,_0x41ddd2);}export var GroupMemberRole;(function(_0x2b0afc){var _0x35d605=_0x490f,_0x25276f={'ZxGYB':'normal','MQuiD':_0x35d605(0x1f4)};_0x2b0afc[_0x2b0afc[_0x25276f[_0x35d605(0x1fa)]]=0x2]='normal',_0x2b0afc[_0x2b0afc['admin']=0x3]=_0x35d605(0x1f5),_0x2b0afc[_0x2b0afc[_0x25276f[_0x35d605(0x1f6)]]=0x4]=_0x35d605(0x1f4);}(GroupMemberRole||(GroupMemberRole={})));
|
@@ -1 +0,0 @@
|
||||
function _0x5436(){var _0x7e1d96=['525aRNMDk','24774ADzSFE','1768vSmtSK','389939GpYsiX','134193FNvady','18092WAsbnc','6363pEYOTQ','3418800fZnBvW','35dOEdLr','99192ZpRgWp'];_0x5436=function(){return _0x7e1d96;};return _0x5436();}(function(_0x24b220,_0x3310bf){var _0xd69dd6=_0x3bbe,_0x47a565=_0x24b220();while(!![]){try{var _0x1e1718=-parseInt(_0xd69dd6(0x175))/0x1+parseInt(_0xd69dd6(0x171))/0x2+-parseInt(_0xd69dd6(0x176))/0x3+parseInt(_0xd69dd6(0x177))/0x4*(parseInt(_0xd69dd6(0x172))/0x5)+parseInt(_0xd69dd6(0x173))/0x6*(parseInt(_0xd69dd6(0x170))/0x7)+parseInt(_0xd69dd6(0x174))/0x8*(-parseInt(_0xd69dd6(0x178))/0x9)+parseInt(_0xd69dd6(0x16f))/0xa;if(_0x1e1718===_0x3310bf)break;else _0x47a565['push'](_0x47a565['shift']());}catch(_0x431aba){_0x47a565['push'](_0x47a565['shift']());}}}(_0x5436,0x484b7));export*from'./user';export*from'./group';function _0x3bbe(_0x568205,_0x2896c0){var _0x543655=_0x5436();return _0x3bbe=function(_0x3bbe58,_0x440211){_0x3bbe58=_0x3bbe58-0x16f;var _0x526ba1=_0x543655[_0x3bbe58];return _0x526ba1;},_0x3bbe(_0x568205,_0x2896c0);}export*from'./msg';export*from'./notify';export*from'./cache';export*from'./constructor';
|
456
src/core.lib/src/entities/msg.d.ts
vendored
456
src/core.lib/src/entities/msg.d.ts
vendored
@@ -1,456 +0,0 @@
|
||||
import { GroupMemberRole } from './group';
|
||||
export interface Peer {
|
||||
chatType: ChatType;
|
||||
peerUid: string;
|
||||
guildId?: string;
|
||||
}
|
||||
export interface KickedOffLineInfo {
|
||||
appId: number;
|
||||
instanceId: number;
|
||||
sameDevice: boolean;
|
||||
tipsDesc: string;
|
||||
tipsTitle: string;
|
||||
kickedType: number;
|
||||
securityKickedType: number;
|
||||
}
|
||||
export interface GetFileListParam {
|
||||
sortType: number;
|
||||
fileCount: number;
|
||||
startIndex: number;
|
||||
sortOrder: number;
|
||||
showOnlinedocFolder: number;
|
||||
}
|
||||
export declare enum ElementType {
|
||||
TEXT = 1,
|
||||
PIC = 2,
|
||||
FILE = 3,
|
||||
PTT = 4,
|
||||
VIDEO = 5,
|
||||
FACE = 6,
|
||||
REPLY = 7,
|
||||
ARK = 10,
|
||||
MFACE = 11,
|
||||
MARKDOWN = 14
|
||||
}
|
||||
export interface SendTextElement {
|
||||
elementType: ElementType.TEXT;
|
||||
elementId: string;
|
||||
textElement: {
|
||||
content: string;
|
||||
atType: number;
|
||||
atUid: string;
|
||||
atTinyId: string;
|
||||
atNtUid: string;
|
||||
};
|
||||
}
|
||||
export interface SendPttElement {
|
||||
elementType: ElementType.PTT;
|
||||
elementId: string;
|
||||
pttElement: {
|
||||
fileName: string;
|
||||
filePath: string;
|
||||
md5HexStr: string;
|
||||
fileSize: number;
|
||||
duration: number;
|
||||
formatType: number;
|
||||
voiceType: number;
|
||||
voiceChangeType: number;
|
||||
canConvert2Text: boolean;
|
||||
waveAmplitudes: number[];
|
||||
fileSubId: string;
|
||||
playState: number;
|
||||
autoConvertText: number;
|
||||
};
|
||||
}
|
||||
export declare enum PicType {
|
||||
gif = 2000,
|
||||
jpg = 1000
|
||||
}
|
||||
export declare enum PicSubType {
|
||||
normal = 0,// 普通图片,大图
|
||||
face = 1
|
||||
}
|
||||
export interface SendPicElement {
|
||||
elementType: ElementType.PIC;
|
||||
elementId: string;
|
||||
picElement: {
|
||||
md5HexStr: string;
|
||||
fileSize: number | string;
|
||||
picWidth: number;
|
||||
picHeight: number;
|
||||
fileName: string;
|
||||
sourcePath: string;
|
||||
original: boolean;
|
||||
picType: PicType;
|
||||
picSubType: PicSubType;
|
||||
fileUuid: string;
|
||||
fileSubId: string;
|
||||
thumbFileSize: number;
|
||||
summary: string;
|
||||
};
|
||||
}
|
||||
export interface SendReplyElement {
|
||||
elementType: ElementType.REPLY;
|
||||
elementId: string;
|
||||
replyElement: {
|
||||
replayMsgSeq: string;
|
||||
replayMsgId: string;
|
||||
senderUin: string;
|
||||
senderUinStr: string;
|
||||
};
|
||||
}
|
||||
export interface SendFaceElement {
|
||||
elementType: ElementType.FACE;
|
||||
elementId: string;
|
||||
faceElement: FaceElement;
|
||||
}
|
||||
export interface SendMarketFaceElement {
|
||||
elementType: ElementType.MFACE;
|
||||
marketFaceElement: MarketFaceElement;
|
||||
}
|
||||
export interface FileElement {
|
||||
fileMd5?: string;
|
||||
fileName: string;
|
||||
filePath: string;
|
||||
fileSize: string;
|
||||
picHeight?: number;
|
||||
picWidth?: number;
|
||||
folderId?: string;
|
||||
picThumbPath?: Map<number, string>;
|
||||
file10MMd5?: string;
|
||||
fileSha?: string;
|
||||
fileSha3?: string;
|
||||
fileUuid?: string;
|
||||
fileSubId?: string;
|
||||
thumbFileSize?: number;
|
||||
fileBizId?: number;
|
||||
}
|
||||
export interface SendFileElement {
|
||||
elementType: ElementType.FILE;
|
||||
elementId: string;
|
||||
fileElement: FileElement;
|
||||
}
|
||||
export interface SendVideoElement {
|
||||
elementType: ElementType.VIDEO;
|
||||
elementId: string;
|
||||
videoElement: VideoElement;
|
||||
}
|
||||
export interface SendArkElement {
|
||||
elementType: ElementType.ARK;
|
||||
elementId: string;
|
||||
arkElement: ArkElement;
|
||||
}
|
||||
export interface SendMarkdownElement {
|
||||
elementType: ElementType.MARKDOWN;
|
||||
elementId: string;
|
||||
markdownElement: MarkdownElement;
|
||||
}
|
||||
export type SendMessageElement = SendTextElement | SendPttElement | SendPicElement | SendReplyElement | SendFaceElement | SendMarketFaceElement | SendFileElement | SendVideoElement | SendArkElement | SendMarkdownElement;
|
||||
export declare enum AtType {
|
||||
notAt = 0,
|
||||
atAll = 1,
|
||||
atUser = 2
|
||||
}
|
||||
export declare enum ChatType {
|
||||
friend = 1,
|
||||
group = 2,
|
||||
chatDevice = 8,//移动设备?
|
||||
temp = 100
|
||||
}
|
||||
export declare enum ChatType2 {
|
||||
KCHATTYPEADELIE = 42,
|
||||
KCHATTYPEBUDDYNOTIFY = 5,
|
||||
KCHATTYPEC2C = 1,
|
||||
KCHATTYPECIRCLE = 113,
|
||||
KCHATTYPEDATALINE = 8,
|
||||
KCHATTYPEDATALINEMQQ = 134,
|
||||
KCHATTYPEDISC = 3,
|
||||
KCHATTYPEFAV = 41,
|
||||
KCHATTYPEGAMEMESSAGE = 105,
|
||||
KCHATTYPEGAMEMESSAGEFOLDER = 116,
|
||||
KCHATTYPEGROUP = 2,
|
||||
KCHATTYPEGROUPBLESS = 133,
|
||||
KCHATTYPEGROUPGUILD = 9,
|
||||
KCHATTYPEGROUPHELPER = 7,
|
||||
KCHATTYPEGROUPNOTIFY = 6,
|
||||
KCHATTYPEGUILD = 4,
|
||||
KCHATTYPEGUILDMETA = 16,
|
||||
KCHATTYPEMATCHFRIEND = 104,
|
||||
KCHATTYPEMATCHFRIENDFOLDER = 109,
|
||||
KCHATTYPENEARBY = 106,
|
||||
KCHATTYPENEARBYASSISTANT = 107,
|
||||
KCHATTYPENEARBYFOLDER = 110,
|
||||
KCHATTYPENEARBYHELLOFOLDER = 112,
|
||||
KCHATTYPENEARBYINTERACT = 108,
|
||||
KCHATTYPEQQNOTIFY = 132,
|
||||
KCHATTYPERELATEACCOUNT = 131,
|
||||
KCHATTYPESERVICEASSISTANT = 118,
|
||||
KCHATTYPESERVICEASSISTANTSUB = 201,
|
||||
KCHATTYPESQUAREPUBLIC = 115,
|
||||
KCHATTYPESUBSCRIBEFOLDER = 30,
|
||||
KCHATTYPETEMPADDRESSBOOK = 111,
|
||||
KCHATTYPETEMPBUSSINESSCRM = 102,
|
||||
KCHATTYPETEMPC2CFROMGROUP = 100,
|
||||
KCHATTYPETEMPC2CFROMUNKNOWN = 99,
|
||||
KCHATTYPETEMPFRIENDVERIFY = 101,
|
||||
KCHATTYPETEMPNEARBYPRO = 119,
|
||||
KCHATTYPETEMPPUBLICACCOUNT = 103,
|
||||
KCHATTYPETEMPWPA = 117,
|
||||
KCHATTYPEUNKNOWN = 0,
|
||||
KCHATTYPEWEIYUN = 40
|
||||
}
|
||||
export interface PttElement {
|
||||
canConvert2Text: boolean;
|
||||
duration: number;
|
||||
fileBizId: null;
|
||||
fileId: number;
|
||||
fileName: string;
|
||||
filePath: string;
|
||||
fileSize: string;
|
||||
fileSubId: string;
|
||||
fileUuid: string;
|
||||
formatType: string;
|
||||
invalidState: number;
|
||||
md5HexStr: string;
|
||||
playState: number;
|
||||
progress: number;
|
||||
text: string;
|
||||
transferStatus: number;
|
||||
translateStatus: number;
|
||||
voiceChangeType: number;
|
||||
voiceType: number;
|
||||
waveAmplitudes: number[];
|
||||
}
|
||||
export interface ArkElement {
|
||||
bytesData: string;
|
||||
linkInfo: null;
|
||||
subElementType: null;
|
||||
}
|
||||
export declare const IMAGE_HTTP_HOST = "https://gchat.qpic.cn";
|
||||
export declare const IMAGE_HTTP_HOST_NT = "https://multimedia.nt.qq.com.cn";
|
||||
export interface PicElement {
|
||||
picSubType?: number;
|
||||
originImageUrl: string;
|
||||
originImageMd5?: string;
|
||||
sourcePath: string;
|
||||
thumbPath: Map<number, string>;
|
||||
picWidth: number;
|
||||
picHeight: number;
|
||||
fileSize: number;
|
||||
fileName: string;
|
||||
fileUuid: string;
|
||||
md5HexStr?: string;
|
||||
}
|
||||
export declare enum GrayTipElementSubType {
|
||||
INVITE_NEW_MEMBER = 12,
|
||||
MEMBER_NEW_TITLE = 17
|
||||
}
|
||||
export interface GrayTipElement {
|
||||
subElementType: GrayTipElementSubType;
|
||||
revokeElement: {
|
||||
operatorRole: string;
|
||||
operatorUid: string;
|
||||
operatorNick: string;
|
||||
operatorRemark: string;
|
||||
operatorMemRemark?: string;
|
||||
wording: string;
|
||||
};
|
||||
aioOpGrayTipElement: TipAioOpGrayTipElement;
|
||||
groupElement: TipGroupElement;
|
||||
xmlElement: {
|
||||
content: string;
|
||||
templId: string;
|
||||
};
|
||||
jsonGrayTipElement: {
|
||||
jsonStr: string;
|
||||
};
|
||||
}
|
||||
export declare enum FaceType {
|
||||
normal = 1,// 小黄脸
|
||||
normal2 = 2,// 新小黄脸, 从faceIndex 222开始?
|
||||
dice = 3
|
||||
}
|
||||
export declare enum FaceIndex {
|
||||
dice = 358,
|
||||
RPS = 359
|
||||
}
|
||||
export interface FaceElement {
|
||||
faceIndex: number;
|
||||
faceType: FaceType;
|
||||
faceText?: string;
|
||||
packId?: string;
|
||||
stickerId?: string;
|
||||
sourceType?: number;
|
||||
stickerType?: number;
|
||||
resultId?: string;
|
||||
surpriseId?: string;
|
||||
randomType?: number;
|
||||
}
|
||||
export interface MarketFaceElement {
|
||||
emojiPackageId: number;
|
||||
faceName: string;
|
||||
emojiId: string;
|
||||
key: string;
|
||||
}
|
||||
export interface VideoElement {
|
||||
filePath: string;
|
||||
fileName: string;
|
||||
videoMd5?: string;
|
||||
thumbMd5?: string;
|
||||
fileTime?: number;
|
||||
thumbSize?: number;
|
||||
fileFormat?: number;
|
||||
fileSize?: string;
|
||||
thumbWidth?: number;
|
||||
thumbHeight?: number;
|
||||
busiType?: 0;
|
||||
subBusiType?: 0;
|
||||
thumbPath?: Map<number, any>;
|
||||
transferStatus?: 0;
|
||||
progress?: 0;
|
||||
invalidState?: 0;
|
||||
fileUuid?: string;
|
||||
fileSubId?: string;
|
||||
fileBizId?: null;
|
||||
originVideoMd5?: string;
|
||||
import_rich_media_context?: null;
|
||||
sourceVideoCodecFormat?: number;
|
||||
}
|
||||
export declare enum viedo_type {
|
||||
VIDEO_FORMAT_AFS = 7,
|
||||
VIDEO_FORMAT_AVI = 1,
|
||||
VIDEO_FORMAT_MKV = 4,
|
||||
VIDEO_FORMAT_MOD = 9,
|
||||
VIDEO_FORMAT_MOV = 8,
|
||||
VIDEO_FORMAT_MP4 = 2,
|
||||
VIDEO_FORMAT_MTS = 11,
|
||||
VIDEO_FORMAT_RM = 6,
|
||||
VIDEO_FORMAT_RMVB = 5,
|
||||
VIDEO_FORMAT_TS = 10,
|
||||
VIDEO_FORMAT_WMV = 3
|
||||
}
|
||||
export interface MarkdownElement {
|
||||
content: string;
|
||||
}
|
||||
export interface InlineKeyboardElementRowButton {
|
||||
id: string;
|
||||
label: string;
|
||||
visitedLabel: string;
|
||||
style: 1;
|
||||
type: 2;
|
||||
clickLimit: 0;
|
||||
unsupportTips: string;
|
||||
data: string;
|
||||
atBotShowChannelList: boolean;
|
||||
permissionType: number;
|
||||
specifyRoleIds: [];
|
||||
specifyTinyids: [];
|
||||
isReply: false;
|
||||
anchor: 0;
|
||||
enter: false;
|
||||
subscribeDataTemplateIds: [];
|
||||
}
|
||||
export interface InlineKeyboardElement {
|
||||
rows: [
|
||||
{
|
||||
buttons: InlineKeyboardElementRowButton[];
|
||||
}
|
||||
];
|
||||
}
|
||||
export interface TipAioOpGrayTipElement {
|
||||
operateType: number;
|
||||
peerUid: string;
|
||||
fromGrpCodeOfTmpChat: string;
|
||||
}
|
||||
export declare enum TipGroupElementType {
|
||||
memberIncrease = 1,
|
||||
kicked = 3,// 被移出群
|
||||
ban = 8
|
||||
}
|
||||
export interface TipGroupElement {
|
||||
type: TipGroupElementType;
|
||||
role: 0;
|
||||
groupName: string;
|
||||
memberUid: string;
|
||||
memberNick: string;
|
||||
memberRemark: string;
|
||||
adminUid: string;
|
||||
adminNick: string;
|
||||
adminRemark: string;
|
||||
createGroup: null;
|
||||
memberAdd?: {
|
||||
showType: 1;
|
||||
otherAdd: null;
|
||||
otherAddByOtherQRCode: null;
|
||||
otherAddByYourQRCode: null;
|
||||
youAddByOtherQRCode: null;
|
||||
otherInviteOther: null;
|
||||
otherInviteYou: null;
|
||||
youInviteOther: null;
|
||||
};
|
||||
shutUp?: {
|
||||
curTime: string;
|
||||
duration: string;
|
||||
admin: {
|
||||
uid: string;
|
||||
card: string;
|
||||
name: string;
|
||||
role: GroupMemberRole;
|
||||
};
|
||||
member: {
|
||||
uid: string;
|
||||
card: string;
|
||||
name: string;
|
||||
role: GroupMemberRole;
|
||||
};
|
||||
};
|
||||
}
|
||||
export interface MultiForwardMsgElement {
|
||||
xmlContent: string;
|
||||
resId: string;
|
||||
fileName: string;
|
||||
}
|
||||
export interface RawMessage {
|
||||
id?: number;
|
||||
msgId: string;
|
||||
msgTime: string;
|
||||
msgSeq: string;
|
||||
msgType: number;
|
||||
subMsgType: number;
|
||||
senderUid: string;
|
||||
senderUin: string;
|
||||
peerUid: string;
|
||||
peerUin: string;
|
||||
sendNickName: string;
|
||||
sendMemberName?: string;
|
||||
chatType: ChatType;
|
||||
sendStatus?: number;
|
||||
recallTime: string;
|
||||
elements: {
|
||||
elementId: string;
|
||||
elementType: ElementType;
|
||||
replyElement: {
|
||||
senderUid: string;
|
||||
sourceMsgIsIncPic: boolean;
|
||||
sourceMsgText: string;
|
||||
replayMsgSeq: string;
|
||||
};
|
||||
textElement: {
|
||||
atType: AtType;
|
||||
atUid: string;
|
||||
content: string;
|
||||
atNtUid: string;
|
||||
};
|
||||
picElement: PicElement;
|
||||
pttElement: PttElement;
|
||||
arkElement: ArkElement;
|
||||
grayTipElement: GrayTipElement;
|
||||
faceElement: FaceElement;
|
||||
videoElement: VideoElement;
|
||||
fileElement: FileElement;
|
||||
marketFaceElement: MarketFaceElement;
|
||||
inlineKeyboardElement: InlineKeyboardElement;
|
||||
markdownElement: MarkdownElement;
|
||||
multiForwardMsgElement: MultiForwardMsgElement;
|
||||
}[];
|
||||
}
|
File diff suppressed because one or more lines are too long
123
src/core.lib/src/entities/notify.d.ts
vendored
123
src/core.lib/src/entities/notify.d.ts
vendored
@@ -1,123 +0,0 @@
|
||||
export declare enum GroupNotifyTypes {
|
||||
INVITE_ME = 1,
|
||||
INVITED_JOIN = 4,// 有人接受了邀请入群
|
||||
JOIN_REQUEST = 7,
|
||||
ADMIN_SET = 8,
|
||||
KICK_MEMBER = 9,
|
||||
MEMBER_EXIT = 11,// 主动退出
|
||||
ADMIN_UNSET = 12,
|
||||
ADMIN_UNSET_OTHER = 13
|
||||
}
|
||||
export interface GroupNotifies {
|
||||
doubt: boolean;
|
||||
nextStartSeq: string;
|
||||
notifies: GroupNotify[];
|
||||
}
|
||||
export declare enum GroupNotifyStatus {
|
||||
IGNORE = 0,
|
||||
WAIT_HANDLE = 1,
|
||||
APPROVE = 2,
|
||||
REJECT = 3
|
||||
}
|
||||
export interface GroupNotify {
|
||||
time: number;
|
||||
seq: string;
|
||||
type: GroupNotifyTypes;
|
||||
status: GroupNotifyStatus;
|
||||
group: {
|
||||
groupCode: string;
|
||||
groupName: string;
|
||||
};
|
||||
user1: {
|
||||
uid: string;
|
||||
nickName: string;
|
||||
};
|
||||
user2: {
|
||||
uid: string;
|
||||
nickName: string;
|
||||
};
|
||||
actionUser: {
|
||||
uid: string;
|
||||
nickName: string;
|
||||
};
|
||||
actionTime: string;
|
||||
invitationExt: {
|
||||
srcType: number;
|
||||
groupCode: string;
|
||||
waitStatus: number;
|
||||
};
|
||||
postscript: string;
|
||||
repeatSeqs: [];
|
||||
warningTips: string;
|
||||
}
|
||||
export declare enum GroupRequestOperateTypes {
|
||||
approve = 1,
|
||||
reject = 2
|
||||
}
|
||||
export declare enum BuddyReqType {
|
||||
KMEINITIATOR = 0,
|
||||
KPEERINITIATOR = 1,
|
||||
KMEAGREED = 2,
|
||||
KMEAGREEDANDADDED = 3,
|
||||
KPEERAGREED = 4,
|
||||
KPEERAGREEDANDADDED = 5,
|
||||
KPEERREFUSED = 6,
|
||||
KMEREFUSED = 7,
|
||||
KMEIGNORED = 8,
|
||||
KMEAGREEANYONE = 9,
|
||||
KMESETQUESTION = 10,
|
||||
KMEAGREEANDADDFAILED = 11,
|
||||
KMSGINFO = 12,
|
||||
KMEINITIATORWAITPEERCONFIRM = 13
|
||||
}
|
||||
export interface FriendRequest {
|
||||
isDecide: boolean;
|
||||
friendUid: string;
|
||||
reqType: BuddyReqType;
|
||||
reqTime: string;
|
||||
extWords: string;
|
||||
isUnread: boolean;
|
||||
friendNick: string;
|
||||
sourceId: number;
|
||||
groupCode: string;
|
||||
}
|
||||
export interface FriendRequestNotify {
|
||||
unreadNums: number;
|
||||
buddyReqs: FriendRequest[];
|
||||
}
|
||||
export declare enum MemberExtSourceType {
|
||||
DEFAULTTYPE = 0,
|
||||
TITLETYPE = 1,
|
||||
NEWGROUPTYPE = 2
|
||||
}
|
||||
export interface GroupExtParam {
|
||||
groupCode: string;
|
||||
seq: string;
|
||||
beginUin: string;
|
||||
dataTime: string;
|
||||
uinList: Array<string>;
|
||||
uinNum: string;
|
||||
groupType: string;
|
||||
richCardNameVer: string;
|
||||
sourceType: MemberExtSourceType;
|
||||
memberExtFilter: {
|
||||
memberLevelInfoUin: number;
|
||||
memberLevelInfoPoint: number;
|
||||
memberLevelInfoActiveDay: number;
|
||||
memberLevelInfoLevel: number;
|
||||
memberLevelInfoName: number;
|
||||
levelName: number;
|
||||
dataTime: number;
|
||||
userShowFlag: number;
|
||||
sysShowFlag: number;
|
||||
timeToUpdate: number;
|
||||
nickName: number;
|
||||
specialTitle: number;
|
||||
levelNameNew: number;
|
||||
userShowFlagNew: number;
|
||||
msgNeedField: number;
|
||||
cmdUinFlagExt3Grocery: number;
|
||||
memberIcon: number;
|
||||
memberInfoSeq: number;
|
||||
};
|
||||
}
|
File diff suppressed because one or more lines are too long
173
src/core.lib/src/entities/user.d.ts
vendored
173
src/core.lib/src/entities/user.d.ts
vendored
@@ -1,173 +0,0 @@
|
||||
export declare enum Sex {
|
||||
male = 1,
|
||||
female = 2,
|
||||
unknown = 255
|
||||
}
|
||||
export interface BuddyCategoryType {
|
||||
categoryId: number;
|
||||
categroyName: string;
|
||||
categroyMbCount: number;
|
||||
buddyList: User[];
|
||||
}
|
||||
export interface ModifyProfileParams {
|
||||
nick: string;
|
||||
longNick: string;
|
||||
sex: Sex;
|
||||
birthday: {
|
||||
birthday_year: string;
|
||||
birthday_month: string;
|
||||
birthday_day: string;
|
||||
};
|
||||
location: any;
|
||||
}
|
||||
export interface BuddyProfileLikeReq {
|
||||
friendUids: string[];
|
||||
basic: number;
|
||||
vote: number;
|
||||
favorite: number;
|
||||
userProfile: number;
|
||||
type: number;
|
||||
start: number;
|
||||
limit: number;
|
||||
}
|
||||
export interface QQLevel {
|
||||
crownNum: number;
|
||||
sunNum: number;
|
||||
moonNum: number;
|
||||
starNum: number;
|
||||
}
|
||||
export interface User {
|
||||
uid: string;
|
||||
uin: string;
|
||||
nick: string;
|
||||
avatarUrl?: string;
|
||||
longNick?: string;
|
||||
remark?: string;
|
||||
sex?: Sex;
|
||||
qqLevel?: QQLevel;
|
||||
qid?: string;
|
||||
birthday_year?: number;
|
||||
birthday_month?: number;
|
||||
birthday_day?: number;
|
||||
topTime?: string;
|
||||
constellation?: number;
|
||||
shengXiao?: number;
|
||||
kBloodType?: number;
|
||||
homeTown?: string;
|
||||
makeFriendCareer?: number;
|
||||
pos?: string;
|
||||
eMail?: string;
|
||||
phoneNum?: string;
|
||||
college?: string;
|
||||
country?: string;
|
||||
province?: string;
|
||||
city?: string;
|
||||
postCode?: string;
|
||||
address?: string;
|
||||
isBlock?: boolean;
|
||||
isSpecialCareOpen?: boolean;
|
||||
isSpecialCareZone?: boolean;
|
||||
ringId?: string;
|
||||
regTime?: number;
|
||||
interest?: string;
|
||||
labels?: string[];
|
||||
isHideQQLevel?: number;
|
||||
privilegeIcon?: {
|
||||
jumpUrl: string;
|
||||
openIconList: unknown[];
|
||||
closeIconList: unknown[];
|
||||
};
|
||||
photoWall?: {
|
||||
picList: unknown[];
|
||||
};
|
||||
vipFlag?: boolean;
|
||||
yearVipFlag?: boolean;
|
||||
svipFlag?: boolean;
|
||||
vipLevel?: number;
|
||||
status?: number;
|
||||
qidianMasterFlag?: number;
|
||||
qidianCrewFlag?: number;
|
||||
qidianCrewFlag2?: number;
|
||||
extStatus?: number;
|
||||
recommendImgFlag?: number;
|
||||
disableEmojiShortCuts?: number;
|
||||
pendantId?: string;
|
||||
}
|
||||
export interface SelfInfo extends User {
|
||||
online?: boolean;
|
||||
}
|
||||
export interface Friend extends User {
|
||||
}
|
||||
export declare enum BizKey {
|
||||
KPRIVILEGEICON = 0,
|
||||
KPHOTOWALL = 1
|
||||
}
|
||||
export interface UserDetailInfoByUin {
|
||||
result: number;
|
||||
errMsg: string;
|
||||
info: {
|
||||
uid: string;
|
||||
qid: string;
|
||||
uin: string;
|
||||
nick: string;
|
||||
remark: string;
|
||||
longNick: string;
|
||||
avatarUrl: string;
|
||||
birthday_year: number;
|
||||
birthday_month: number;
|
||||
birthday_day: number;
|
||||
sex: number;
|
||||
topTime: string;
|
||||
constellation: number;
|
||||
shengXiao: number;
|
||||
kBloodType: number;
|
||||
homeTown: string;
|
||||
makeFriendCareer: number;
|
||||
pos: string;
|
||||
eMail: string;
|
||||
phoneNum: string;
|
||||
college: string;
|
||||
country: string;
|
||||
province: string;
|
||||
city: string;
|
||||
postCode: string;
|
||||
address: string;
|
||||
isBlock: boolean;
|
||||
isSpecialCareOpen: boolean;
|
||||
isSpecialCareZone: boolean;
|
||||
ringId: string;
|
||||
regTime: number;
|
||||
interest: string;
|
||||
termType: number;
|
||||
labels: any[];
|
||||
qqLevel: {
|
||||
crownNum: number;
|
||||
sunNum: number;
|
||||
moonNum: number;
|
||||
starNum: number;
|
||||
};
|
||||
isHideQQLevel: number;
|
||||
privilegeIcon: {
|
||||
jumpUrl: string;
|
||||
openIconList: any[];
|
||||
closeIconList: any[];
|
||||
};
|
||||
isHidePrivilegeIcon: number;
|
||||
photoWall: {
|
||||
picList: any[];
|
||||
};
|
||||
vipFlag: boolean;
|
||||
yearVipFlag: boolean;
|
||||
svipFlag: boolean;
|
||||
vipLevel: number;
|
||||
status: number;
|
||||
qidianMasterFlag: number;
|
||||
qidianCrewFlag: number;
|
||||
qidianCrewFlag2: number;
|
||||
extStatus: number;
|
||||
recommendImgFlag: number;
|
||||
disableEmojiShortCuts: number;
|
||||
pendantId: string;
|
||||
vipNameColorId: string;
|
||||
};
|
||||
}
|
@@ -1 +0,0 @@
|
||||
(function(_0x5650bf,_0xe51e96){var _0x5cd9ab=_0x2cdb,_0x480c63=_0x5650bf();while(!![]){try{var _0x3d0f03=-parseInt(_0x5cd9ab(0x14d))/0x1+parseInt(_0x5cd9ab(0x14f))/0x2*(-parseInt(_0x5cd9ab(0x154))/0x3)+parseInt(_0x5cd9ab(0x151))/0x4+parseInt(_0x5cd9ab(0x15b))/0x5+parseInt(_0x5cd9ab(0x159))/0x6*(parseInt(_0x5cd9ab(0x15a))/0x7)+parseInt(_0x5cd9ab(0x158))/0x8*(-parseInt(_0x5cd9ab(0x14b))/0x9)+-parseInt(_0x5cd9ab(0x155))/0xa;if(_0x3d0f03===_0xe51e96)break;else _0x480c63['push'](_0x480c63['shift']());}catch(_0x434ee3){_0x480c63['push'](_0x480c63['shift']());}}}(_0x4d56,0xed20a));export var Sex;function _0x2cdb(_0x3d5b1c,_0x1fbd7c){var _0x4d5635=_0x4d56();return _0x2cdb=function(_0x2cdb84,_0x2fde94){_0x2cdb84=_0x2cdb84-0x14b;var _0x327e8e=_0x4d5635[_0x2cdb84];return _0x327e8e;},_0x2cdb(_0x3d5b1c,_0x1fbd7c);}function _0x4d56(){var _0x3b1b50=['9ywjKCE','female','6755SmnXtB','RaDUz','44134qWRnuW','bBzeI','6933932slYrkw','male','KPHOTOWALL','78JYBxIs','10854850MpxAVM','cSRtr','unknown','13097944VlTEkL','11886XHQVqz','2828svUqbe','8703460KgfOhI'];_0x4d56=function(){return _0x3b1b50;};return _0x4d56();}(function(_0x573086){var _0x4a64b5=_0x2cdb,_0x50bbe0={'BuehO':_0x4a64b5(0x14c),'bBzeI':_0x4a64b5(0x157)};_0x573086[_0x573086[_0x4a64b5(0x152)]=0x1]='male',_0x573086[_0x573086[_0x50bbe0['BuehO']]=0x2]=_0x50bbe0['BuehO'],_0x573086[_0x573086[_0x50bbe0[_0x4a64b5(0x150)]]=0xff]='unknown';}(Sex||(Sex={})));export var BizKey;(function(_0x25af09){var _0xbbd430=_0x2cdb,_0xcbd994={'cSRtr':'KPRIVILEGEICON','RaDUz':_0xbbd430(0x153)};_0x25af09[_0x25af09[_0xcbd994[_0xbbd430(0x156)]]=0x0]=_0xcbd994[_0xbbd430(0x156)],_0x25af09[_0x25af09[_0xcbd994['RaDUz']]=0x1]=_0xcbd994[_0xbbd430(0x14e)];}(BizKey||(BizKey={})));
|
@@ -1 +0,0 @@
|
||||
(function(_0x5a611f,_0x3308b1){var _0x31267f=_0x3daa,_0x2a0ebf=_0x5a611f();while(!![]){try{var _0x4c8c78=-parseInt(_0x31267f(0x182))/0x1*(-parseInt(_0x31267f(0x17f))/0x2)+-parseInt(_0x31267f(0x186))/0x3*(-parseInt(_0x31267f(0x17e))/0x4)+-parseInt(_0x31267f(0x188))/0x5*(parseInt(_0x31267f(0x187))/0x6)+-parseInt(_0x31267f(0x180))/0x7+parseInt(_0x31267f(0x183))/0x8+parseInt(_0x31267f(0x181))/0x9*(-parseInt(_0x31267f(0x189))/0xa)+-parseInt(_0x31267f(0x185))/0xb*(-parseInt(_0x31267f(0x184))/0xc);if(_0x4c8c78===_0x3308b1)break;else _0x2a0ebf['push'](_0x2a0ebf['shift']());}catch(_0x5cb6b8){_0x2a0ebf['push'](_0x2a0ebf['shift']());}}}(_0x44d9,0xc66d6));import _0x21ae4a from'./wrapper';export*from'./adapters';function _0x3daa(_0x4c5ad3,_0x1c5bf5){var _0x44d917=_0x44d9();return _0x3daa=function(_0x3daaab,_0x43bb68){_0x3daaab=_0x3daaab-0x17e;var _0x3abd90=_0x44d917[_0x3daaab];return _0x3abd90;},_0x3daa(_0x4c5ad3,_0x1c5bf5);}export*from'./apis';export*from'./entities';export*from'./listeners';export*from'./services';export*as Adapters from'./adapters';export*as APIs from'./apis';export*as Entities from'./entities';export*as Listeners from'./listeners';function _0x44d9(){var _0x6bcbcc=['215qKWFmZ','9280znJdEW','159684aKOSlB','4mhrhJq','11122125dhrXkz','5409KDpclF','95219dOgrzz','2176728ugeRXJ','118452QZoXkP','3223emvWXb','48IaQoAP','144294OmMqDZ'];_0x44d9=function(){return _0x6bcbcc;};return _0x44d9();}export*as Services from'./services';export{_0x21ae4a as Wrapper};export*as WrapperInterface from'./wrapper';export*as SessionConfig from'./sessionConfig';export{napCatCore}from'./core';
|
@@ -1,44 +0,0 @@
|
||||
import { BuddyCategoryType, FriendRequestNotify } from '@/core/entities';
|
||||
export type OnBuddyChangeParams = BuddyCategoryType[];
|
||||
interface IBuddyListener {
|
||||
onBuddyListChange(arg: OnBuddyChangeParams): void;
|
||||
onBuddyInfoChange(arg: unknown): void;
|
||||
onBuddyDetailInfoChange(arg: unknown): void;
|
||||
onNickUpdated(arg: unknown): void;
|
||||
onBuddyRemarkUpdated(arg: unknown): void;
|
||||
onAvatarUrlUpdated(arg: unknown): void;
|
||||
onBuddyReqChange(arg: FriendRequestNotify): void;
|
||||
onBuddyReqUnreadCntChange(arg: unknown): void;
|
||||
onCheckBuddySettingResult(arg: unknown): void;
|
||||
onAddBuddyNeedVerify(arg: unknown): void;
|
||||
onSmartInfos(arg: unknown): void;
|
||||
onSpacePermissionInfos(arg: unknown): void;
|
||||
onDoubtBuddyReqChange(arg: unknown): void;
|
||||
onDoubtBuddyReqUnreadNumChange(arg: unknown): void;
|
||||
onBlockChanged(arg: unknown): void;
|
||||
onAddMeSettingChanged(arg: unknown): void;
|
||||
onDelBatchBuddyInfos(arg: unknown): void;
|
||||
}
|
||||
export interface NodeIKernelBuddyListener extends IBuddyListener {
|
||||
new (listener: IBuddyListener): NodeIKernelBuddyListener;
|
||||
}
|
||||
export declare class BuddyListener implements IBuddyListener {
|
||||
onAddBuddyNeedVerify(arg: unknown): void;
|
||||
onAddMeSettingChanged(arg: unknown): void;
|
||||
onAvatarUrlUpdated(arg: unknown): void;
|
||||
onBlockChanged(arg: unknown): void;
|
||||
onBuddyDetailInfoChange(arg: unknown): void;
|
||||
onBuddyInfoChange(arg: unknown): void;
|
||||
onBuddyListChange(arg: OnBuddyChangeParams): void;
|
||||
onBuddyRemarkUpdated(arg: unknown): void;
|
||||
onBuddyReqChange(arg: FriendRequestNotify): void;
|
||||
onBuddyReqUnreadCntChange(arg: unknown): void;
|
||||
onCheckBuddySettingResult(arg: unknown): void;
|
||||
onDelBatchBuddyInfos(arg: unknown): void;
|
||||
onDoubtBuddyReqChange(arg: unknown): void;
|
||||
onDoubtBuddyReqUnreadNumChange(arg: unknown): void;
|
||||
onNickUpdated(arg: unknown): void;
|
||||
onSmartInfos(arg: unknown): void;
|
||||
onSpacePermissionInfos(arg: unknown): void;
|
||||
}
|
||||
export {};
|
@@ -1 +0,0 @@
|
||||
var _0x477372=_0x2171;(function(_0x2ad203,_0x423810){var _0x558daf=_0x2171,_0x300753=_0x2ad203();while(!![]){try{var _0x33e68d=-parseInt(_0x558daf(0x16c))/0x1*(parseInt(_0x558daf(0x15c))/0x2)+-parseInt(_0x558daf(0x166))/0x3+parseInt(_0x558daf(0x15f))/0x4+-parseInt(_0x558daf(0x16d))/0x5*(-parseInt(_0x558daf(0x168))/0x6)+-parseInt(_0x558daf(0x170))/0x7*(-parseInt(_0x558daf(0x15d))/0x8)+parseInt(_0x558daf(0x163))/0x9+-parseInt(_0x558daf(0x16e))/0xa;if(_0x33e68d===_0x423810)break;else _0x300753['push'](_0x300753['shift']());}catch(_0x4f47a8){_0x300753['push'](_0x300753['shift']());}}}(_0x2104,0x6cf10));function _0x2104(){var _0x5aaa06=['13779210izOZGL','onDelBatchBuddyInfos','70cMqgUd','514IrQDUC','57040BrMOct','onDoubtBuddyReqChange','3409168HlykBs','onDoubtBuddyReqUnreadNumChange','onBuddyReqChange','onBuddyInfoChange','5516109lQjldF','onAddMeSettingChanged','onCheckBuddySettingResult','758109uHryOs','onBuddyListChange','12bgyFCZ','onBuddyRemarkUpdated','onAvatarUrlUpdated','onSmartInfos','941snrSNN','1955480XcbUks'];_0x2104=function(){return _0x5aaa06;};return _0x2104();}function _0x2171(_0x2b9791,_0x38032c){var _0x210405=_0x2104();return _0x2171=function(_0x217105,_0x103c23){_0x217105=_0x217105-0x15c;var _0x2b76d9=_0x210405[_0x217105];return _0x2b76d9;},_0x2171(_0x2b9791,_0x38032c);}export class BuddyListener{['onAddBuddyNeedVerify'](_0x4e8c35){}[_0x477372(0x164)](_0x20ba98){}[_0x477372(0x16a)](_0x487844){}['onBlockChanged'](_0x32f80a){}['onBuddyDetailInfoChange'](_0x3d6623){}[_0x477372(0x162)](_0x11e90c){}[_0x477372(0x167)](_0x25273c){}[_0x477372(0x169)](_0x3942eb){}[_0x477372(0x161)](_0x286132){}['onBuddyReqUnreadCntChange'](_0x3d91a2){}[_0x477372(0x165)](_0x464114){}[_0x477372(0x16f)](_0x21a880){}[_0x477372(0x15e)](_0x46729d){}[_0x477372(0x160)](_0x21af9a){}['onNickUpdated'](_0xa5bf38){}[_0x477372(0x16b)](_0x5a3472){}['onSpacePermissionInfos'](_0x2c2cb5){}}
|
@@ -1,17 +0,0 @@
|
||||
export interface IKernelFileAssistantListener {
|
||||
onFileStatusChanged(...args: unknown[]): unknown;
|
||||
onSessionListChanged(...args: unknown[]): unknown;
|
||||
onSessionChanged(...args: unknown[]): unknown;
|
||||
onFileListChanged(...args: unknown[]): unknown;
|
||||
onFileSearch(...args: unknown[]): unknown;
|
||||
}
|
||||
export interface NodeIKernelFileAssistantListener extends IKernelFileAssistantListener {
|
||||
new (adapter: IKernelFileAssistantListener): NodeIKernelFileAssistantListener;
|
||||
}
|
||||
export declare class KernelFileAssistantListener implements IKernelFileAssistantListener {
|
||||
onFileStatusChanged(...args: unknown[]): void;
|
||||
onSessionListChanged(...args: unknown[]): void;
|
||||
onSessionChanged(...args: unknown[]): void;
|
||||
onFileListChanged(...args: unknown[]): void;
|
||||
onFileSearch(...args: unknown[]): void;
|
||||
}
|
@@ -1 +0,0 @@
|
||||
function _0x3323(_0x5b4b05,_0x20a3a4){var _0x452b78=_0x452b();return _0x3323=function(_0x332358,_0x4ae1d5){_0x332358=_0x332358-0x1c8;var _0x50e617=_0x452b78[_0x332358];return _0x50e617;},_0x3323(_0x5b4b05,_0x20a3a4);}var _0x53c6ac=_0x3323;(function(_0x4d86b1,_0x1a34c5){var _0x3682cb=_0x3323,_0x19b1af=_0x4d86b1();while(!![]){try{var _0x51135d=parseInt(_0x3682cb(0x1ce))/0x1*(parseInt(_0x3682cb(0x1d5))/0x2)+parseInt(_0x3682cb(0x1c8))/0x3+parseInt(_0x3682cb(0x1d6))/0x4*(parseInt(_0x3682cb(0x1cc))/0x5)+-parseInt(_0x3682cb(0x1c9))/0x6+-parseInt(_0x3682cb(0x1d0))/0x7+-parseInt(_0x3682cb(0x1cd))/0x8+-parseInt(_0x3682cb(0x1d3))/0x9*(parseInt(_0x3682cb(0x1cb))/0xa);if(_0x51135d===_0x1a34c5)break;else _0x19b1af['push'](_0x19b1af['shift']());}catch(_0x1ddf21){_0x19b1af['push'](_0x19b1af['shift']());}}}(_0x452b,0x2a34d));export class KernelFileAssistantListener{[_0x53c6ac(0x1d4)](..._0x51e8d6){}[_0x53c6ac(0x1cf)](..._0x24d1bc){}[_0x53c6ac(0x1d2)](..._0x593c69){}[_0x53c6ac(0x1d1)](..._0x41b7be){}[_0x53c6ac(0x1ca)](..._0x4fa8d4){}}function _0x452b(){var _0x14b4e0=['297724pndVNW','onFileListChanged','onSessionChanged','108063DGZRyN','onFileStatusChanged','698gfoKBH','1360484DUWEiL','926808LsNijs','1150446wlxYFY','onFileSearch','270BETNBR','5VgQKYd','1902008AgwduO','917DFolBt','onSessionListChanged'];_0x452b=function(){return _0x14b4e0;};return _0x452b();}
|
@@ -1,95 +0,0 @@
|
||||
import { Group, GroupMember, GroupNotify } from '@/core/entities';
|
||||
interface IGroupListener {
|
||||
onGroupListUpdate(updateType: number, groupList: Group[]): void;
|
||||
onGroupExtListUpdate(...args: unknown[]): void;
|
||||
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]): void;
|
||||
onGroupNotifiesUpdated(dboubt: boolean, notifies: GroupNotify[]): void;
|
||||
onGroupNotifiesUnreadCountUpdated(...args: unknown[]): void;
|
||||
onGroupDetailInfoChange(...args: unknown[]): void;
|
||||
onGroupAllInfoChange(...args: unknown[]): void;
|
||||
onGroupsMsgMaskResult(...args: unknown[]): void;
|
||||
onGroupConfMemberChange(...args: unknown[]): void;
|
||||
onGroupBulletinChange(...args: unknown[]): void;
|
||||
onGetGroupBulletinListResult(...args: unknown[]): void;
|
||||
onMemberListChange(arg: {
|
||||
sceneId: string;
|
||||
ids: string[];
|
||||
infos: Map<string, GroupMember>;
|
||||
finish: boolean;
|
||||
hasRobot: boolean;
|
||||
}): void;
|
||||
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>): void;
|
||||
onSearchMemberChange(...args: unknown[]): void;
|
||||
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]): void;
|
||||
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]): void;
|
||||
onGroupStatisticInfoChange(...args: unknown[]): void;
|
||||
onJoinGroupNotify(...args: unknown[]): void;
|
||||
onShutUpMemberListChanged(...args: unknown[]): void;
|
||||
onGroupBulletinRemindNotify(...args: unknown[]): void;
|
||||
onGroupFirstBulletinNotify(...args: unknown[]): void;
|
||||
onJoinGroupNoVerifyFlag(...args: unknown[]): void;
|
||||
onGroupArkInviteStateResult(...args: unknown[]): void;
|
||||
onGroupMemberLevelInfoChange(...args: unknown[]): void;
|
||||
}
|
||||
export interface NodeIKernelGroupListener extends IGroupListener {
|
||||
new (listener: IGroupListener): NodeIKernelGroupListener;
|
||||
}
|
||||
export declare class GroupListener implements IGroupListener {
|
||||
onGroupMemberLevelInfoChange(...args: unknown[]): void;
|
||||
onGetGroupBulletinListResult(...args: unknown[]): void;
|
||||
onGroupAllInfoChange(...args: unknown[]): void;
|
||||
onGroupBulletinChange(...args: unknown[]): void;
|
||||
onGroupBulletinRemindNotify(...args: unknown[]): void;
|
||||
onGroupArkInviteStateResult(...args: unknown[]): void;
|
||||
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]): void;
|
||||
onGroupConfMemberChange(...args: unknown[]): void;
|
||||
onGroupDetailInfoChange(...args: unknown[]): void;
|
||||
onGroupExtListUpdate(...args: unknown[]): void;
|
||||
onGroupFirstBulletinNotify(...args: unknown[]): void;
|
||||
onGroupListUpdate(updateType: number, groupList: Group[]): void;
|
||||
onGroupNotifiesUpdated(dboubt: boolean, notifies: GroupNotify[]): void;
|
||||
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]): void;
|
||||
onGroupNotifiesUnreadCountUpdated(...args: unknown[]): void;
|
||||
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]): void;
|
||||
onGroupsMsgMaskResult(...args: unknown[]): void;
|
||||
onGroupStatisticInfoChange(...args: unknown[]): void;
|
||||
onJoinGroupNotify(...args: unknown[]): void;
|
||||
onJoinGroupNoVerifyFlag(...args: unknown[]): void;
|
||||
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>): void;
|
||||
onMemberListChange(arg: {
|
||||
sceneId: string;
|
||||
ids: string[];
|
||||
infos: Map<string, GroupMember>;
|
||||
finish: boolean;
|
||||
hasRobot: boolean;
|
||||
}): void;
|
||||
onSearchMemberChange(...args: unknown[]): void;
|
||||
onShutUpMemberListChanged(...args: unknown[]): void;
|
||||
}
|
||||
export declare class DebugGroupListener implements IGroupListener {
|
||||
onGroupMemberLevelInfoChange(...args: unknown[]): void;
|
||||
onGetGroupBulletinListResult(...args: unknown[]): void;
|
||||
onGroupAllInfoChange(...args: unknown[]): void;
|
||||
onGroupBulletinChange(...args: unknown[]): void;
|
||||
onGroupBulletinRemindNotify(...args: unknown[]): void;
|
||||
onGroupArkInviteStateResult(...args: unknown[]): void;
|
||||
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]): void;
|
||||
onGroupConfMemberChange(...args: unknown[]): void;
|
||||
onGroupDetailInfoChange(...args: unknown[]): void;
|
||||
onGroupExtListUpdate(...args: unknown[]): void;
|
||||
onGroupFirstBulletinNotify(...args: unknown[]): void;
|
||||
onGroupListUpdate(...args: unknown[]): void;
|
||||
onGroupNotifiesUpdated(...args: unknown[]): void;
|
||||
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]): void;
|
||||
onGroupNotifiesUnreadCountUpdated(...args: unknown[]): void;
|
||||
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]): void;
|
||||
onGroupsMsgMaskResult(...args: unknown[]): void;
|
||||
onGroupStatisticInfoChange(...args: unknown[]): void;
|
||||
onJoinGroupNotify(...args: unknown[]): void;
|
||||
onJoinGroupNoVerifyFlag(...args: unknown[]): void;
|
||||
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>): void;
|
||||
onMemberListChange(...args: unknown[]): void;
|
||||
onSearchMemberChange(...args: unknown[]): void;
|
||||
onShutUpMemberListChanged(...args: unknown[]): void;
|
||||
}
|
||||
export {};
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user