mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-03-01 08:10:25 +00:00
Compare commits
79 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32d3ff6998 | ||
|
|
84f0e0f9a0 | ||
|
|
8697061a90 | ||
|
|
872a3e0100 | ||
|
|
4fcbdc4d89 | ||
|
|
176af14915 | ||
|
|
81cf1fd98e | ||
|
|
5189099146 | ||
|
|
7fc17d45ba | ||
|
|
c54f74609e | ||
|
|
a2d7ac4878 | ||
|
|
fd0afa3b25 | ||
|
|
7685cc3dfc | ||
|
|
f9c0b9d106 | ||
|
|
d31f0a45b4 | ||
|
|
7c701781a1 | ||
|
|
3c612e03ff | ||
|
|
f27db01145 | ||
|
|
ae97cfba03 | ||
|
|
162ddc1bf5 | ||
|
|
afb6ef421a | ||
|
|
173a165c4b | ||
|
|
d525f9b03d | ||
|
|
f2ba789cc0 | ||
|
|
2cdc9bdc09 | ||
|
|
c123b34d5f | ||
|
|
d25b43ebf2 | ||
|
|
8fe4a9e6ac | ||
|
|
09da80aad5 | ||
|
|
3d3f718fd5 | ||
|
|
6068abdec0 | ||
|
|
3957d7af5a | ||
|
|
a2837974fe | ||
|
|
6f8edfe570 | ||
|
|
0b655db4dd | ||
|
|
d800466a30 | ||
|
|
fa80441e36 | ||
|
|
1990761ad6 | ||
|
|
ef63812391 | ||
|
|
0f033b0ac8 | ||
|
|
9fdef3cde9 | ||
|
|
20e8643193 | ||
|
|
8645ed4d9d | ||
|
|
c0b9817ff5 | ||
|
|
b147e57c1c | ||
|
|
ad4a108781 | ||
|
|
df824d77ae | ||
|
|
19888d52dc | ||
|
|
4dc8b3ed3b | ||
|
|
8df54d5cd3 | ||
|
|
aa982b3071 | ||
|
|
8e71dec63a | ||
|
|
31bb1e5dee | ||
|
|
75e1e8dd79 | ||
|
|
d32ccc6eb5 | ||
|
|
7b3e94d568 | ||
|
|
5cfe479044 | ||
|
|
f04ffa5dc6 | ||
|
|
a2a73ce2dd | ||
|
|
66d02eeb6a | ||
|
|
b99c0ca437 | ||
|
|
019b90984d | ||
|
|
5043a49779 | ||
|
|
36aa08a8f5 | ||
|
|
8bc8df32f9 | ||
|
|
bc183ae002 | ||
|
|
b85f9197e3 | ||
|
|
c8fd66fa9b | ||
|
|
6e9f448a0c | ||
|
|
142016778f | ||
|
|
159fb8cd3a | ||
|
|
01c911e178 | ||
|
|
8b3ea8dcef | ||
|
|
fe8b270ab3 | ||
|
|
f02ae5894f | ||
|
|
a6a0b408af | ||
|
|
e9856ac80f | ||
|
|
f553f9dc8d | ||
|
|
5608638e9a |
8
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
8
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
name: Bug 反馈
|
name: Bug 反馈
|
||||||
description: 报告可能的 NapCat 异常行为
|
description: 报告可能的 NapCat 异常行为
|
||||||
title: '[BUG] '
|
title: "[BUG] "
|
||||||
labels: bug
|
labels: bug
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
@@ -10,6 +10,10 @@ body:
|
|||||||
在提交新的 Bug 反馈前,请确保您:
|
在提交新的 Bug 反馈前,请确保您:
|
||||||
* 已经搜索了现有的 issues,并且没有找到可以解决您问题的方法
|
* 已经搜索了现有的 issues,并且没有找到可以解决您问题的方法
|
||||||
* 不与现有的某一 issue 重复
|
* 不与现有的某一 issue 重复
|
||||||
|
* **不接受因发送不当内容而导致的问题报告**
|
||||||
|
- 包括但不限于:多媒体发送失败、转发消息失败、消息被拦截等因 18+ 内容、违规内容或触发风控的问题
|
||||||
|
- 提交 issue 前,请确认您发送的多媒体内容、链接、文本等均为正常合规内容,不会触发平台风控机制
|
||||||
|
- 因违规内容导致的问题,一律不予受理
|
||||||
- type: input
|
- type: input
|
||||||
id: system-version
|
id: system-version
|
||||||
attributes:
|
attributes:
|
||||||
@@ -30,7 +34,7 @@ body:
|
|||||||
id: napcat-version
|
id: napcat-version
|
||||||
attributes:
|
attributes:
|
||||||
label: NapCat 版本
|
label: NapCat 版本
|
||||||
description: 可在 LiteLoaderQQNT 的设置页或是 QQNT 的设置页侧栏中找到
|
description: 可在 WebUI 的「系统信息」页中找到
|
||||||
placeholder: 1.0.0
|
placeholder: 1.0.0
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
60
.github/ISSUE_TEMPLATE/feat_request.yml
vendored
Normal file
60
.github/ISSUE_TEMPLATE/feat_request.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: Feat 请求
|
||||||
|
description: 提交新的 NapCat 功能或改进建议
|
||||||
|
title: '[FEAT] '
|
||||||
|
labels: enhancement
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
欢迎来到 NapCat 的 Issue Tracker!请填写以下表格来提交功能请求。
|
||||||
|
在提交新的功能请求前,请确保您:
|
||||||
|
* 已经搜索了现有的 issues,并且没有找到类似的建议
|
||||||
|
* 不与现有的某一 issue 重复
|
||||||
|
- type: input
|
||||||
|
id: system-version
|
||||||
|
attributes:
|
||||||
|
label: 系统版本
|
||||||
|
description: 运行 QQNT 的系统版本
|
||||||
|
placeholder: Windows 11 24H2
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: qqnt-version
|
||||||
|
attributes:
|
||||||
|
label: QQNT 版本
|
||||||
|
description: 可在 QQNT 的「关于」的设置页中找到
|
||||||
|
placeholder: 9.9.16-29927
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: input
|
||||||
|
id: napcat-version
|
||||||
|
attributes:
|
||||||
|
label: NapCat 版本
|
||||||
|
description: 可在 WebUI 的「系统信息」页中找到
|
||||||
|
placeholder: 1.0.0
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: feature-description
|
||||||
|
attributes:
|
||||||
|
label: 功能描述
|
||||||
|
description: 请详细描述你希望添加的功能或改进
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: feature-reason
|
||||||
|
attributes:
|
||||||
|
label: 需求背景与理由
|
||||||
|
description: 请说明为什么需要这个功能,解决了什么问题
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
- type: textarea
|
||||||
|
id: feature-expected
|
||||||
|
attributes:
|
||||||
|
label: 期望的实现方式或效果
|
||||||
|
description: 请描述你期望的功能实现方式或最终效果
|
||||||
|
- type: textarea
|
||||||
|
id: other-info
|
||||||
|
attributes:
|
||||||
|
label: 其他补充信息
|
||||||
|
description: 你还想补充什么?
|
||||||
329
.github/workflows/auto-release.yml
vendored
329
.github/workflows/auto-release.yml
vendored
@@ -1,262 +1,83 @@
|
|||||||
name: AI RELEASE NapCat
|
name: Auto Release Docker
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
release:
|
||||||
push:
|
types: [published]
|
||||||
tags:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
permissions: write-all
|
|
||||||
|
|
||||||
env:
|
|
||||||
OPENROUTER_API_URL: https://openrouter.ai/api/v1/chat/completions
|
|
||||||
OPENROUTER_MODEL: "openrouter/auto"
|
|
||||||
RELEASE_NAME: "NapCat"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build-LiteLoader:
|
shell-docker:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone Main Repository
|
- name: Trigger NapCat-Docker docker-publish workflow
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Use Node.js 20.X
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20.x
|
|
||||||
- name: Build NapCat.Framework
|
|
||||||
run: |
|
|
||||||
npm i -g pnpm
|
|
||||||
pnpm i
|
|
||||||
pnpm --filter napcat-webui-frontend run build || exit 1
|
|
||||||
pnpm run build:framework
|
|
||||||
mv packages/napcat-framework/dist framework-dist
|
|
||||||
cd framework-dist
|
|
||||||
npm install --omit=dev
|
|
||||||
rm ./package-lock.json || exit 0
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: NapCat.Framework
|
|
||||||
path: framework-dist
|
|
||||||
|
|
||||||
Build-Shell:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Clone Main Repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Use Node.js 20.X
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 20.x
|
|
||||||
- name: Build NapCat.Shell
|
|
||||||
run: |
|
|
||||||
npm i -g pnpm
|
|
||||||
pnpm i
|
|
||||||
pnpm --filter napcat-webui-frontend run build || exit 1
|
|
||||||
pnpm run build:shell
|
|
||||||
mv packages/napcat-shell/dist shell-dist
|
|
||||||
cd shell-dist
|
|
||||||
npm install --omit=dev
|
|
||||||
rm ./package-lock.json || exit 0
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: NapCat.Shell
|
|
||||||
path: shell-dist
|
|
||||||
Download-QNX64:
|
|
||||||
needs: Build-Shell
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Download Artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: ./artifacts
|
|
||||||
|
|
||||||
- name: Setup tools
|
|
||||||
run: |
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y aria2 unzip zip p7zip-full curl jq
|
|
||||||
|
|
||||||
- name: Download QQ x64, Node.js and Assemble NapCat.Shell.Windows.Node.zip
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
TMPDIR=$(mktemp -d)
|
|
||||||
cd "$TMPDIR"
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 1) 下载 QQ x64
|
|
||||||
# -----------------------------
|
|
||||||
JS_URL="https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/windowsConfig.js"
|
|
||||||
NT_URL=$(curl -fsSL "$JS_URL" | grep -oP '"ntDownloadX64Url"\s*:\s*"\K[^"]+')
|
|
||||||
QQ_ZIP="$(basename "$NT_URL")"
|
|
||||||
aria2c -x16 -s16 -k1M -o "$QQ_ZIP" "$NT_URL"
|
|
||||||
|
|
||||||
QQ_EXTRACT="$TMPDIR/qq_extracted"
|
|
||||||
mkdir -p "$QQ_EXTRACT"
|
|
||||||
7z x -y -o"$QQ_EXTRACT" "$QQ_ZIP" >/dev/null
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 2) 下载 Node.js Windows x64 zip 22.11.0
|
|
||||||
# -----------------------------
|
|
||||||
NODE_VER="22.11.0"
|
|
||||||
NODE_URL="https://nodejs.org/dist/v$NODE_VER/node-v$NODE_VER-win-x64.zip"
|
|
||||||
NODE_ZIP="node-v$NODE_VER-win-x64.zip"
|
|
||||||
aria2c -x1 -s1 -k1M -o "$NODE_ZIP" "$NODE_URL"
|
|
||||||
|
|
||||||
NODE_EXTRACT="$TMPDIR/node_extracted"
|
|
||||||
mkdir -p "$NODE_EXTRACT"
|
|
||||||
unzip -q "$NODE_ZIP" -d "$NODE_EXTRACT"
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 3) 创建输出目录
|
|
||||||
# -----------------------------
|
|
||||||
OUT_DIR="$GITHUB_WORKSPACE/NapCat.Shell.Windows.Node"
|
|
||||||
mkdir -p "$OUT_DIR/NapCat.Shell.Windows.Node"
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 4) 解压 NapCat.Shell.zip 到 napcat
|
|
||||||
# -----------------------------
|
|
||||||
cp -a "$GITHUB_WORKSPACE/artifacts/NapCat.Shell/." "$OUT_DIR/napcat/"
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 5) 拷贝 QQ 文件到 NapCat.Shell.Windows.Node
|
|
||||||
# -----------------------------
|
|
||||||
QQ_TARGETS=("avif_convert.dll" "broadcast_ipc.dll" "config.json" "libglib-2.0-0.dll" "libgobject-2.0-0.dll" "libvips-42.dll" "ncnn.dll" "opencv.dll" "package.json" "QBar.dll" "wrapper.node")
|
|
||||||
for name in "${QQ_TARGETS[@]}"; do
|
|
||||||
find "$QQ_EXTRACT" -iname "$name" -exec cp -a {} "$OUT_DIR" \; || true
|
|
||||||
done
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 6) 拷贝仓库文件 napcat.bat 和 index.js
|
|
||||||
# -----------------------------
|
|
||||||
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/napcat.bat" "$OUT_DIR/" || true
|
|
||||||
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/index.js" "$OUT_DIR/" || true
|
|
||||||
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/QQNT.dll" "$OUT_DIR/" || true
|
|
||||||
# -----------------------------
|
|
||||||
# 7) 拷贝 Node.exe 到 NapCat.Shell.Windows.Node
|
|
||||||
# -----------------------------
|
|
||||||
cp -a "$NODE_EXTRACT/node-v$NODE_VER-win-x64/node.exe" "$OUT_DIR/" || true
|
|
||||||
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: NapCat.Shell.Windows.Node
|
|
||||||
path: NapCat.Shell.Windows.Node
|
|
||||||
|
|
||||||
release-napcat:
|
|
||||||
needs: [Build-LiteLoader, Build-Shell, Download-QNX64]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Download Artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: ./artifacts
|
|
||||||
|
|
||||||
- name: Zip Artifacts
|
|
||||||
run: |
|
|
||||||
cd artifacts
|
|
||||||
[ -d NapCat.Framework ] && (cd NapCat.Framework && zip -qr ../../NapCat.Framework.zip .)
|
|
||||||
[ -d NapCat.Shell ] && (cd NapCat.Shell && zip -qr ../../NapCat.Shell.zip .)
|
|
||||||
[ -d NapCat.Shell.Windows.Node ] && (cd NapCat.Shell.Windows.Node && zip -qr ../../NapCat.Shell.Windows.Node.zip .)
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
- name: Generate release note via OpenRouter
|
|
||||||
env:
|
env:
|
||||||
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||||
OPENROUTER_API_URL: ${{ env.OPENROUTER_API_URL }}
|
|
||||||
OPENROUTER_MODEL: ${{ env.OPENROUTER_MODEL }}
|
|
||||||
GITHUB_OWNER: "NapNeKo" # 替换成你的 repo owner
|
|
||||||
GITHUB_REPO: "NapCatQQ" # 替换成你的 repo 名
|
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
curl -X POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
# 当前 tag
|
-H "Authorization: Bearer $GH_TOKEN" \
|
||||||
CURRENT_TAG="${GITHUB_REF#refs/tags/}"
|
https://api.github.com/repos/NapNeko/NapCat-Docker/actions/workflows/docker-publish.yml/dispatches \
|
||||||
echo "Current tag: $CURRENT_TAG"
|
-d '{"ref":"main"}'
|
||||||
|
framework-docker:
|
||||||
# 从 GitHub API 获取 tag 列表
|
runs-on: ubuntu-latest
|
||||||
TAGS_JSON=$(curl -s "https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/tags?per_page=100")
|
steps:
|
||||||
TAGS=( $(echo "$TAGS_JSON" | jq -r '.[].name' | sort -V) )
|
- name: Trigger NapCat-Framework-Docker docker-publish workflow
|
||||||
|
env:
|
||||||
# 找到上一个 tag
|
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||||
PREV_TAG=""
|
run: |
|
||||||
for i in "${!TAGS[@]}"; do
|
curl -X POST \
|
||||||
if [ "${TAGS[$i]}" = "$CURRENT_TAG" ]; then
|
-H "Accept: application/vnd.github+json" \
|
||||||
if [ $i -gt 0 ]; then
|
-H "Authorization: Bearer $GH_TOKEN" \
|
||||||
PREV_TAG="${TAGS[$((i-1))]}"
|
https://api.github.com/repos/NapNeko/NapCat.Docker.Framework/actions/workflows/docker-image.yml/dispatches \
|
||||||
fi
|
-d '{"ref":"main"}'
|
||||||
break
|
appimage-shell-docker:
|
||||||
fi
|
runs-on: ubuntu-latest
|
||||||
done
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
if [ -z "$PREV_TAG" ]; then
|
uses: actions/checkout@v4
|
||||||
echo "❌ Could not find previous tag for $CURRENT_TAG, aborting."
|
- name: Get Latest NapCat Version
|
||||||
exit 1
|
id: get_version
|
||||||
fi
|
run: |
|
||||||
|
# 获取当前仓库的最新 tag
|
||||||
echo "Previous tag: $PREV_TAG"
|
latest_tag=$(git describe --tags $(git rev-list --tags --max-count=1))
|
||||||
|
# 输出调试信息
|
||||||
# 强制拉取上一个 tag 和当前 tag
|
echo "Debug: Latest NapCat Version is ${latest_tag}"
|
||||||
git fetch origin "refs/tags/$PREV_TAG:refs/tags/$PREV_TAG" --force
|
echo "latest_tag=${latest_tag}" >> $GITHUB_ENV
|
||||||
git fetch origin "refs/tags/$CURRENT_TAG:refs/tags/$CURRENT_TAG" --force
|
- name: Trigger Release NapCat AppImage Workflow
|
||||||
|
env:
|
||||||
# 获取 commit title + body + 作者,保留换行
|
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||||
COMMITS=$(git log --pretty=format:'%h %B (%an)' "$PREV_TAG".."$CURRENT_TAG" | sed 's/$/\\n/')
|
NAPCAT_VERSION: ${{ env.latest_tag }}
|
||||||
|
QQ_VERSION_X86_64: 'https://dldir1v6.qq.com/qqfile/qq/QQNT/8015ff90/linuxqq_3.2.21-42086_x86_64.AppImage' # 写死 QQ 版本
|
||||||
echo "Commit list from $PREV_TAG to $CURRENT_TAG:"
|
QQ_VERSION_ARM64: 'https://dldir1v6.qq.com/qqfile/qq/QQNT/8015ff90/linuxqq_3.2.21-42086_arm64.AppImage' # 写死 QQ 版本
|
||||||
echo -e "$COMMITS"
|
run: |
|
||||||
|
echo "Debug: Triggering Release NapCat AppImage with napcat_version=${NAPCAT_VERSION}, qq_version_x86_64=${QQ_VERSION_X86_64}, qq_version_arm64=${QQ_VERSION_ARM64}"
|
||||||
# 读取 prompt
|
curl -X POST \
|
||||||
PROMPT_FILE=".github/prompt/release_note_prompt.txt"
|
-H "Accept: application/vnd.github+json" \
|
||||||
SYSTEM_PROMPT=$(<"$PROMPT_FILE")
|
-H "Authorization: Bearer $GH_TOKEN" \
|
||||||
|
https://api.github.com/repos/NapNeko/NapCatAppImageBuild/actions/workflows/release.yml/dispatches \
|
||||||
# 构建用户内容
|
-d "{\"ref\":\"main\",\"inputs\":{\"napcat_version\":\"${NAPCAT_VERSION}\",\"qq_version_x86_64\":\"${QQ_VERSION_X86_64}\",\"qq_version_arm64\":\"${QQ_VERSION_ARM64}\"}}"
|
||||||
USER_CONTENT="当前真正的版本: $CURRENT_TAG\n提交列表:\n$COMMITS"
|
node-shell-docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
# 构建请求 JSON
|
steps:
|
||||||
BODY=$(jq -n \
|
- name: Checkout Repository
|
||||||
--arg system "$SYSTEM_PROMPT" \
|
uses: actions/checkout@v4
|
||||||
--arg user "$USER_CONTENT" \
|
- name: Get Latest NapCat Version
|
||||||
'{model: env.OPENROUTER_MODEL, messages:[{role:"system", content:$system},{role:"user", content:$user}], temperature:0.3, max_tokens:800}')
|
id: get_version
|
||||||
|
run: |
|
||||||
echo "=== OpenRouter request body ==="
|
# 获取当前仓库的最新 tag
|
||||||
echo "$BODY" | jq .
|
latest_tag=$(git describe --tags $(git rev-list --tags --max-count=1))
|
||||||
|
# 输出调试信息
|
||||||
# 调用 OpenRouter
|
echo "Debug: Latest NapCat Version is ${latest_tag}"
|
||||||
RESPONSE=$(curl -s -X POST "$OPENROUTER_API_URL" \
|
echo "latest_tag=${latest_tag}" >> $GITHUB_ENV
|
||||||
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
|
- name: Trigger Release NapCat AppImage Workflow
|
||||||
-H "Content-Type: application/json" \
|
env:
|
||||||
-d "$BODY")
|
GH_TOKEN: ${{ secrets.NAPCAT_BUILD }}
|
||||||
|
NAPCAT_VERSION: ${{ env.latest_tag }}
|
||||||
echo "=== OpenRouter raw response ==="
|
QQ_VERSION_X86_64: 'https://dldir1v6.qq.com/qqfile/qq/QQNT/8015ff90/linuxqq_3.2.21-42086_x86_64.AppImage' # 写死 QQ 版本
|
||||||
echo "$RESPONSE" | jq .
|
QQ_VERSION_ARM64: 'https://dldir1v6.qq.com/qqfile/qq/QQNT/8015ff90/linuxqq_3.2.21-42086_arm64.AppImage' # 写死 QQ 版本
|
||||||
|
run: |
|
||||||
# 提取生成内容
|
echo "Debug: Triggering Release NapCat AppImage with napcat_version=${NAPCAT_VERSION}, qq_url_amd64=${QQ_VERSION_X86_64}, qq_url_arm64=${QQ_VERSION_ARM64}"
|
||||||
RELEASE_BODY=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // .choices[0].text // ""')
|
curl -X POST \
|
||||||
|
-H "Accept: application/vnd.github+json" \
|
||||||
if [ -z "$RELEASE_BODY" ]; then
|
-H "Authorization: Bearer $GH_TOKEN" \
|
||||||
echo "❌ OpenRouter failed to generate release note, terminating workflow."
|
https://api.github.com/repos/NapNeko/NapCatLinuxNodeLoader/actions/workflows/release.yml/dispatches \
|
||||||
exit 1
|
-d "{\"ref\":\"main\",\"inputs\":{\"napcat_version\":\"${NAPCAT_VERSION}\",\"qq_url_amd64\":\"${QQ_VERSION_X86_64}\",\"qq_url_arm64\":\"${QQ_VERSION_ARM64}\"}}"
|
||||||
fi
|
|
||||||
|
|
||||||
# 输出到 CHANGELOG.md
|
|
||||||
echo -e "$RELEASE_BODY" > CHANGELOG.md
|
|
||||||
echo "=== generated release note ==="
|
|
||||||
cat CHANGELOG.md
|
|
||||||
|
|
||||||
- name: Create Release Draft and Upload Artifacts
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
name: NapCat ${{ github.ref_name }}
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
body_path: CHANGELOG.md
|
|
||||||
files: |
|
|
||||||
NapCat.Shell.Windows.Node.zip
|
|
||||||
NapCat.Framework.zip
|
|
||||||
NapCat.Shell.zip
|
|
||||||
draft: true
|
|
||||||
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: "Build Action"
|
name: Build NapCat Artifacts
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
@@ -8,7 +8,7 @@ on:
|
|||||||
permissions: write-all
|
permissions: write-all
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build-LiteLoader:
|
Build-Framework:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone Main Repository
|
- name: Clone Main Repository
|
||||||
@@ -21,6 +21,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
npm i -g pnpm
|
npm i -g pnpm
|
||||||
pnpm i
|
pnpm i
|
||||||
|
pnpm run typecheck || exit 1
|
||||||
|
pnpm test || exit 1
|
||||||
pnpm --filter napcat-webui-frontend run build || exit 1
|
pnpm --filter napcat-webui-frontend run build || exit 1
|
||||||
pnpm run build:framework
|
pnpm run build:framework
|
||||||
mv packages/napcat-framework/dist framework-dist
|
mv packages/napcat-framework/dist framework-dist
|
||||||
@@ -45,6 +47,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
npm i -g pnpm
|
npm i -g pnpm
|
||||||
pnpm i
|
pnpm i
|
||||||
|
pnpm run typecheck || exit 1
|
||||||
|
pnpm test || exit 1
|
||||||
pnpm --filter napcat-webui-frontend run build || exit 1
|
pnpm --filter napcat-webui-frontend run build || exit 1
|
||||||
pnpm run build:shell
|
pnpm run build:shell
|
||||||
mv packages/napcat-shell/dist shell-dist
|
mv packages/napcat-shell/dist shell-dist
|
||||||
|
|||||||
228
.github/workflows/release.yml
vendored
228
.github/workflows/release.yml
vendored
@@ -1,12 +1,20 @@
|
|||||||
name: "Build Release"
|
name: Release NapCat
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
permissions: write-all
|
permissions: write-all
|
||||||
|
|
||||||
|
env:
|
||||||
|
OPENROUTER_API_URL: https://91vip.futureppo.top/v1/chat/completions
|
||||||
|
OPENROUTER_MODEL: "kimi-k2-0905-turbo"
|
||||||
|
RELEASE_NAME: "NapCat"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Build-LiteLoader:
|
Build-Framework:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone Main Repository
|
- name: Clone Main Repository
|
||||||
@@ -55,34 +63,212 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: NapCat.Shell
|
name: NapCat.Shell
|
||||||
path: shell-dist
|
path: shell-dist
|
||||||
|
Download-QNX64:
|
||||||
release-napcat:
|
needs: Build-Shell
|
||||||
needs: [Build-LiteLoader, Build-Shell]
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Download All Artifact
|
- uses: actions/checkout@v4
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
|
|
||||||
- name: Compress subdirectories
|
- name: Download Artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: ./artifacts
|
||||||
|
|
||||||
|
- name: Setup tools
|
||||||
run: |
|
run: |
|
||||||
cd ./NapCat.Shell/
|
sudo apt update
|
||||||
zip -q -r NapCat.Shell.zip *
|
sudo apt install -y aria2 unzip zip p7zip-full curl jq
|
||||||
cd ..
|
|
||||||
cd ./NapCat.Framework/
|
- name: Download QQ x64, Node.js and Assemble NapCat.Shell.Windows.Node.zip
|
||||||
zip -q -r NapCat.Framework.zip *
|
run: |
|
||||||
cd ..
|
set -euo pipefail
|
||||||
rm ./NapCat.Shell.zip -rf
|
TMPDIR=$(mktemp -d)
|
||||||
rm ./NapCat.Framework.zip -rf
|
cd "$TMPDIR"
|
||||||
mv ./NapCat.Shell/NapCat.Shell.zip ./
|
|
||||||
mv ./NapCat.Framework/NapCat.Framework.zip ./
|
# -----------------------------
|
||||||
|
# 1) 下载 QQ x64
|
||||||
|
# -----------------------------
|
||||||
|
# JS_URL="https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/windowsConfig.js"
|
||||||
|
# JS_URL="https://slave.docadan488.workers.dev/proxy?url=https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/windowsConfig.js"
|
||||||
|
# NT_URL=$(curl -fsSL "$JS_URL" | grep -oP '"ntDownloadX64Url"\s*:\s*"\K[^"]+')
|
||||||
|
NT_URL="https://dldir1v6.qq.com/qqfile/qq/QQNT/eb263b35/QQ9.9.23.42086_x64.exe"
|
||||||
|
QQ_ZIP="$(basename "$NT_URL")"
|
||||||
|
aria2c -x16 -s16 -k1M -o "$QQ_ZIP" "$NT_URL"
|
||||||
|
|
||||||
|
QQ_EXTRACT="$TMPDIR/qq_extracted"
|
||||||
|
mkdir -p "$QQ_EXTRACT"
|
||||||
|
7z x -y -o"$QQ_EXTRACT" "$QQ_ZIP" >/dev/null
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# 2) 下载 Node.js Windows x64 zip 22.11.0
|
||||||
|
# -----------------------------
|
||||||
|
NODE_VER="22.11.0"
|
||||||
|
NODE_URL="https://nodejs.org/dist/v$NODE_VER/node-v$NODE_VER-win-x64.zip"
|
||||||
|
NODE_ZIP="node-v$NODE_VER-win-x64.zip"
|
||||||
|
aria2c -x1 -s1 -k1M -o "$NODE_ZIP" "$NODE_URL"
|
||||||
|
|
||||||
|
NODE_EXTRACT="$TMPDIR/node_extracted"
|
||||||
|
mkdir -p "$NODE_EXTRACT"
|
||||||
|
unzip -q "$NODE_ZIP" -d "$NODE_EXTRACT"
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# 3) 创建输出目录
|
||||||
|
# -----------------------------
|
||||||
|
OUT_DIR="$GITHUB_WORKSPACE/NapCat.Shell.Windows.Node"
|
||||||
|
mkdir -p "$OUT_DIR/NapCat.Shell.Windows.Node"
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# 4) 解压 NapCat.Shell.zip 到 napcat
|
||||||
|
# -----------------------------
|
||||||
|
cp -a "$GITHUB_WORKSPACE/artifacts/NapCat.Shell/." "$OUT_DIR/napcat/"
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# 5) 拷贝 QQ 文件到 NapCat.Shell.Windows.Node
|
||||||
|
# -----------------------------
|
||||||
|
QQ_TARGETS=("avif_convert.dll" "broadcast_ipc.dll" "config.json" "libglib-2.0-0.dll" "libgobject-2.0-0.dll" "libvips-42.dll" "ncnn.dll" "opencv.dll" "package.json" "QBar.dll" "wrapper.node")
|
||||||
|
for name in "${QQ_TARGETS[@]}"; do
|
||||||
|
find "$QQ_EXTRACT" -iname "$name" -exec cp -a {} "$OUT_DIR" \; || true
|
||||||
|
done
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# 6) 拷贝仓库文件 napcat.bat 和 index.js
|
||||||
|
# -----------------------------
|
||||||
|
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/napcat.bat" "$OUT_DIR/" || true
|
||||||
|
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/index.js" "$OUT_DIR/" || true
|
||||||
|
cp -a "$GITHUB_WORKSPACE/packages/napcat-develop/QQNT.dll" "$OUT_DIR/" || true
|
||||||
|
# -----------------------------
|
||||||
|
# 7) 拷贝 Node.exe 到 NapCat.Shell.Windows.Node
|
||||||
|
# -----------------------------
|
||||||
|
cp -a "$NODE_EXTRACT/node-v$NODE_VER-win-x64/node.exe" "$OUT_DIR/" || true
|
||||||
|
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: NapCat.Shell.Windows.Node
|
||||||
|
path: NapCat.Shell.Windows.Node
|
||||||
|
|
||||||
|
release-napcat:
|
||||||
|
needs: [Build-Framework, Build-Shell, Download-QNX64]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Download Artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: ./artifacts
|
||||||
|
|
||||||
|
- name: Zip Artifacts
|
||||||
|
run: |
|
||||||
|
cd artifacts
|
||||||
|
[ -d NapCat.Framework ] && (cd NapCat.Framework && zip -qr ../../NapCat.Framework.zip .)
|
||||||
|
[ -d NapCat.Shell ] && (cd NapCat.Shell && zip -qr ../../NapCat.Shell.zip .)
|
||||||
|
[ -d NapCat.Shell.Windows.Node ] && (cd NapCat.Shell.Windows.Node && zip -qr ../../NapCat.Shell.Windows.Node.zip .)
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
- name: Generate release note via OpenRouter
|
||||||
|
env:
|
||||||
|
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
||||||
|
OPENROUTER_API_URL: ${{ env.OPENROUTER_API_URL }}
|
||||||
|
OPENROUTER_MODEL: ${{ env.OPENROUTER_MODEL }}
|
||||||
|
GITHUB_OWNER: "NapNeKo" # 替换成你的 repo owner
|
||||||
|
GITHUB_REPO: "NapCatQQ" # 替换成你的 repo 名
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# 当前 tag
|
||||||
|
CURRENT_TAG="${GITHUB_REF#refs/tags/}"
|
||||||
|
echo "Current tag: $CURRENT_TAG"
|
||||||
|
|
||||||
|
# 从 GitHub API 获取 tag 列表
|
||||||
|
TAGS_JSON=$(curl -s "https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/tags?per_page=100")
|
||||||
|
TAGS=( $(echo "$TAGS_JSON" | jq -r '.[].name' | sort -V) )
|
||||||
|
|
||||||
|
# 找到上一个 tag
|
||||||
|
PREV_TAG=""
|
||||||
|
for i in "${!TAGS[@]}"; do
|
||||||
|
if [ "${TAGS[$i]}" = "$CURRENT_TAG" ]; then
|
||||||
|
if [ $i -gt 0 ]; then
|
||||||
|
PREV_TAG="${TAGS[$((i-1))]}"
|
||||||
|
fi
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$PREV_TAG" ]; then
|
||||||
|
echo "❌ Could not find previous tag for $CURRENT_TAG, aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Previous tag: $PREV_TAG"
|
||||||
|
|
||||||
|
# 强制拉取上一个 tag 和当前 tag
|
||||||
|
git fetch origin "refs/tags/$PREV_TAG:refs/tags/$PREV_TAG" --force
|
||||||
|
git fetch origin "refs/tags/$CURRENT_TAG:refs/tags/$CURRENT_TAG" --force
|
||||||
|
|
||||||
|
# 获取 commit title + body + 作者,保留换行
|
||||||
|
COMMITS=$(git log --pretty=format:'%h %B (%an)' "$PREV_TAG".."$CURRENT_TAG" | sed 's/$/\\n/')
|
||||||
|
|
||||||
|
echo "Commit list from $PREV_TAG to $CURRENT_TAG:"
|
||||||
|
echo -e "$COMMITS"
|
||||||
|
|
||||||
|
# 读取 prompt
|
||||||
|
PROMPT_FILE=".github/prompt/release_note_prompt.txt"
|
||||||
|
SYSTEM_PROMPT=$(<"$PROMPT_FILE")
|
||||||
|
|
||||||
|
# 构建用户内容
|
||||||
|
USER_CONTENT="当前真正的版本: $CURRENT_TAG\n提交列表:\n$COMMITS"
|
||||||
|
|
||||||
|
# 构建请求 JSON
|
||||||
|
BODY=$(jq -n \
|
||||||
|
--arg system "$SYSTEM_PROMPT" \
|
||||||
|
--arg user "$USER_CONTENT" \
|
||||||
|
'{model: env.OPENROUTER_MODEL, messages:[{role:"system", content:$system},{role:"user", content:$user}], temperature:0.3, max_tokens:800}')
|
||||||
|
|
||||||
|
echo "=== OpenRouter request body ==="
|
||||||
|
echo "$BODY" | jq .
|
||||||
|
|
||||||
|
# 调用 OpenRouter
|
||||||
|
if RESPONSE=$(curl -s -X POST "$OPENROUTER_API_URL" \
|
||||||
|
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$BODY"); then
|
||||||
|
echo "=== raw response ==="
|
||||||
|
echo "$RESPONSE"
|
||||||
|
echo "=== OpenRouter raw response ==="
|
||||||
|
if echo "$RESPONSE" | jq . >/dev/null 2>&1; then
|
||||||
|
echo "$RESPONSE" | jq .
|
||||||
|
else
|
||||||
|
echo "jq failed to parse response"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 提取生成内容
|
||||||
|
RELEASE_BODY=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // .choices[0].text // ""' 2>/dev/null || echo "")
|
||||||
|
|
||||||
|
if [ -z "$RELEASE_BODY" ]; then
|
||||||
|
echo "❌ OpenRouter failed to generate release note, using default.md"
|
||||||
|
cp .github/prompt/default.md CHANGELOG.md
|
||||||
|
else
|
||||||
|
echo -e "$RELEASE_BODY" > CHANGELOG.md
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "❌ Curl failed, using default.md"
|
||||||
|
cp .github/prompt/default.md CHANGELOG.md
|
||||||
|
fi
|
||||||
|
echo "=== generated release note ==="
|
||||||
|
cat CHANGELOG.md
|
||||||
|
|
||||||
- name: Create Release Draft and Upload Artifacts
|
- name: Create Release Draft and Upload Artifacts
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
name: NapCat
|
name: NapCat ${{ github.ref_name }}
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
body: Automated release artifact (no version detection)
|
body_path: CHANGELOG.md
|
||||||
files: |
|
files: |
|
||||||
|
NapCat.Shell.Windows.Node.zip
|
||||||
NapCat.Framework.zip
|
NapCat.Framework.zip
|
||||||
NapCat.Shell.zip
|
NapCat.Shell.zip
|
||||||
draft: true
|
draft: true
|
||||||
|
|||||||
12
.vscode/launch.json
vendored
Normal file
12
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node-terminal",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "调试程序",
|
||||||
|
"command": "pnpm run dev:shell",
|
||||||
|
"cwd": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
35
.vscode/settings.json
vendored
35
.vscode/settings.json
vendored
@@ -1,2 +1,37 @@
|
|||||||
{
|
{
|
||||||
|
"explorer.fileNesting.enabled": true,
|
||||||
|
"explorer.fileNesting.expand": false,
|
||||||
|
"explorer.fileNesting.patterns": {
|
||||||
|
".env.universal": ".env.*",
|
||||||
|
"vite.config.ts": "vite*.ts",
|
||||||
|
"README.md": "CODE_OF_CONDUCT.md, RELEASES.md, CONTRIBUTING.md, CHANGELOG.md, SECURITY.md",
|
||||||
|
"tsconfig.json": "tsconfig.*.json, env.d.ts",
|
||||||
|
"package.json": "package-lock.json, eslint*, .prettier*, .editorconfig, manifest.json, logo.png, .gitignore, LICENSE"
|
||||||
|
},
|
||||||
|
"css.customData": [
|
||||||
|
".vscode/tailwindcss.json"
|
||||||
|
],
|
||||||
|
"editor.detectIndentation": false,
|
||||||
|
"editor.tabSize": 2,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.formatOnType": false,
|
||||||
|
"editor.formatOnPaste": true,
|
||||||
|
"editor.formatOnSaveMode": "file",
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": "always"
|
||||||
|
},
|
||||||
|
"files.autoSave": "onFocusChange",
|
||||||
|
"javascript.preferences.quoteStyle": "single",
|
||||||
|
"typescript.preferences.quoteStyle": "single",
|
||||||
|
"javascript.format.semicolons": "insert",
|
||||||
|
"typescript.format.semicolons": "insert",
|
||||||
|
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
|
||||||
|
"typescript.format.insertSpaceBeforeFunctionParenthesis": true,
|
||||||
|
"typescript.format.insertSpaceAfterConstructor": true,
|
||||||
|
"javascript.format.insertSpaceAfterConstructor": true,
|
||||||
|
"typescript.preferences.importModuleSpecifier": "non-relative",
|
||||||
|
"typescript.preferences.importModuleSpecifierEnding": "minimal",
|
||||||
|
"javascript.preferences.importModuleSpecifier": "non-relative",
|
||||||
|
"javascript.preferences.importModuleSpecifierEnding": "minimal",
|
||||||
|
"typescript.disableAutomaticTypeAcquisition": true
|
||||||
}
|
}
|
||||||
55
.vscode/tailwindcss.json
vendored
Normal file
55
.vscode/tailwindcss.json
vendored
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"version": 1.1,
|
||||||
|
"atDirectives": [
|
||||||
|
{
|
||||||
|
"name": "@tailwind",
|
||||||
|
"description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#tailwind"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@apply",
|
||||||
|
"description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#apply"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@responsive",
|
||||||
|
"description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#responsive"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@screen",
|
||||||
|
"description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#screen"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "@variants",
|
||||||
|
"description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"name": "Tailwind Documentation",
|
||||||
|
"url": "https://tailwindcss.com/docs/functions-and-directives#variants"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -43,7 +43,7 @@ _Modern protocol-side framework implemented based on NTQQ._
|
|||||||
|
|
||||||
**首次使用**请务必查看如下文档看使用教程
|
**首次使用**请务必查看如下文档看使用教程
|
||||||
|
|
||||||
> 项目非盈利,对接问题/基础问题/下层框架问题 请自行搜索解决,本项目社区不提供此类解答。
|
> 项目非盈利,涉及 对接问题/基础问题/下层框架问题 请自行搜索解决,本项目社区不提供此类解答。
|
||||||
|
|
||||||
## Link
|
## Link
|
||||||
|
|
||||||
|
|||||||
52
eslint.config.js
Normal file
52
eslint.config.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import neostandard from 'neostandard';
|
||||||
|
|
||||||
|
/** 尾随逗号 */
|
||||||
|
const commaDangle = val => {
|
||||||
|
if (val?.rules?.['@stylistic/comma-dangle']?.[0] === 'warn') {
|
||||||
|
const rule = val?.rules?.['@stylistic/comma-dangle']?.[1];
|
||||||
|
Object.keys(rule).forEach(key => {
|
||||||
|
rule[key] = 'always-multiline';
|
||||||
|
});
|
||||||
|
val.rules['@stylistic/comma-dangle'][1] = rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 三元表达式 */
|
||||||
|
if (val?.rules?.['@stylistic/indent']) {
|
||||||
|
val.rules['@stylistic/indent'][2] = {
|
||||||
|
...val.rules?.['@stylistic/indent']?.[2],
|
||||||
|
flatTernaryExpressions: true,
|
||||||
|
offsetTernaryExpressions: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 支持下划线 - 禁用 camelcase 规则 */
|
||||||
|
if (val?.rules?.camelcase) {
|
||||||
|
val.rules.camelcase = 'off';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 未使用的变量强制报错 */
|
||||||
|
if (val?.rules?.['@typescript-eslint/no-unused-vars']) {
|
||||||
|
val.rules['@typescript-eslint/no-unused-vars'] = ['error', {
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
caughtErrorsIgnorePattern: '^_',
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 忽略的文件 */
|
||||||
|
const ignores = [
|
||||||
|
'node_modules',
|
||||||
|
'**/dist/**',
|
||||||
|
'launcher',
|
||||||
|
];
|
||||||
|
|
||||||
|
const options = neostandard({
|
||||||
|
ts: true,
|
||||||
|
ignores,
|
||||||
|
semi: true, // 强制使用分号
|
||||||
|
}).map(commaDangle);
|
||||||
|
|
||||||
|
export default options;
|
||||||
18
package.json
18
package.json
@@ -5,18 +5,30 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:shell": "pnpm --filter napcat-shell run build || exit 1",
|
"build:shell": "pnpm --filter napcat-shell run build || exit 1",
|
||||||
|
"build:shell:dev": "pnpm --filter napcat-shell run build:dev || exit 1",
|
||||||
"build:framework": "pnpm --filter napcat-framework run build || exit 1",
|
"build:framework": "pnpm --filter napcat-framework run build || exit 1",
|
||||||
"build:webui": "pnpm --filter napcat-webui-frontend run build || exit 1",
|
"build:webui": "pnpm --filter napcat-webui-frontend run build || exit 1",
|
||||||
"dev:shell": "pnpm --filter napcat-develop run dev || exit 1"
|
"dev:shell": "pnpm --filter napcat-develop run dev || exit 1",
|
||||||
|
"typecheck": "pnpm -r --if-present run typecheck",
|
||||||
|
"test": "pnpm --filter napcat-test run test",
|
||||||
|
"test:ui": "pnpm --filter napcat-test run test:ui",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"lint:fix": "eslint . --fix"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||||
|
"@vitejs/plugin-react-swc": "^4.2.2",
|
||||||
|
"@vitest/ui": "^4.0.9",
|
||||||
|
"eslint": "^9.39.1",
|
||||||
|
"neostandard": "^0.12.2",
|
||||||
|
"typescript": "^5.3.0",
|
||||||
"vite": "^6.4.1",
|
"vite": "^6.4.1",
|
||||||
"vite-plugin-cp": "^6.0.3"
|
"vite-plugin-cp": "^6.0.3",
|
||||||
|
"vitest": "^4.0.9"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"silk-wasm": "^3.6.1",
|
|
||||||
"express": "^5.0.0",
|
"express": "^5.0.0",
|
||||||
|
"silk-wasm": "^3.6.1",
|
||||||
"ws": "^8.18.3"
|
"ws": "^8.18.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,9 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
|
"scripts": {
|
||||||
|
"typecheck": "tsc --noEmit --skipLibCheck -p tsconfig.json"
|
||||||
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./src/index.ts"
|
"import": "./src/index.ts"
|
||||||
@@ -13,14 +16,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"compressing": "^1.10.1",
|
|
||||||
"json5": "^2.2.3",
|
|
||||||
"ajv": "^8.13.0",
|
"ajv": "^8.13.0",
|
||||||
"file-type": "^21.0.0",
|
"file-type": "^21.0.0",
|
||||||
"napcat-image-size": "workspace:*",
|
"silk-wasm": "^3.6.1"
|
||||||
"napcat-core": "workspace:*",
|
|
||||||
"silk-wasm": "^3.6.1",
|
|
||||||
"winston": "^3.17.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.0.1"
|
"@types/node": "^22.0.1"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Peer } from '@/napcat-core';
|
import { Peer } from './types';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
|
|
||||||
class TimeBasedCache<K, V> {
|
class TimeBasedCache<K, V> {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import fs from 'fs';
|
|||||||
import { stat } from 'fs/promises';
|
import { stat } from 'fs/promises';
|
||||||
import crypto, { randomUUID } from 'crypto';
|
import crypto, { randomUUID } from 'crypto';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { solveProblem } from '@/napcat-common/helper';
|
import { solveProblem } from '@/napcat-common/src/helper';
|
||||||
|
|
||||||
export interface HttpDownloadOptions {
|
export interface HttpDownloadOptions {
|
||||||
url: string;
|
url: string;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import { QQLevel } from '@/napcat-core';
|
import { QQVersionConfigType, QQLevel } from './types';
|
||||||
import { QQVersionConfigType } from './types';
|
import { RequestUtil } from './request';
|
||||||
|
|
||||||
export async function solveProblem<T extends (...arg: any[]) => any> (func: T, ...args: Parameters<T>): Promise<ReturnType<T> | undefined> {
|
export async function solveProblem<T extends (...arg: any[]) => any> (func: T, ...args: Parameters<T>): Promise<ReturnType<T> | undefined> {
|
||||||
return new Promise<ReturnType<T> | undefined>((resolve) => {
|
return new Promise<ReturnType<T> | undefined>((resolve) => {
|
||||||
@@ -212,3 +212,81 @@ export function parseAppidFromMajor (nodeMajor: string): string | undefined {
|
|||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const baseUrl = 'https://github.com/NapNeko/NapCatQQ.git/info/refs?service=git-upload-pack';
|
||||||
|
const urls = [
|
||||||
|
'https://j.1win.ggff.net/' + baseUrl,
|
||||||
|
'https://git.yylx.win/' + baseUrl,
|
||||||
|
'https://ghfile.geekertao.top/' + baseUrl,
|
||||||
|
'https://gh-proxy.net/' + baseUrl,
|
||||||
|
'https://ghm.078465.xyz/' + baseUrl,
|
||||||
|
'https://gitproxy.127731.xyz/' + baseUrl,
|
||||||
|
'https://jiashu.1win.eu.org/' + baseUrl,
|
||||||
|
baseUrl,
|
||||||
|
];
|
||||||
|
|
||||||
|
async function testUrl (url: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await PromiseTimer(RequestUtil.HttpGetText(url), 5000);
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function findAvailableUrl (): Promise<string | null> {
|
||||||
|
for (const url of urls) {
|
||||||
|
if (await testUrl(url)) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAllTags (): Promise<string[]> {
|
||||||
|
const availableUrl = await findAvailableUrl();
|
||||||
|
if (!availableUrl) {
|
||||||
|
throw new Error('No available URL for fetching tags');
|
||||||
|
}
|
||||||
|
const raw = await RequestUtil.HttpGetText(availableUrl);
|
||||||
|
return raw
|
||||||
|
.split('\n')
|
||||||
|
.map(line => {
|
||||||
|
const match = line.match(/refs\/tags\/(.+)$/);
|
||||||
|
return match ? match[1] : null;
|
||||||
|
})
|
||||||
|
.filter(tag => tag !== null && !tag!.endsWith('^{}')) as string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function getLatestTag (): Promise<string> {
|
||||||
|
const tags = await getAllTags();
|
||||||
|
|
||||||
|
tags.sort((a, b) => compareVersion(a, b));
|
||||||
|
|
||||||
|
const latest = tags.at(-1);
|
||||||
|
if (!latest) {
|
||||||
|
throw new Error('No tags found');
|
||||||
|
}
|
||||||
|
// 去掉开头的 v
|
||||||
|
return latest.replace(/^v/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function compareVersion (a: string, b: string): number {
|
||||||
|
const normalize = (v: string) =>
|
||||||
|
v.replace(/^v/, '') // 去掉开头的 v
|
||||||
|
.split('.')
|
||||||
|
.map(n => parseInt(n) || 0);
|
||||||
|
|
||||||
|
const pa = normalize(a);
|
||||||
|
const pb = normalize(b);
|
||||||
|
const len = Math.max(pa.length, pb.length);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const na = pa[i] || 0;
|
||||||
|
const nb = pb[i] || 0;
|
||||||
|
if (na !== nb) return na - nb;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
24
packages/napcat-common/src/log-interface.ts
Normal file
24
packages/napcat-common/src/log-interface.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
export enum LogLevel {
|
||||||
|
DEBUG = 'debug',
|
||||||
|
INFO = 'info',
|
||||||
|
WARN = 'warn',
|
||||||
|
ERROR = 'error',
|
||||||
|
FATAL = 'fatal',
|
||||||
|
}
|
||||||
|
export interface ILogWrapper {
|
||||||
|
fileLogEnabled: boolean;
|
||||||
|
consoleLogEnabled: boolean;
|
||||||
|
cleanOldLogs (logDir: string): void;
|
||||||
|
setFileAndConsoleLogLevel (fileLogLevel: LogLevel, consoleLogLevel: LogLevel): void;
|
||||||
|
setLogSelfInfo (selfInfo: { nick: string; uid: string; }): void;
|
||||||
|
setFileLogEnabled (isEnabled: boolean): void;
|
||||||
|
setConsoleLogEnabled (isEnabled: boolean): void;
|
||||||
|
formatMsg (msg: any[]): string;
|
||||||
|
_log (level: LogLevel, ...args: any[]): void;
|
||||||
|
log (...args: any[]): void;
|
||||||
|
logDebug (...args: any[]): void;
|
||||||
|
logError (...args: any[]): void;
|
||||||
|
logWarn (...args: any[]): void;
|
||||||
|
logFatal (...args: any[]): void;
|
||||||
|
logMessage (msg: unknown, selfInfo: unknown): void;
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Peer } from '@/napcat-core';
|
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
|
import { Peer } from './types';
|
||||||
export class LimitedHashTable<K, V> {
|
export class LimitedHashTable<K, V> {
|
||||||
private readonly keyToValue: Map<K, V> = new Map();
|
private readonly keyToValue: Map<K, V> = new Map();
|
||||||
private readonly valueToKey: Map<V, K> = new Map();
|
private readonly valueToKey: Map<V, K> = new Map();
|
||||||
|
|||||||
@@ -1,317 +0,0 @@
|
|||||||
/**
|
|
||||||
* 性能监控器 - 用于统计函数调用次数、耗时等信息
|
|
||||||
*/
|
|
||||||
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
|
|
||||||
export interface FunctionStats {
|
|
||||||
name: string;
|
|
||||||
callCount: number;
|
|
||||||
totalTime: number;
|
|
||||||
averageTime: number;
|
|
||||||
minTime: number;
|
|
||||||
maxTime: number;
|
|
||||||
fileName?: string;
|
|
||||||
lineNumber?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PerformanceMonitor {
|
|
||||||
private static instance: PerformanceMonitor;
|
|
||||||
private stats = new Map<string, FunctionStats>();
|
|
||||||
private startTimes = new Map<string, number>();
|
|
||||||
private reportInterval: NodeJS.Timeout | null = null;
|
|
||||||
|
|
||||||
static getInstance (): PerformanceMonitor {
|
|
||||||
if (!PerformanceMonitor.instance) {
|
|
||||||
PerformanceMonitor.instance = new PerformanceMonitor();
|
|
||||||
// 启动定时统计报告
|
|
||||||
PerformanceMonitor.instance.startPeriodicReport();
|
|
||||||
}
|
|
||||||
return PerformanceMonitor.instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始定时统计报告 (每60秒)
|
|
||||||
*/
|
|
||||||
private startPeriodicReport (): void {
|
|
||||||
if (this.reportInterval) {
|
|
||||||
clearInterval(this.reportInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.reportInterval = setInterval(() => {
|
|
||||||
if (this.stats.size > 0) {
|
|
||||||
this.printPeriodicReport();
|
|
||||||
this.writeDetailedLogToFile();
|
|
||||||
}
|
|
||||||
}, 60000); // 60秒
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 停止定时统计报告
|
|
||||||
*/
|
|
||||||
stopPeriodicReport (): void {
|
|
||||||
if (this.reportInterval) {
|
|
||||||
clearInterval(this.reportInterval);
|
|
||||||
this.reportInterval = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打印定时统计报告 (简化版本)
|
|
||||||
*/
|
|
||||||
private printPeriodicReport (): void {
|
|
||||||
const now = new Date().toLocaleString();
|
|
||||||
console.log(`\n=== 性能监控定时报告 [${now}] ===`);
|
|
||||||
|
|
||||||
const totalFunctions = this.stats.size;
|
|
||||||
const totalCalls = Array.from(this.stats.values()).reduce((sum, stat) => sum + stat.callCount, 0);
|
|
||||||
const totalTime = Array.from(this.stats.values()).reduce((sum, stat) => sum + stat.totalTime, 0);
|
|
||||||
|
|
||||||
console.log(`📊 总览: ${totalFunctions} 个函数, ${totalCalls} 次调用, 总耗时: ${totalTime.toFixed(2)}ms`);
|
|
||||||
|
|
||||||
// 显示Top 5最活跃的函数
|
|
||||||
console.log('\n🔥 最活跃函数 (Top 5):');
|
|
||||||
this.getTopByCallCount(5).forEach((stat, index) => {
|
|
||||||
console.log(`${index + 1}. ${stat.name} - 调用: ${stat.callCount}次, 总耗时: ${stat.totalTime.toFixed(2)}ms`);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示Top 5最耗时的函数
|
|
||||||
console.log('\n⏱️ 最耗时函数 (Top 5):');
|
|
||||||
this.getTopByTotalTime(5).forEach((stat, index) => {
|
|
||||||
console.log(`${index + 1}. ${stat.name} - 总耗时: ${stat.totalTime.toFixed(2)}ms, 平均: ${stat.averageTime.toFixed(2)}ms`);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('===============================\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将详细统计数据写入日志文件
|
|
||||||
*/
|
|
||||||
private writeDetailedLogToFile (): void {
|
|
||||||
try {
|
|
||||||
const now = new Date();
|
|
||||||
const dateStr = now.toISOString().replace(/[:.]/g, '-').split('T')[0];
|
|
||||||
const timeStr = now.toTimeString().split(' ')[0]?.replace(/:/g, '-') || 'unknown-time';
|
|
||||||
const timestamp = `${dateStr}_${timeStr}`;
|
|
||||||
const fileName = `${timestamp}.log.txt`;
|
|
||||||
const logPath = path.join(process.cwd(), 'logs', fileName);
|
|
||||||
|
|
||||||
// 确保logs目录存在
|
|
||||||
const logsDir = path.dirname(logPath);
|
|
||||||
if (!fs.existsSync(logsDir)) {
|
|
||||||
fs.mkdirSync(logsDir, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const totalFunctions = this.stats.size;
|
|
||||||
const totalCalls = Array.from(this.stats.values()).reduce((sum, stat) => sum + stat.callCount, 0);
|
|
||||||
const totalTime = Array.from(this.stats.values()).reduce((sum, stat) => sum + stat.totalTime, 0);
|
|
||||||
|
|
||||||
let logContent = '';
|
|
||||||
logContent += '=== 性能监控详细报告 ===\n';
|
|
||||||
logContent += `生成时间: ${now.toLocaleString()}\n`;
|
|
||||||
logContent += '统计周期: 60秒\n';
|
|
||||||
logContent += `总览: ${totalFunctions} 个函数, ${totalCalls} 次调用, 总耗时: ${totalTime.toFixed(2)}ms\n\n`;
|
|
||||||
|
|
||||||
// 详细函数统计
|
|
||||||
logContent += '=== 所有函数详细统计 ===\n';
|
|
||||||
const allStats = this.getStats().sort((a, b) => b.totalTime - a.totalTime);
|
|
||||||
|
|
||||||
allStats.forEach((stat, index) => {
|
|
||||||
logContent += `${index + 1}. 函数: ${stat.name}\n`;
|
|
||||||
logContent += ` 文件: ${stat.fileName || 'N/A'}\n`;
|
|
||||||
logContent += ` 行号: ${stat.lineNumber || 'N/A'}\n`;
|
|
||||||
logContent += ` 调用次数: ${stat.callCount}\n`;
|
|
||||||
logContent += ` 总耗时: ${stat.totalTime.toFixed(4)}ms\n`;
|
|
||||||
logContent += ` 平均耗时: ${stat.averageTime.toFixed(4)}ms\n`;
|
|
||||||
logContent += ` 最小耗时: ${stat.minTime === Infinity ? 'N/A' : stat.minTime.toFixed(4)}ms\n`;
|
|
||||||
logContent += ` 最大耗时: ${stat.maxTime.toFixed(4)}ms\n`;
|
|
||||||
logContent += ` 性能占比: ${((stat.totalTime / totalTime) * 100).toFixed(2)}%\n`;
|
|
||||||
logContent += '\n';
|
|
||||||
});
|
|
||||||
|
|
||||||
// 排行榜统计
|
|
||||||
logContent += '=== 总耗时排行榜 (Top 20) ===\n';
|
|
||||||
this.getTopByTotalTime(20).forEach((stat, index) => {
|
|
||||||
logContent += `${index + 1}. ${stat.name} - 总耗时: ${stat.totalTime.toFixed(2)}ms, 调用: ${stat.callCount}次, 平均: ${stat.averageTime.toFixed(2)}ms\n`;
|
|
||||||
});
|
|
||||||
|
|
||||||
logContent += '\n=== 调用次数排行榜 (Top 20) ===\n';
|
|
||||||
this.getTopByCallCount(20).forEach((stat, index) => {
|
|
||||||
logContent += `${index + 1}. ${stat.name} - 调用: ${stat.callCount}次, 总耗时: ${stat.totalTime.toFixed(2)}ms, 平均: ${stat.averageTime.toFixed(2)}ms\n`;
|
|
||||||
});
|
|
||||||
|
|
||||||
logContent += '\n=== 平均耗时排行榜 (Top 20) ===\n';
|
|
||||||
this.getTopByAverageTime(20).forEach((stat, index) => {
|
|
||||||
logContent += `${index + 1}. ${stat.name} - 平均: ${stat.averageTime.toFixed(2)}ms, 调用: ${stat.callCount}次, 总耗时: ${stat.totalTime.toFixed(2)}ms\n`;
|
|
||||||
});
|
|
||||||
|
|
||||||
logContent += '\n=== 性能热点分析 ===\n';
|
|
||||||
// 找出最耗时的前10个函数
|
|
||||||
const hotSpots = this.getTopByTotalTime(10);
|
|
||||||
hotSpots.forEach((stat, index) => {
|
|
||||||
const efficiency = stat.callCount / stat.totalTime; // 每毫秒的调用次数
|
|
||||||
logContent += `${index + 1}. ${stat.name}\n`;
|
|
||||||
logContent += ` 性能影响: ${((stat.totalTime / totalTime) * 100).toFixed(2)}%\n`;
|
|
||||||
logContent += ` 调用效率: ${efficiency.toFixed(4)} 调用/ms\n`;
|
|
||||||
logContent += ` 优化建议: ${stat.averageTime > 10
|
|
||||||
? '考虑优化此函数的执行效率'
|
|
||||||
: stat.callCount > 1000
|
|
||||||
? '考虑减少此函数的调用频率'
|
|
||||||
: '性能表现良好'}\n\n`;
|
|
||||||
});
|
|
||||||
|
|
||||||
logContent += '=== 报告结束 ===\n';
|
|
||||||
|
|
||||||
// 写入文件
|
|
||||||
fs.writeFileSync(logPath, logContent, 'utf8');
|
|
||||||
console.log(`📄 详细性能报告已保存到: ${logPath}`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('写入性能日志文件时出错:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开始记录函数调用
|
|
||||||
*/
|
|
||||||
startFunction (functionName: string, fileName?: string, lineNumber?: number): string {
|
|
||||||
const callId = `${functionName}_${Date.now()}_${Math.random()}`;
|
|
||||||
this.startTimes.set(callId, performance.now());
|
|
||||||
|
|
||||||
// 初始化或更新统计信息
|
|
||||||
if (!this.stats.has(functionName)) {
|
|
||||||
this.stats.set(functionName, {
|
|
||||||
name: functionName,
|
|
||||||
callCount: 0,
|
|
||||||
totalTime: 0,
|
|
||||||
averageTime: 0,
|
|
||||||
minTime: Infinity,
|
|
||||||
maxTime: 0,
|
|
||||||
fileName,
|
|
||||||
lineNumber,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const stat = this.stats.get(functionName)!;
|
|
||||||
stat.callCount++;
|
|
||||||
|
|
||||||
return callId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束记录函数调用
|
|
||||||
*/
|
|
||||||
endFunction (callId: string, functionName: string): void {
|
|
||||||
const startTime = this.startTimes.get(callId);
|
|
||||||
if (!startTime) return;
|
|
||||||
|
|
||||||
const endTime = performance.now();
|
|
||||||
const duration = endTime - startTime;
|
|
||||||
|
|
||||||
this.startTimes.delete(callId);
|
|
||||||
|
|
||||||
const stat = this.stats.get(functionName);
|
|
||||||
if (!stat) return;
|
|
||||||
|
|
||||||
stat.totalTime += duration;
|
|
||||||
stat.averageTime = stat.totalTime / stat.callCount;
|
|
||||||
stat.minTime = Math.min(stat.minTime, duration);
|
|
||||||
stat.maxTime = Math.max(stat.maxTime, duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取所有统计信息
|
|
||||||
*/
|
|
||||||
getStats (): FunctionStats[] {
|
|
||||||
return Array.from(this.stats.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取排行榜 - 按总耗时排序
|
|
||||||
*/
|
|
||||||
getTopByTotalTime (limit = 20): FunctionStats[] {
|
|
||||||
return this.getStats()
|
|
||||||
.sort((a, b) => b.totalTime - a.totalTime)
|
|
||||||
.slice(0, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取排行榜 - 按调用次数排序
|
|
||||||
*/
|
|
||||||
getTopByCallCount (limit = 20): FunctionStats[] {
|
|
||||||
return this.getStats()
|
|
||||||
.sort((a, b) => b.callCount - a.callCount)
|
|
||||||
.slice(0, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取排行榜 - 按平均耗时排序
|
|
||||||
*/
|
|
||||||
getTopByAverageTime (limit = 20): FunctionStats[] {
|
|
||||||
return this.getStats()
|
|
||||||
.sort((a, b) => b.averageTime - a.averageTime)
|
|
||||||
.slice(0, limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空统计数据
|
|
||||||
*/
|
|
||||||
clear (): void {
|
|
||||||
this.stats.clear();
|
|
||||||
this.startTimes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打印统计报告
|
|
||||||
*/
|
|
||||||
printReport (): void {
|
|
||||||
console.log('\n=== 函数性能监控报告 ===');
|
|
||||||
|
|
||||||
console.log('\n🔥 总耗时排行榜 (Top 10):');
|
|
||||||
this.getTopByTotalTime(10).forEach((stat, index) => {
|
|
||||||
console.log(`${index + 1}. ${stat.name} - 总耗时: ${stat.totalTime.toFixed(2)}ms, 调用次数: ${stat.callCount}, 平均耗时: ${stat.averageTime.toFixed(2)}ms`);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('\n📈 调用次数排行榜 (Top 10):');
|
|
||||||
this.getTopByCallCount(10).forEach((stat, index) => {
|
|
||||||
console.log(`${index + 1}. ${stat.name} - 调用次数: ${stat.callCount}, 总耗时: ${stat.totalTime.toFixed(2)}ms, 平均耗时: ${stat.averageTime.toFixed(2)}ms`);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('\n⏱️ 平均耗时排行榜 (Top 10):');
|
|
||||||
this.getTopByAverageTime(10).forEach((stat, index) => {
|
|
||||||
console.log(`${index + 1}. ${stat.name} - 平均耗时: ${stat.averageTime.toFixed(2)}ms, 调用次数: ${stat.callCount}, 总耗时: ${stat.totalTime.toFixed(2)}ms`);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('\n========================\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取JSON格式的统计数据
|
|
||||||
*/
|
|
||||||
toJSON (): FunctionStats[] {
|
|
||||||
return this.getStats();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全局性能监控器实例
|
|
||||||
export const performanceMonitor = PerformanceMonitor.getInstance();
|
|
||||||
|
|
||||||
// 在进程退出时打印报告并停止定时器
|
|
||||||
if (typeof process !== 'undefined') {
|
|
||||||
process.on('exit', () => {
|
|
||||||
performanceMonitor.stopPeriodicReport();
|
|
||||||
performanceMonitor.printReport();
|
|
||||||
});
|
|
||||||
|
|
||||||
process.on('SIGINT', () => {
|
|
||||||
performanceMonitor.stopPeriodicReport();
|
|
||||||
performanceMonitor.printReport();
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
process.on('SIGTERM', () => {
|
|
||||||
performanceMonitor.stopPeriodicReport();
|
|
||||||
performanceMonitor.printReport();
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
24
packages/napcat-common/src/status-interface.ts
Normal file
24
packages/napcat-common/src/status-interface.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
export interface SystemStatus {
|
||||||
|
cpu: {
|
||||||
|
model: string,
|
||||||
|
speed: string;
|
||||||
|
usage: {
|
||||||
|
system: string;
|
||||||
|
qq: string;
|
||||||
|
},
|
||||||
|
core: number;
|
||||||
|
},
|
||||||
|
memory: {
|
||||||
|
total: string;
|
||||||
|
usage: {
|
||||||
|
system: string;
|
||||||
|
qq: string;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
arch: string;
|
||||||
|
}
|
||||||
|
export interface IStatusHelperSubscription {
|
||||||
|
on (event: 'statusUpdate', listener: (status: SystemStatus) => void): this;
|
||||||
|
off (event: 'statusUpdate', listener: (status: SystemStatus) => void): this;
|
||||||
|
emit (event: 'statusUpdate', status: SystemStatus): boolean;
|
||||||
|
}
|
||||||
@@ -19,4 +19,4 @@ class Store {
|
|||||||
|
|
||||||
const store = new Store();
|
const store = new Store();
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|||||||
6
packages/napcat-common/src/subscription-interface.ts
Normal file
6
packages/napcat-common/src/subscription-interface.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export type LogListener = (msg: string) => void;
|
||||||
|
export interface ISubscription {
|
||||||
|
subscribe (listener: LogListener): void;
|
||||||
|
unsubscribe (listener: LogListener): void;
|
||||||
|
notify (msg: string): void;
|
||||||
|
}
|
||||||
@@ -15,3 +15,14 @@ export type QQVersionConfigType = {
|
|||||||
export type QQAppidTableType = {
|
export type QQAppidTableType = {
|
||||||
[key: string]: { appid: string, qua: string };
|
[key: string]: { appid: string, qua: string };
|
||||||
};
|
};
|
||||||
|
export interface Peer {
|
||||||
|
chatType: number; // 聊天类型
|
||||||
|
peerUid: string; // 对等方的唯一标识符
|
||||||
|
guildId?: string; // 可选的频道ID
|
||||||
|
}
|
||||||
|
export interface QQLevel {
|
||||||
|
crownNum: number;
|
||||||
|
sunNum: number;
|
||||||
|
moonNum: number;
|
||||||
|
starNum: number;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
export const napCatVersion = import.meta.env.VITE_NAPCAT_VERSION || 'alpha';
|
// @ts-ignore
|
||||||
|
export const napCatVersion = (typeof import.meta?.env !== 'undefined' && import.meta.env.VITE_NAPCAT_VERSION) || 'alpha';
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
],
|
],
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
"rootDir": "src",
|
"rootDir": ".",
|
||||||
"noEmit": false,
|
"noEmit": false,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": false,
|
||||||
"strictFunctionTypes": true,
|
"strictFunctionTypes": true,
|
||||||
"strictBindCallApply": true,
|
"strictBindCallApply": true,
|
||||||
"alwaysStrict": true,
|
"alwaysStrict": true,
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/napcat-common/*": [
|
"@/*": [
|
||||||
"src/*"
|
"../*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export class NodeIDependsAdapter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onMSFSsoError (_args: unknown) {
|
onMSFSsoError (_code: number, _desc: string) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,4 +24,4 @@ export class NodeIDependsAdapter {
|
|||||||
|
|
||||||
// console.log('[NodeIDependsAdapter] onSendMsfReply', _seq, _cmd, _uk1, _uk2, Buffer.from(_rsp.pbBuffer).toString('hex'));
|
// console.log('[NodeIDependsAdapter] onSendMsfReply', _seq, _cmd, _uk1, _uk2, Buffer.from(_rsp.pbBuffer).toString('hex'));
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,7 @@ import {
|
|||||||
IMAGE_HTTP_HOST_NT,
|
IMAGE_HTTP_HOST_NT,
|
||||||
Peer,
|
Peer,
|
||||||
PicElement,
|
PicElement,
|
||||||
PicSubType,
|
|
||||||
RawMessage,
|
RawMessage,
|
||||||
SendFileElement,
|
|
||||||
SendPicElement,
|
|
||||||
SendPttElement,
|
|
||||||
SendVideoElement,
|
|
||||||
} from '@/napcat-core/types';
|
} from '@/napcat-core/types';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
@@ -19,16 +14,9 @@ import { InstanceContext, NapCatCore, SearchResultItem } from '@/napcat-core/ind
|
|||||||
import { fileTypeFromFile } from 'file-type';
|
import { fileTypeFromFile } from 'file-type';
|
||||||
import { RkeyManager } from '@/napcat-core/helper/rkey';
|
import { RkeyManager } from '@/napcat-core/helper/rkey';
|
||||||
import { calculateFileMD5 } from 'napcat-common/src/file';
|
import { calculateFileMD5 } from 'napcat-common/src/file';
|
||||||
import pathLib from 'node:path';
|
|
||||||
import { defaultVideoThumbB64 } from 'napcat-common/src/video';
|
|
||||||
import { encodeSilk } from 'napcat-common/src/audio';
|
|
||||||
import { SendMessageContext } from 'napcat-onebot/api/msg';
|
|
||||||
import { getFileTypeForSendType } from '../helper/msg';
|
|
||||||
import { FFmpegService } from 'napcat-common/src/ffmpeg';
|
|
||||||
import { rkeyDataType } from '../types/file';
|
import { rkeyDataType } from '../types/file';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { FileId } from '../packet/transformer/proto/misc/fileid';
|
import { FileId } from '../packet/transformer/proto/misc/fileid';
|
||||||
import { imageSizeFallBack } from 'napcat-image-size';
|
|
||||||
|
|
||||||
export class NTQQFileApi {
|
export class NTQQFileApi {
|
||||||
context: InstanceContext;
|
context: InstanceContext;
|
||||||
@@ -45,7 +33,7 @@ export class NTQQFileApi {
|
|||||||
'http://ss.xingzhige.com/music_card/rkey',
|
'http://ss.xingzhige.com/music_card/rkey',
|
||||||
'https://secret-service.bietiaop.com/rkeys',
|
'https://secret-service.bietiaop.com/rkeys',
|
||||||
],
|
],
|
||||||
this.context.logger
|
this.context.logger
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,165 +169,6 @@ export class NTQQFileApi {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async createValidSendFileElement (context: SendMessageContext, filePath: string, fileName: string = '', folderId: string = ''): Promise<SendFileElement> {
|
|
||||||
const {
|
|
||||||
fileName: _fileName,
|
|
||||||
path,
|
|
||||||
fileSize,
|
|
||||||
} = await this.core.apis.FileApi.uploadFile(filePath, ElementType.FILE);
|
|
||||||
if (fileSize === 0) {
|
|
||||||
throw new Error('文件异常,大小为0');
|
|
||||||
}
|
|
||||||
context.deleteAfterSentFiles.push(path);
|
|
||||||
return {
|
|
||||||
elementType: ElementType.FILE,
|
|
||||||
elementId: '',
|
|
||||||
fileElement: {
|
|
||||||
fileName: fileName || _fileName,
|
|
||||||
folderId,
|
|
||||||
filePath: path,
|
|
||||||
fileSize: fileSize.toString(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async createValidSendPicElement (context: SendMessageContext, picPath: string, summary: string = '', subType: PicSubType = 0): Promise<SendPicElement> {
|
|
||||||
const { md5, fileName, path, fileSize } = await this.core.apis.FileApi.uploadFile(picPath, ElementType.PIC, subType);
|
|
||||||
if (fileSize === 0) {
|
|
||||||
throw new Error('文件异常,大小为0');
|
|
||||||
}
|
|
||||||
const imageSize = await imageSizeFallBack(picPath);
|
|
||||||
context.deleteAfterSentFiles.push(path);
|
|
||||||
return {
|
|
||||||
elementType: ElementType.PIC,
|
|
||||||
elementId: '',
|
|
||||||
picElement: {
|
|
||||||
md5HexStr: md5,
|
|
||||||
fileSize: fileSize.toString(),
|
|
||||||
picWidth: imageSize.width,
|
|
||||||
picHeight: imageSize.height,
|
|
||||||
fileName,
|
|
||||||
sourcePath: path,
|
|
||||||
original: true,
|
|
||||||
picType: await getFileTypeForSendType(picPath),
|
|
||||||
picSubType: subType,
|
|
||||||
fileUuid: '',
|
|
||||||
fileSubId: '',
|
|
||||||
thumbFileSize: 0,
|
|
||||||
summary,
|
|
||||||
} as PicElement,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async createValidSendVideoElement (context: SendMessageContext, filePath: string, fileName: string = '', _diyThumbPath: string = ''): Promise<SendVideoElement> {
|
|
||||||
let videoInfo = {
|
|
||||||
width: 1920,
|
|
||||||
height: 1080,
|
|
||||||
time: 15,
|
|
||||||
format: 'mp4',
|
|
||||||
size: 0,
|
|
||||||
filePath,
|
|
||||||
};
|
|
||||||
let fileExt = 'mp4';
|
|
||||||
try {
|
|
||||||
const tempExt = (await fileTypeFromFile(filePath))?.ext;
|
|
||||||
if (tempExt) fileExt = tempExt;
|
|
||||||
} catch (e) {
|
|
||||||
this.context.logger.logError('获取文件类型失败', e);
|
|
||||||
}
|
|
||||||
const newFilePath = `${filePath}.${fileExt}`;
|
|
||||||
fs.copyFileSync(filePath, newFilePath);
|
|
||||||
context.deleteAfterSentFiles.push(newFilePath);
|
|
||||||
filePath = newFilePath;
|
|
||||||
|
|
||||||
const { fileName: _fileName, path, fileSize, md5 } = await this.core.apis.FileApi.uploadFile(filePath, ElementType.VIDEO);
|
|
||||||
context.deleteAfterSentFiles.push(path);
|
|
||||||
if (fileSize === 0) {
|
|
||||||
throw new Error('文件异常,大小为0');
|
|
||||||
}
|
|
||||||
const thumbDir = path.replace(`${pathLib.sep}Ori${pathLib.sep}`, `${pathLib.sep}Thumb${pathLib.sep}`);
|
|
||||||
fs.mkdirSync(pathLib.dirname(thumbDir), { recursive: true });
|
|
||||||
const thumbPath = pathLib.join(pathLib.dirname(thumbDir), `${md5}_0.png`);
|
|
||||||
try {
|
|
||||||
videoInfo = await FFmpegService.getVideoInfo(filePath, thumbPath);
|
|
||||||
if (!fs.existsSync(thumbPath)) {
|
|
||||||
this.context.logger.logError('获取视频缩略图失败', new Error('缩略图不存在'));
|
|
||||||
throw new Error('获取视频缩略图失败');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.context.logger.logError('获取视频信息失败', e);
|
|
||||||
fs.writeFileSync(thumbPath, Buffer.from(defaultVideoThumbB64, 'base64'));
|
|
||||||
}
|
|
||||||
if (_diyThumbPath) {
|
|
||||||
try {
|
|
||||||
await this.copyFile(_diyThumbPath, thumbPath);
|
|
||||||
} catch (e) {
|
|
||||||
this.context.logger.logError('复制自定义缩略图失败', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
context.deleteAfterSentFiles.push(thumbPath);
|
|
||||||
const thumbSize = (await fsPromises.stat(thumbPath)).size;
|
|
||||||
const thumbMd5 = await calculateFileMD5(thumbPath);
|
|
||||||
context.deleteAfterSentFiles.push(thumbPath);
|
|
||||||
|
|
||||||
const uploadName = (fileName || _fileName).toLocaleLowerCase().endsWith(`.${fileExt.toLocaleLowerCase()}`) ? (fileName || _fileName) : `${fileName || _fileName}.${fileExt}`;
|
|
||||||
return {
|
|
||||||
elementType: ElementType.VIDEO,
|
|
||||||
elementId: '',
|
|
||||||
videoElement: {
|
|
||||||
fileName: uploadName,
|
|
||||||
filePath: path,
|
|
||||||
videoMd5: md5,
|
|
||||||
thumbMd5,
|
|
||||||
fileTime: videoInfo.time,
|
|
||||||
thumbPath: new Map([[0, thumbPath]]),
|
|
||||||
thumbSize,
|
|
||||||
thumbWidth: videoInfo.width,
|
|
||||||
thumbHeight: videoInfo.height,
|
|
||||||
fileSize: fileSize.toString(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async createValidSendPttElement (_context: SendMessageContext, pttPath: string): Promise<SendPttElement> {
|
|
||||||
const { converted, path: silkPath, duration } = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger);
|
|
||||||
if (!silkPath) {
|
|
||||||
throw new Error('语音转换失败, 请检查语音文件是否正常');
|
|
||||||
}
|
|
||||||
const { md5, fileName, path, fileSize } = await this.core.apis.FileApi.uploadFile(silkPath, ElementType.PTT);
|
|
||||||
if (fileSize === 0) {
|
|
||||||
throw new Error('文件异常,大小为0');
|
|
||||||
}
|
|
||||||
if (converted) {
|
|
||||||
fsPromises.unlink(silkPath).then().catch((e) => this.context.logger.logError('删除临时文件失败', e));
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
elementType: ElementType.PTT,
|
|
||||||
elementId: '',
|
|
||||||
pttElement: {
|
|
||||||
fileName,
|
|
||||||
filePath: path,
|
|
||||||
md5HexStr: md5,
|
|
||||||
fileSize: fileSize.toString(),
|
|
||||||
duration: duration ?? 1,
|
|
||||||
formatType: 1,
|
|
||||||
voiceType: 1,
|
|
||||||
voiceChangeType: 0,
|
|
||||||
canConvert2Text: true,
|
|
||||||
waveAmplitudes: [
|
|
||||||
0, 18, 9, 23, 16, 17, 16, 15, 44, 17, 24, 20, 14, 15, 17,
|
|
||||||
],
|
|
||||||
fileSubId: '',
|
|
||||||
playState: 1,
|
|
||||||
autoConvertText: 0,
|
|
||||||
storeID: 0,
|
|
||||||
otherBusinessInfo: {
|
|
||||||
aiVoiceType: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async downloadFileForModelId (peer: Peer, modelId: string, unknown: string, timeout = 1000 * 60 * 2) {
|
async downloadFileForModelId (peer: Peer, modelId: string, unknown: string, timeout = 1000 * 60 * 2) {
|
||||||
const [, fileTransNotifyInfo] = await this.core.eventWrapper.callNormalEventV2(
|
const [, fileTransNotifyInfo] = await this.core.eventWrapper.callNormalEventV2(
|
||||||
'NodeIKernelRichMediaService/downloadFileForModelId',
|
'NodeIKernelRichMediaService/downloadFileForModelId',
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ import {
|
|||||||
} from '@/napcat-core/index';
|
} from '@/napcat-core/index';
|
||||||
import { isNumeric, solveAsyncProblem } from 'napcat-common/src/helper';
|
import { isNumeric, solveAsyncProblem } from 'napcat-common/src/helper';
|
||||||
import { LimitedHashTable } from 'napcat-common/src/message-unique';
|
import { LimitedHashTable } from 'napcat-common/src/message-unique';
|
||||||
import { NTEventWrapper } from 'napcat-common/src/event';
|
|
||||||
import { CancelableTask, TaskExecutor } from 'napcat-common/src/cancel-task';
|
import { CancelableTask, TaskExecutor } from 'napcat-common/src/cancel-task';
|
||||||
import { createGroupDetailInfoV2Param, createGroupExtFilter, createGroupExtInfo } from '../data';
|
import { createGroupDetailInfoV2Param, createGroupExtFilter, createGroupExtInfo } from '../data';
|
||||||
|
import { NTEventWrapper } from '../helper/event';
|
||||||
|
|
||||||
export class NTQQGroupApi {
|
export class NTQQGroupApi {
|
||||||
context: InstanceContext;
|
context: InstanceContext;
|
||||||
@@ -395,7 +395,7 @@ export class NTQQGroupApi {
|
|||||||
'NodeIKernelGroupListener/onMemberInfoChange',
|
'NodeIKernelGroupListener/onMemberInfoChange',
|
||||||
[groupCode, [uid], forced],
|
[groupCode, [uid], forced],
|
||||||
(ret) => ret.result === 0,
|
(ret) => ret.result === 0,
|
||||||
(params, _, members) => params === GroupCode && members.size > 0 && members.has(uid),
|
(params: string, _: any, members: Map<string, GroupMember>) => params === GroupCode && members.size > 0 && members.has(uid),
|
||||||
1,
|
1,
|
||||||
forced ? 2500 : 250
|
forced ? 2500 : 250
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import offset from '@/napcat-core/external/napi2native.json';
|
import offset from '@/napcat-core/external/napi2native.json';
|
||||||
import { InstanceContext, NapCatCore } from '@/napcat-core/index';
|
import { InstanceContext, NapCatCore } from '@/napcat-core/index';
|
||||||
import { LogWrapper } from 'napcat-common/src/log';
|
|
||||||
import { PacketClientSession } from '@/napcat-core/packet/clientSession';
|
import { PacketClientSession } from '@/napcat-core/packet/clientSession';
|
||||||
import { napCatVersion } from 'napcat-common/src/version';
|
import { napCatVersion } from 'napcat-common/src/version';
|
||||||
|
import { LogWrapper } from '../helper/log';
|
||||||
|
|
||||||
interface OffsetType {
|
interface OffsetType {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
|
|||||||
32
packages/napcat-core/external/appid.json
vendored
32
packages/napcat-core/external/appid.json
vendored
@@ -466,5 +466,37 @@
|
|||||||
"6.9.85-42086": {
|
"6.9.85-42086": {
|
||||||
"appid": 537320237,
|
"appid": 537320237,
|
||||||
"qua": "V1_MAC_NQ_6.9.85_42086_GW_B"
|
"qua": "V1_MAC_NQ_6.9.85_42086_GW_B"
|
||||||
|
},
|
||||||
|
"9.9.23-42430": {
|
||||||
|
"appid": 537320212,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.23_42430_GW_B"
|
||||||
|
},
|
||||||
|
"9.9.25-42744": {
|
||||||
|
"appid": 537328470,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.23_42744_GW_B"
|
||||||
|
},
|
||||||
|
"6.9.86-42744": {
|
||||||
|
"appid": 537328495,
|
||||||
|
"qua": "V1_MAC_NQ_6.9.85_42744_GW_B"
|
||||||
|
},
|
||||||
|
"9.9.25-42905": {
|
||||||
|
"appid": 537328521,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.25_42905_GW_B"
|
||||||
|
},
|
||||||
|
"6.9.86-42905": {
|
||||||
|
"appid": 537328546,
|
||||||
|
"qua": "V1_MAC_NQ_6.9.86_42905_GW_B"
|
||||||
|
},
|
||||||
|
"3.2.22-42941": {
|
||||||
|
"appid": 537328659,
|
||||||
|
"qua": "V1_LNX_NQ_3.2.22_42941_GW_B"
|
||||||
|
},
|
||||||
|
"9.9.25-42941": {
|
||||||
|
"appid": 537328623,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.25_42941_GW_B"
|
||||||
|
},
|
||||||
|
"6.9.86-42941": {
|
||||||
|
"appid": 537328648,
|
||||||
|
"qua": "V1_MAC_NQ_6.9.86_42941_GW_B"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
36
packages/napcat-core/external/napi2native.json
vendored
36
packages/napcat-core/external/napi2native.json
vendored
@@ -90,5 +90,41 @@
|
|||||||
"3.2.21-42086-x64": {
|
"3.2.21-42086-x64": {
|
||||||
"send": "5B42CF0",
|
"send": "5B42CF0",
|
||||||
"recv": "2FDA6F0"
|
"recv": "2FDA6F0"
|
||||||
|
},
|
||||||
|
"9.9.23-42430-x64": {
|
||||||
|
"send": "0A01A34",
|
||||||
|
"recv": "1D1CFF9"
|
||||||
|
},
|
||||||
|
"9.9.25-42744-x64": {
|
||||||
|
"send": "0A0D104",
|
||||||
|
"recv": "1D3E7F9"
|
||||||
|
},
|
||||||
|
"6.9.85-42744-arm64": {
|
||||||
|
"send": "23DFEF0",
|
||||||
|
"recv": "095FD80"
|
||||||
|
},
|
||||||
|
"9.9.25-42905-x64": {
|
||||||
|
"send": "0A12E74",
|
||||||
|
"recv": "1D450FD"
|
||||||
|
},
|
||||||
|
"6.9.86-42905-arm64": {
|
||||||
|
"send": "2342408",
|
||||||
|
"recv": "09639B8"
|
||||||
|
},
|
||||||
|
"3.2.22-42941-x64": {
|
||||||
|
"send": "5BC1630",
|
||||||
|
"recv": "3011E00"
|
||||||
|
},
|
||||||
|
"3.2.22-42941-arm64": {
|
||||||
|
"send": "3DC90AC",
|
||||||
|
"recv": "1497A70"
|
||||||
|
},
|
||||||
|
"9.9.25-42941-x64": {
|
||||||
|
"send": "0A131D4",
|
||||||
|
"recv": "1D4547D"
|
||||||
|
},
|
||||||
|
"6.9.86-42941-arm64": {
|
||||||
|
"send": "2346108",
|
||||||
|
"recv": "09675F0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
36
packages/napcat-core/external/packet.json
vendored
36
packages/napcat-core/external/packet.json
vendored
@@ -602,5 +602,41 @@
|
|||||||
"3.2.21-42086-arm64": {
|
"3.2.21-42086-arm64": {
|
||||||
"send": "6B13038",
|
"send": "6B13038",
|
||||||
"recv": "6B169C8"
|
"recv": "6B169C8"
|
||||||
|
},
|
||||||
|
"9.9.23-42430-x64": {
|
||||||
|
"send": "2C9A4A0",
|
||||||
|
"recv": "2C9DA20"
|
||||||
|
},
|
||||||
|
"9.9.25-42744-x64": {
|
||||||
|
"send": "2CD8E40",
|
||||||
|
"recv": "2CDC3C0"
|
||||||
|
},
|
||||||
|
"6.9.86-42744-arm64": {
|
||||||
|
"send": "3DCC840",
|
||||||
|
"recv": "3DCF150"
|
||||||
|
},
|
||||||
|
"9.9.25-42905-x64": {
|
||||||
|
"send": "2CE46A0",
|
||||||
|
"recv": "2CE7C20"
|
||||||
|
},
|
||||||
|
"6.9.86-42905-arm64": {
|
||||||
|
"send": "3DD6098",
|
||||||
|
"recv": "3DD89A8"
|
||||||
|
},
|
||||||
|
"3.2.22-42941-x64": {
|
||||||
|
"send": "A8AD8A0",
|
||||||
|
"recv": "A8B1320"
|
||||||
|
},
|
||||||
|
"9.9.25-42941-x64": {
|
||||||
|
"send": "2CE4DA0",
|
||||||
|
"recv": "2CE8320"
|
||||||
|
},
|
||||||
|
"3.2.22-42941-arm64": {
|
||||||
|
"send": "6BC95E8",
|
||||||
|
"recv": "6BCCF78"
|
||||||
|
},
|
||||||
|
"6.9.86-42941-arm64": {
|
||||||
|
"send": "3DDDAD0",
|
||||||
|
"recv": "3DE03E0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// TODO: further refactor in NapCat.Packet v2
|
// TODO: further refactor in NapCat.Packet v2
|
||||||
import { NapProtoMsg, ProtoField, ScalarType } from '@napneko/nap-proto-core';
|
import { NapProtoMsg, ProtoField, ScalarType } from 'napcat-protobuf';
|
||||||
|
|
||||||
const LikeDetail = {
|
const LikeDetail = {
|
||||||
txt: ProtoField(1, ScalarType.STRING),
|
txt: ProtoField(1, ScalarType.STRING),
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import fsPromise from 'fs/promises';
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
import { EncodeResult, getDuration, getWavFileInfo, isSilk, isWav } from 'silk-wasm';
|
import { EncodeResult, getDuration, getWavFileInfo, isSilk, isWav } from 'silk-wasm';
|
||||||
import { LogWrapper } from '@/napcat-common/log';
|
import { LogWrapper } from '@/napcat-core/helper/log';
|
||||||
import { EncodeArgs } from '@/napcat-common/audio-worker';
|
import { EncodeArgs } from 'napcat-common/src/audio-worker';
|
||||||
import { FFmpegService } from '@/napcat-common/ffmpeg';
|
import { FFmpegService } from '@/napcat-core/helper/ffmpeg/ffmpeg';
|
||||||
import { runTask } from './worker';
|
import { runTask } from 'napcat-common/src/worker';
|
||||||
import { fileURLToPath } from 'node:url';
|
import { fileURLToPath } from 'node:url';
|
||||||
|
|
||||||
const ALLOW_SAMPLE_RATE = [8000, 12000, 16000, 24000, 32000, 44100, 48000];
|
const ALLOW_SAMPLE_RATE = [8000, 12000, 16000, 24000, 32000, 44100, 48000];
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import type { NapCatCore } from 'napcat-core';
|
import type { NapCatCore } from '@/napcat-core';
|
||||||
import json5 from 'json5';
|
import json5 from 'json5';
|
||||||
import Ajv, { AnySchema, ValidateFunction } from 'ajv';
|
import Ajv, { AnySchema, ValidateFunction } from 'ajv';
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ConfigBase } from 'napcat-common/src/config-base';
|
import { ConfigBase } from '@/napcat-core/helper/config-base';
|
||||||
import { NapCatCore } from '@/napcat-core/index';
|
import { NapCatCore } from '@/napcat-core/index';
|
||||||
import { Type, Static } from '@sinclair/typebox';
|
import { Type, Static } from '@sinclair/typebox';
|
||||||
import { AnySchema } from 'ajv';
|
import { AnySchema } from 'ajv';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { NodeIQQNTWrapperSession } from '@/napcat-core/wrapper';
|
import { NodeIQQNTWrapperSession } from '@/napcat-core/wrapper';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
import { ListenerNamingMapping, ServiceNamingMapping } from '@/napcat-core';
|
import { ListenerNamingMapping, ServiceNamingMapping } from '@/napcat-core/index';
|
||||||
|
|
||||||
interface InternalMapKey {
|
interface InternalMapKey {
|
||||||
timeout: number;
|
timeout: number;
|
||||||
@@ -54,7 +54,7 @@ export class NTEventWrapper {
|
|||||||
Service extends keyof ServiceNamingMapping,
|
Service extends keyof ServiceNamingMapping,
|
||||||
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
|
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
|
||||||
T extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
|
T extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
|
||||||
> (eventName: `${Service}/${ServiceMethod}`): T | undefined {
|
>(eventName: `${Service}/${ServiceMethod}`): T | undefined {
|
||||||
const eventNameArr = eventName.split('/');
|
const eventNameArr = eventName.split('/');
|
||||||
type eventType = {
|
type eventType = {
|
||||||
[key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>>; };
|
[key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>>; };
|
||||||
@@ -112,7 +112,7 @@ export class NTEventWrapper {
|
|||||||
Service extends keyof ServiceNamingMapping,
|
Service extends keyof ServiceNamingMapping,
|
||||||
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
|
ServiceMethod extends FuncKeys<ServiceNamingMapping[Service]>,
|
||||||
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
|
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>
|
||||||
> (
|
>(
|
||||||
serviceAndMethod: `${Service}/${ServiceMethod}`,
|
serviceAndMethod: `${Service}/${ServiceMethod}`,
|
||||||
...args: Parameters<EventType>
|
...args: Parameters<EventType>
|
||||||
): Promise<Awaited<ReturnType<EventType>>> {
|
): Promise<Awaited<ReturnType<EventType>>> {
|
||||||
@@ -123,7 +123,7 @@ export class NTEventWrapper {
|
|||||||
Listener extends keyof ListenerNamingMapping,
|
Listener extends keyof ListenerNamingMapping,
|
||||||
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
|
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
|
||||||
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
|
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
|
||||||
> (
|
>(
|
||||||
listenerAndMethod: `${Listener}/${ListenerMethod}`,
|
listenerAndMethod: `${Listener}/${ListenerMethod}`,
|
||||||
checker: (...args: Parameters<ListenerType>) => boolean,
|
checker: (...args: Parameters<ListenerType>) => boolean,
|
||||||
waitTimes = 1,
|
waitTimes = 1,
|
||||||
@@ -177,7 +177,7 @@ export class NTEventWrapper {
|
|||||||
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
|
ListenerMethod extends FuncKeys<ListenerNamingMapping[Listener]>,
|
||||||
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>,
|
EventType extends (...args: any) => any = EnsureFunc<ServiceNamingMapping[Service][ServiceMethod]>,
|
||||||
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
|
ListenerType extends (...args: any) => any = EnsureFunc<ListenerNamingMapping[Listener][ListenerMethod]>
|
||||||
> (
|
>(
|
||||||
serviceAndMethod: `${Service}/${ServiceMethod}`,
|
serviceAndMethod: `${Service}/${ServiceMethod}`,
|
||||||
listenerAndMethod: `${Listener}/${ListenerMethod}`,
|
listenerAndMethod: `${Listener}/${ListenerMethod}`,
|
||||||
args: Parameters<EventType>,
|
args: Parameters<EventType>,
|
||||||
@@ -6,7 +6,7 @@ import * as os from 'os';
|
|||||||
import * as compressing from 'compressing'; // 修正导入方式
|
import * as compressing from 'compressing'; // 修正导入方式
|
||||||
import { pipeline } from 'stream/promises';
|
import { pipeline } from 'stream/promises';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { LogWrapper } from './log';
|
import { LogWrapper } from '@/napcat-core/helper/log';
|
||||||
|
|
||||||
const downloadOri = 'https://github.com/NapNeko/ffmpeg-build/releases/download/v1.0.0/ffmpeg-7.1.1-win64.zip';
|
const downloadOri = 'https://github.com/NapNeko/ffmpeg-build/releases/download/v1.0.0/ffmpeg-7.1.1-win64.zip';
|
||||||
const urls = [
|
const urls = [
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
* 自动检测并选择最佳的 FFmpeg 适配器
|
* 自动检测并选择最佳的 FFmpeg 适配器
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { LogWrapper } from './log';
|
import { LogWrapper } from '@/napcat-core/helper/log';
|
||||||
import { FFmpegAddonAdapter } from './ffmpeg-addon-adapter';
|
import { FFmpegAddonAdapter } from './ffmpeg-addon-adapter';
|
||||||
import { FFmpegExecAdapter } from './ffmpeg-exec-adapter';
|
import { FFmpegExecAdapter } from './ffmpeg-exec-adapter';
|
||||||
import type { IFFmpegAdapter } from './ffmpeg-adapter-interface';
|
import type { IFFmpegAdapter } from './ffmpeg-adapter-interface';
|
||||||
@@ -68,13 +68,13 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
|
|||||||
const addon = this.ensureAddon();
|
const addon = this.ensureAddon();
|
||||||
const info = await addon.getVideoInfo(videoPath);
|
const info = await addon.getVideoInfo(videoPath);
|
||||||
|
|
||||||
let format = info.format.includes(',') ? info.format.split(',')[0] ?? info.format : info.format;
|
const format = info.format.includes(',') ? info.format.split(',')[0] ?? info.format : info.format;
|
||||||
console.log('[FFmpegAddonAdapter] Detected format:', format);
|
console.log('[FFmpegAddonAdapter] Detected format:', format);
|
||||||
return {
|
return {
|
||||||
width: info.width,
|
width: info.width,
|
||||||
height: info.height,
|
height: info.height,
|
||||||
duration: info.duration,
|
duration: info.duration,
|
||||||
format: format,
|
format,
|
||||||
thumbnail: info.image,
|
thumbnail: info.image,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ import { promisify } from 'util';
|
|||||||
import { fileTypeFromFile } from 'file-type';
|
import { fileTypeFromFile } from 'file-type';
|
||||||
import { imageSizeFallBack } from 'napcat-image-size/src/index';
|
import { imageSizeFallBack } from 'napcat-image-size/src/index';
|
||||||
import { downloadFFmpegIfNotExists } from './download-ffmpeg';
|
import { downloadFFmpegIfNotExists } from './download-ffmpeg';
|
||||||
import { LogWrapper } from './log';
|
import { LogWrapper } from '@/napcat-core/helper/log';
|
||||||
import type { IFFmpegAdapter, VideoInfoResult } from './ffmpeg-adapter-interface';
|
import type { IFFmpegAdapter, VideoInfoResult } from './ffmpeg-adapter-interface';
|
||||||
|
|
||||||
const execFileAsync = promisify(execFile);
|
const execFileAsync = promisify(execFile);
|
||||||
@@ -3,7 +3,7 @@ import path from 'path';
|
|||||||
import type { VideoInfo } from './video';
|
import type { VideoInfo } from './video';
|
||||||
import { fileTypeFromFile } from 'file-type';
|
import { fileTypeFromFile } from 'file-type';
|
||||||
import { platform } from 'node:os';
|
import { platform } from 'node:os';
|
||||||
import { LogWrapper } from './log';
|
import { LogWrapper } from '@/napcat-core/helper/log';
|
||||||
import { FFmpegAdapterFactory } from './ffmpeg-adapter-factory';
|
import { FFmpegAdapterFactory } from './ffmpeg-adapter-factory';
|
||||||
import type { IFFmpegAdapter } from './ffmpeg-adapter-interface';
|
import type { IFFmpegAdapter } from './ffmpeg-adapter-interface';
|
||||||
|
|
||||||
@@ -53,7 +53,6 @@ export class FFmpegService {
|
|||||||
throw new Error('FFmpeg service not initialized. Please call FFmpegService.init() first.');
|
throw new Error('FFmpeg service not initialized. Please call FFmpegService.init() first.');
|
||||||
}
|
}
|
||||||
return this.adapter.name;
|
return this.adapter.name;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import winston, { format, transports } from 'winston';
|
import winston, { format, transports } from 'winston';
|
||||||
import { truncateString } from './helper';
|
import { truncateString } from 'napcat-common/src/helper';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
import { NTMsgAtType, ChatType, ElementType, MessageElement, RawMessage, SelfInfo } from 'napcat-core/index';
|
import { NTMsgAtType, ChatType, ElementType, MessageElement, RawMessage, SelfInfo } from '@/napcat-core/index';
|
||||||
|
import { ILogWrapper } from 'napcat-common/src/log-interface';
|
||||||
import EventEmitter from 'node:events';
|
import EventEmitter from 'node:events';
|
||||||
export enum LogLevel {
|
export enum LogLevel {
|
||||||
DEBUG = 'debug',
|
DEBUG = 'debug',
|
||||||
@@ -56,7 +57,7 @@ class Subscription {
|
|||||||
|
|
||||||
export const logSubscription = new Subscription();
|
export const logSubscription = new Subscription();
|
||||||
|
|
||||||
export class LogWrapper {
|
export class LogWrapper implements ILogWrapper {
|
||||||
fileLogEnabled = true;
|
fileLogEnabled = true;
|
||||||
consoleLogEnabled = true;
|
consoleLogEnabled = true;
|
||||||
logger: winston.Logger;
|
logger: winston.Logger;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { LogWrapper } from '@/napcat-common/log';
|
import { LogWrapper } from '@/napcat-core/helper/log';
|
||||||
|
|
||||||
export function proxyHandlerOf (logger: LogWrapper) {
|
export function proxyHandlerOf (logger: LogWrapper) {
|
||||||
return {
|
return {
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import { systemPlatform } from '@/napcat-common/system';
|
import { systemPlatform } from 'napcat-common/src/system';
|
||||||
import { getDefaultQQVersionConfigInfo, getQQPackageInfoPath, getQQVersionConfigPath, parseAppidFromMajor } from './helper';
|
import { getDefaultQQVersionConfigInfo, getQQPackageInfoPath, getQQVersionConfigPath, parseAppidFromMajor } from 'napcat-common/src/helper';
|
||||||
import AppidTable from 'napcat-core/external/appid.json';
|
import AppidTable from '@/napcat-core/external/appid.json';
|
||||||
import { LogWrapper } from '@/napcat-common/log';
|
import { LogWrapper } from './log';
|
||||||
import { getMajorPath } from 'napcat-core';
|
import { getMajorPath } from '@/napcat-core/index';
|
||||||
import { QQAppidTableType, QQPackageInfoType, QQVersionConfigType } from './types';
|
import { QQAppidTableType, QQPackageInfoType, QQVersionConfigType } from 'napcat-common/src/types';
|
||||||
|
|
||||||
export class QQBasicInfoWrapper {
|
export class QQBasicInfoWrapper {
|
||||||
QQMainPath: string | undefined;
|
QQMainPath: string | undefined;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { LogWrapper } from 'napcat-common/src/log';
|
|
||||||
import { RequestUtil } from 'napcat-common/src/request';
|
import { RequestUtil } from 'napcat-common/src/request';
|
||||||
|
import { LogWrapper } from './log';
|
||||||
|
|
||||||
interface ServerRkeyData {
|
interface ServerRkeyData {
|
||||||
group_rkey: string;
|
group_rkey: string;
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import EventEmitter from 'node:events';
|
import EventEmitter from 'node:events';
|
||||||
|
import { IStatusHelperSubscription } from 'napcat-common/src/status-interface';
|
||||||
export interface SystemStatus {
|
export interface SystemStatus {
|
||||||
cpu: {
|
cpu: {
|
||||||
model: string,
|
model: string,
|
||||||
speed: string
|
speed: string;
|
||||||
usage: {
|
usage: {
|
||||||
system: string
|
system: string;
|
||||||
qq: string
|
qq: string;
|
||||||
},
|
},
|
||||||
core: number
|
core: number;
|
||||||
},
|
},
|
||||||
memory: {
|
memory: {
|
||||||
total: string
|
total: string;
|
||||||
usage: {
|
usage: {
|
||||||
system: string
|
system: string;
|
||||||
qq: string
|
qq: string;
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
arch: string
|
arch: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StatusHelper {
|
export class StatusHelper {
|
||||||
@@ -101,7 +101,7 @@ export class StatusHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StatusHelperSubscription extends EventEmitter {
|
class StatusHelperSubscription extends EventEmitter implements IStatusHelperSubscription {
|
||||||
private statusHelper: StatusHelper;
|
private statusHelper: StatusHelper;
|
||||||
private interval: NodeJS.Timeout | null = null;
|
private interval: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
|
|||||||
@@ -16,21 +16,24 @@ import {
|
|||||||
WrapperNodeApi,
|
WrapperNodeApi,
|
||||||
WrapperSessionInitConfig,
|
WrapperSessionInitConfig,
|
||||||
} from '@/napcat-core/wrapper';
|
} from '@/napcat-core/wrapper';
|
||||||
import { LogLevel, LogWrapper } from 'napcat-common/src/log';
|
import { LogLevel, LogWrapper } from '@/napcat-core/helper/log';
|
||||||
import { NodeIKernelLoginService } from '@/napcat-core/services';
|
import { NodeIKernelLoginService } from '@/napcat-core/services';
|
||||||
import { QQBasicInfoWrapper } from 'napcat-common/src/qq-basic-info';
|
import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info';
|
||||||
import { NapCatPathWrapper } from 'napcat-common/src/path';
|
import { NapCatPathWrapper } from 'napcat-common/src/path';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import { hostname, systemName, systemVersion } from 'napcat-common/src/system';
|
import { hostname, systemName, systemVersion } from 'napcat-common/src/system';
|
||||||
import { NTEventWrapper } from 'napcat-common/src/event';
|
import { NTEventWrapper } from '@/napcat-core/helper/event';
|
||||||
import { KickedOffLineInfo, SelfInfo, SelfStatusInfo } from '@/napcat-core/types';
|
import { KickedOffLineInfo, SelfInfo, SelfStatusInfo } from '@/napcat-core/types';
|
||||||
import { NapCatConfigLoader, NapcatConfigSchema } from '@/napcat-core/helper/config';
|
import { NapCatConfigLoader, NapcatConfigSchema } from '@/napcat-core/helper/config';
|
||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
import { NodeIKernelMsgListener, NodeIKernelProfileListener } from '@/napcat-core/listeners';
|
import { NodeIKernelMsgListener, NodeIKernelProfileListener } from '@/napcat-core/listeners';
|
||||||
import { proxiedListenerOf } from 'napcat-common/src/proxy-handler';
|
import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler';
|
||||||
import { NTQQPacketApi } from './apis/packet';
|
import { NTQQPacketApi } from './apis/packet';
|
||||||
import { NativePacketHandler } from './packet/handler/client';
|
import { NativePacketHandler } from './packet/handler/client';
|
||||||
|
import { container, ReceiverServiceRegistry } from './packet/handler/serviceRegister';
|
||||||
|
import { appEvent } from './packet/handler/eventList';
|
||||||
|
import { TypedEventEmitter } from './packet/handler/typeEvent';
|
||||||
export * from './wrapper';
|
export * from './wrapper';
|
||||||
export * from './types/index';
|
export * from './types/index';
|
||||||
export * from './services/index';
|
export * from './services/index';
|
||||||
@@ -92,6 +95,7 @@ export function getMajorPath (QQVersion: string): string {
|
|||||||
export class NapCatCore {
|
export class NapCatCore {
|
||||||
readonly context: InstanceContext;
|
readonly context: InstanceContext;
|
||||||
readonly eventWrapper: NTEventWrapper;
|
readonly eventWrapper: NTEventWrapper;
|
||||||
|
event = appEvent;
|
||||||
NapCatDataPath: string = '';
|
NapCatDataPath: string = '';
|
||||||
NapCatTempPath: string = '';
|
NapCatTempPath: string = '';
|
||||||
apis: StableNTApiWrapper;
|
apis: StableNTApiWrapper;
|
||||||
@@ -118,6 +122,16 @@ export class NapCatCore {
|
|||||||
UserApi: new NTQQUserApi(this.context, this),
|
UserApi: new NTQQUserApi(this.context, this),
|
||||||
GroupApi: new NTQQGroupApi(this.context, this),
|
GroupApi: new NTQQGroupApi(this.context, this),
|
||||||
};
|
};
|
||||||
|
container.bind(NapCatCore).toConstantValue(this);
|
||||||
|
container.bind(TypedEventEmitter).toConstantValue(this.event);
|
||||||
|
ReceiverServiceRegistry.forEach((ServiceClass, serviceName) => {
|
||||||
|
container.bind(ServiceClass).toSelf();
|
||||||
|
console.log(`Registering service handler for: ${serviceName}`);
|
||||||
|
this.context.packetHandler.onCmd(serviceName, ({ seq, hex_data }) => {
|
||||||
|
const serviceInstance = container.get(ServiceClass);
|
||||||
|
return serviceInstance.handler(seq, hex_data);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async initCore () {
|
async initCore () {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ChatType, KickedOffLineInfo, RawMessage } from '@/napcat-core/types';
|
import { ChatType, KickedOffLineInfo, RawMessage } from '@/napcat-core/types';
|
||||||
import { CommonFileInfo } from '@/napcat-core';
|
import { CommonFileInfo } from '@/napcat-core/index';
|
||||||
|
|
||||||
export interface OnRichMediaDownloadCompleteParams {
|
export interface OnRichMediaDownloadCompleteParams {
|
||||||
fileModelId: string,
|
fileModelId: string,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export class NodeIKernelStorageCleanListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onScanCacheProgressChanged (_args: unknown): any {
|
onScanCacheProgressChanged (_current_progress: number, _total_progress: number): any {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ export class NodeIKernelStorageCleanListener {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onFinishScan (_args: unknown): any {
|
onFinishScan (_sizes: Array<`${number}`>): any {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
|
"scripts": {
|
||||||
|
"typecheck": "tsc --noEmit --skipLibCheck -p tsconfig.json"
|
||||||
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"import": "./index.ts"
|
"import": "./index.ts"
|
||||||
@@ -13,14 +16,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"winston": "^3.17.0",
|
||||||
|
"json5": "^2.2.3",
|
||||||
|
"inversify": "^7.10.4",
|
||||||
|
"reflect-metadata": "^0.2.2",
|
||||||
"@protobuf-ts/runtime": "^2.11.1",
|
"@protobuf-ts/runtime": "^2.11.1",
|
||||||
"@napneko/nap-proto-core": "^0.0.4",
|
|
||||||
"ajv": "^8.13.0",
|
"ajv": "^8.13.0",
|
||||||
"@sinclair/typebox": "^0.34.38",
|
"@sinclair/typebox": "^0.34.38",
|
||||||
"file-type": "^21.0.0",
|
"file-type": "^21.0.0",
|
||||||
|
"compressing": "^1.10.1",
|
||||||
"napcat-image-size": "workspace:*",
|
"napcat-image-size": "workspace:*",
|
||||||
"napcat-common": "workspace:*",
|
"napcat-common": "workspace:*",
|
||||||
"napcat-onebot": "workspace:*"
|
"napcat-protobuf": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^22.0.1"
|
"@types/node": "^22.0.1"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { LogLevel, LogWrapper } from 'napcat-common/src/log';
|
|
||||||
import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
|
import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
|
||||||
|
import { LogWrapper, LogLevel } from '@/napcat-core/helper/log';
|
||||||
|
|
||||||
// TODO: check bind?
|
// TODO: check bind?
|
||||||
export class PacketLogger {
|
export class PacketLogger {
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ import {
|
|||||||
PacketMsgReplyElement,
|
PacketMsgReplyElement,
|
||||||
PacketMsgVideoElement,
|
PacketMsgVideoElement,
|
||||||
} from '@/napcat-core/packet/message/element';
|
} from '@/napcat-core/packet/message/element';
|
||||||
import { ChatType, MsgSourceType, NTMsgType, RawMessage } from '@/napcat-core';
|
import { ChatType, MsgSourceType, NTMsgType, RawMessage } from '@/napcat-core/index';
|
||||||
import { MiniAppRawData, MiniAppReqParams } from '@/napcat-core/packet/entities/miniApp';
|
import { MiniAppRawData, MiniAppReqParams } from '@/napcat-core/packet/entities/miniApp';
|
||||||
import { AIVoiceChatType } from '@/napcat-core/packet/entities/aiChat';
|
import { AIVoiceChatType } from '@/napcat-core/packet/entities/aiChat';
|
||||||
import { NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { IndexNode, LongMsgResult, MsgInfo, PushMsgBody } from '@/napcat-core/packet/transformer/proto';
|
import { IndexNode, LongMsgResult, MsgInfo, PushMsgBody } from '@/napcat-core/packet/transformer/proto';
|
||||||
import { OidbPacket } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket } from '@/napcat-core/packet/transformer/base';
|
||||||
import { ImageOcrResult } from '@/napcat-core/packet/entities/ocrResult';
|
import { ImageOcrResult } from '@/napcat-core/packet/entities/ocrResult';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { PacketHighwayContext } from '@/napcat-core/packet/highway/highwayContext';
|
import { PacketHighwayContext } from '@/napcat-core/packet/highway/highwayContext';
|
||||||
import { NapCatCore } from '@/napcat-core';
|
import { NapCatCore } from '@/napcat-core/index';
|
||||||
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
|
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
|
||||||
import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
|
import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
|
||||||
import { PacketClientContext } from '@/napcat-core/packet/context/clientContext';
|
import { PacketClientContext } from '@/napcat-core/packet/context/clientContext';
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import path, { dirname } from 'path';
|
|||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { constants } from 'node:os';
|
import { constants } from 'node:os';
|
||||||
import { LogWrapper } from 'napcat-common/src/log';
|
|
||||||
import offset from '@/napcat-core/external/packet.json';
|
import offset from '@/napcat-core/external/packet.json';
|
||||||
|
import { LogWrapper } from '../../helper/log';
|
||||||
interface OffsetType {
|
interface OffsetType {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
recv: string;
|
recv: string;
|
||||||
@@ -50,7 +50,6 @@ export class NativePacketHandler {
|
|||||||
this.logger.logError('NativePacketClient 加载出错:', error);
|
this.logger.logError('NativePacketClient 加载出错:', error);
|
||||||
this.loaded = false;
|
this.loaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
6
packages/napcat-core/packet/handler/eventList.ts
Normal file
6
packages/napcat-core/packet/handler/eventList.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { TypedEventEmitter } from './typeEvent';
|
||||||
|
|
||||||
|
export interface AppEvents {
|
||||||
|
'event:emoji_like': { groupId: string; senderUin: string; emojiId: string, msgSeq: string, isAdd: boolean, count: number };
|
||||||
|
}
|
||||||
|
export const appEvent = new TypedEventEmitter<AppEvents>();
|
||||||
28
packages/napcat-core/packet/handler/serviceRegister.ts
Normal file
28
packages/napcat-core/packet/handler/serviceRegister.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import 'reflect-metadata';
|
||||||
|
import { Container, injectable } from 'inversify';
|
||||||
|
import { NapCatCore } from '../..';
|
||||||
|
import { TypedEventEmitter } from './typeEvent';
|
||||||
|
|
||||||
|
export const container = new Container();
|
||||||
|
|
||||||
|
export const ReceiverServiceRegistry = new Map<string, new (...args: any[]) => ServiceBase>();
|
||||||
|
|
||||||
|
export abstract class ServiceBase {
|
||||||
|
get core (): NapCatCore {
|
||||||
|
return container.get(NapCatCore);
|
||||||
|
}
|
||||||
|
|
||||||
|
get event () {
|
||||||
|
return container.get(TypedEventEmitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract handler (seq: number, hex_data: string): Promise<void> | void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ReceiveService (serviceName: string) {
|
||||||
|
return function <T extends new (...args: any[]) => ServiceBase>(constructor: T) {
|
||||||
|
injectable()(constructor);
|
||||||
|
ReceiverServiceRegistry.set(serviceName, constructor);
|
||||||
|
return constructor;
|
||||||
|
};
|
||||||
|
}
|
||||||
22
packages/napcat-core/packet/handler/typeEvent.ts
Normal file
22
packages/napcat-core/packet/handler/typeEvent.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { EventEmitter } from 'node:events';
|
||||||
|
|
||||||
|
export class TypedEventEmitter<E extends Record<string, any>> {
|
||||||
|
private emitter = new EventEmitter();
|
||||||
|
|
||||||
|
on<K extends keyof E>(event: K, listener: (payload: E[K]) => void) {
|
||||||
|
this.emitter.on(event as string, listener);
|
||||||
|
return () => this.off(event, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
once<K extends keyof E>(event: K, listener: (payload: E[K]) => void) {
|
||||||
|
this.emitter.once(event as string, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
off<K extends keyof E>(event: K, listener: (payload: E[K]) => void) {
|
||||||
|
this.emitter.off(event as string, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit<K extends keyof E>(event: K, payload: E[K]) {
|
||||||
|
this.emitter.emit(event as string, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
import { ChatType, Peer } from '@/napcat-core/index';
|
import { ChatType, Peer } from '@/napcat-core/index';
|
||||||
import { calculateSha1, calculateSha1StreamBytes, computeMd5AndLengthWithLimit } from '@/napcat-core/packet/utils/crypto/hash';
|
import { calculateSha1, calculateSha1StreamBytes, computeMd5AndLengthWithLimit } from '@/napcat-core/packet/utils/crypto/hash';
|
||||||
import UploadGroupImage from '@/napcat-core/packet/transformer/highway/UploadGroupImage';
|
import UploadGroupImage from '@/napcat-core/packet/transformer/highway/UploadGroupImage';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import * as trans from '@/napcat-core/packet/transformer';
|
import * as trans from '@/napcat-core/packet/transformer';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { IHighwayUploader } from '@/napcat-core/packet/highway/uploader/highwayUploader';
|
import { IHighwayUploader } from '@/napcat-core/packet/highway/uploader/highwayUploader';
|
||||||
import { Frame } from '@/napcat-core/packet/highway/frame';
|
import { Frame } from '@/napcat-core/packet/highway/frame';
|
||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import net from 'node:net';
|
import net from 'node:net';
|
||||||
import stream from 'node:stream';
|
import stream from 'node:stream';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { BlockSize } from '@/napcat-core/packet/highway/highwayContext';
|
import { BlockSize } from '@/napcat-core/packet/highway/highwayContext';
|
||||||
import { Frame } from '@/napcat-core/packet/highway/frame';
|
import { Frame } from '@/napcat-core/packet/highway/frame';
|
||||||
import { IHighwayUploader } from '@/napcat-core/packet/highway/uploader/highwayUploader';
|
import { IHighwayUploader } from '@/napcat-core/packet/highway/uploader/highwayUploader';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// import * as tea from '@/napcat-core/packet/utils/crypto/tea';
|
// import * as tea from '@/napcat-core/packet/utils/crypto/tea';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { PacketHighwayTrans } from '@/napcat-core/packet/highway/client';
|
import { PacketHighwayTrans } from '@/napcat-core/packet/highway/client';
|
||||||
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
|
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
|
||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { NapProtoEncodeStructType } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType } from 'napcat-protobuf';
|
||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|
||||||
export const int32ip2str = (ip: number) => {
|
export const int32ip2str = (ip: number) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import { PushMsgBody } from '@/napcat-core/packet/transformer/proto';
|
import { PushMsgBody } from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoEncodeStructType } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType } from 'napcat-protobuf';
|
||||||
import { PacketMsg, PacketSendMsgElement } from '@/napcat-core/packet/message/message';
|
import { PacketMsg, PacketSendMsgElement } from '@/napcat-core/packet/message/message';
|
||||||
import { IPacketMsgElement, PacketMsgTextElement } from '@/napcat-core/packet/message/element';
|
import { IPacketMsgElement, PacketMsgTextElement } from '@/napcat-core/packet/message/element';
|
||||||
import { SendTextElement } from '@/napcat-core/index';
|
import { SendTextElement } from '@/napcat-core/index';
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
PacketMultiMsgElement,
|
PacketMultiMsgElement,
|
||||||
} from '@/napcat-core/packet/message/element';
|
} from '@/napcat-core/packet/message/element';
|
||||||
import { PacketMsg, PacketSendMsgElement } from '@/napcat-core/packet/message/message';
|
import { PacketMsg, PacketSendMsgElement } from '@/napcat-core/packet/message/message';
|
||||||
import { NapProtoDecodeStructType } from '@napneko/nap-proto-core';
|
import { NapProtoDecodeStructType } from 'napcat-protobuf';
|
||||||
import { Elem } from '@/napcat-core/packet/transformer/proto';
|
import { Elem } from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|
||||||
const SupportedElementTypes = [
|
const SupportedElementTypes = [
|
||||||
@@ -132,7 +132,6 @@ export class PacketMsgConverter {
|
|||||||
time: msg.time,
|
time: msg.time,
|
||||||
msg: msg.msg.map((element) => {
|
msg: msg.msg.map((element) => {
|
||||||
if (!this.isValidElementType(element.elementType)) return null;
|
if (!this.isValidElementType(element.elementType)) return null;
|
||||||
// @ts-ignore
|
|
||||||
return this.rawToPacketMsgConverters[element.elementType](element as MessageElement);
|
return this.rawToPacketMsgConverters[element.elementType](element as MessageElement);
|
||||||
}).filter((e) => e !== null),
|
}).filter((e) => e !== null),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as zlib from 'node:zlib';
|
import * as zlib from 'node:zlib';
|
||||||
import { NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoDecodeStructType, NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import {
|
import {
|
||||||
CustomFace,
|
CustomFace,
|
||||||
Elem,
|
Elem,
|
||||||
@@ -32,8 +32,8 @@ import {
|
|||||||
SendTextElement,
|
SendTextElement,
|
||||||
SendVideoElement,
|
SendVideoElement,
|
||||||
Peer,
|
Peer,
|
||||||
} from '@/napcat-core';
|
} from '@/napcat-core/index';
|
||||||
import { ForwardMsgBuilder } from 'napcat-common/src/forward-msg-builder';
|
import { ForwardMsgBuilder } from '@/napcat-core/helper/forward-msg-builder';
|
||||||
import { PacketMsg, PacketSendMsgElement } from '@/napcat-core/packet/message/message';
|
import { PacketMsg, PacketSendMsgElement } from '@/napcat-core/packet/message/message';
|
||||||
|
|
||||||
export type ParseElementFnR = [MessageElement, NapProtoDecodeStructType<typeof Elem> | null] | undefined;
|
export type ParseElementFnR = [MessageElement, NapProtoDecodeStructType<typeof Elem> | null] | undefined;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { IPacketMsgElement } from '@/napcat-core/packet/message/element';
|
import { IPacketMsgElement } from '@/napcat-core/packet/message/element';
|
||||||
import { SendMessageElement, SendMultiForwardMsgElement } from '@/napcat-core';
|
import { SendMessageElement, SendMultiForwardMsgElement } from '@/napcat-core/index';
|
||||||
|
|
||||||
export type PacketSendMsgElement = SendMessageElement | SendMultiForwardMsgElement;
|
export type PacketSendMsgElement = SendMessageElement | SendMultiForwardMsgElement;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { AIVoiceChatType } from '@/napcat-core/packet/entities/aiChat';
|
import { AIVoiceChatType } from '@/napcat-core/packet/entities/aiChat';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { AIVoiceChatType } from '@/napcat-core/packet/entities/aiChat';
|
import { AIVoiceChatType } from '@/napcat-core/packet/entities/aiChat';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import { MiniAppReqParams } from '@/napcat-core/packet/entities/miniApp';
|
import { MiniAppReqParams } from '@/napcat-core/packet/entities/miniApp';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { NapProtoDecodeStructType } from '@napneko/nap-proto-core';
|
import { NapProtoDecodeStructType } from 'napcat-protobuf';
|
||||||
import { PacketMsgBuilder } from '@/napcat-core/packet/message/builder';
|
import { PacketMsgBuilder } from '@/napcat-core/packet/message/builder';
|
||||||
|
|
||||||
export type PacketBuf = Buffer & { readonly hexNya: unique symbol; };
|
export type PacketBuf = Buffer & { readonly hexNya: unique symbol; };
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoEncodeStructType, NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoEncodeStructType, NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
import { IndexNode } from '@/napcat-core/packet/transformer/proto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketBufBuilder, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
|
|
||||||
class FetchSessionKey extends PacketTransformer<typeof proto.HttpConn0x6ff_501Response> {
|
class FetchSessionKey extends PacketTransformer<typeof proto.HttpConn0x6ff_501Response> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { PacketMsgFileElement } from '@/napcat-core/packet/message/element';
|
import { PacketMsgFileElement } from '@/napcat-core/packet/message/element';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import { PacketMsgFileElement } from '@/napcat-core/packet/message/element';
|
import { PacketMsgFileElement } from '@/napcat-core/packet/message/element';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as proto from '@/napcat-core/packet/transformer/proto';
|
import * as proto from '@/napcat-core/packet/transformer/proto';
|
||||||
import { NapProtoMsg } from '@napneko/nap-proto-core';
|
import { NapProtoMsg } from 'napcat-protobuf';
|
||||||
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
import { OidbPacket, PacketTransformer } from '@/napcat-core/packet/transformer/base';
|
||||||
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
import OidbBase from '@/napcat-core/packet/transformer/oidb/oidbBase';
|
||||||
import crypto from 'node:crypto';
|
import crypto from 'node:crypto';
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user