diff --git a/.gitignore b/.gitignore index 3df3e7c7..42d6420b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ devconfig/* *.db checkVersion.sh bun.lockb +tests/run/ \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 983a8d0c..c35ec1f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "napcat", - "version": "4.9.21", + "version": "4.9.25", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "napcat", - "version": "4.9.21", + "version": "4.9.25", "dependencies": { "express": "^5.0.0", "silk-wasm": "^3.6.1", @@ -44,6 +44,7 @@ "express-rate-limit": "^7.5.0", "fast-xml-parser": "^4.3.6", "file-type": "^21.0.0", + "fs-extra": "^11.3.2", "json5": "^2.2.3", "multer": "^2.0.1", "napcat.protobuf": "^1.1.4", @@ -5222,9 +5223,9 @@ "license": "MIT" }, "node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 79f7aa16..21c55fbf 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "lint:webui": "cd napcat.webui && eslint src/**/*", "lint:fix:webui": "cd napcat.webui && eslint --fix src/**/*", "depend": "cd dist && npm install --omit=dev", - "dev:depend": "npm i && cd napcat.webui && npm i" + "dev:depend": "npm i && cd napcat.webui && npm i", + "test:winshell": "pwsh ./tests/nodeTest.ps1" }, "devDependencies": { "@babel/core": "^7.28.0", @@ -57,6 +58,7 @@ "express-rate-limit": "^7.5.0", "fast-xml-parser": "^4.3.6", "file-type": "^21.0.0", + "fs-extra": "^11.3.2", "json5": "^2.2.3", "multer": "^2.0.1", "napcat.protobuf": "^1.1.4", diff --git a/src/shell/base.ts b/src/shell/base.ts index 6abed9c5..f7b3f92b 100644 --- a/src/shell/base.ts +++ b/src/shell/base.ts @@ -24,7 +24,6 @@ import path from 'path'; import fs from 'fs'; import os from 'os'; import { LoginListItem, NodeIKernelLoginService } from '@/core/services'; -import { program } from 'commander'; import qrcode from '@/qrcode/lib/main'; import { NapCatOneBot11Adapter } from '@/onebot'; import { InitWebUi } from '@/webui'; @@ -322,7 +321,9 @@ export async function NCoreInitShell () { // 初始化 FFmpeg 服务 await FFmpegService.init(pathWrapper.binaryPath, logger); - await connectToNamedPipe(logger).catch(e => logger.logError('命名管道连接失败', e)); + if (process.env['NAPCAT_DISABLE_PIPE'] !== '1') { + await connectToNamedPipe(logger).catch(e => logger.logError('命名管道连接失败', e)); + } const basicInfoWrapper = new QQBasicInfoWrapper({ logger }); const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVersion()); const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用 @@ -362,9 +363,18 @@ export async function NCoreInitShell () { await initializeEngine(engine, basicInfoWrapper, dataPathGlobal, systemPlatform, systemVersion); await initializeLoginService(loginService, basicInfoWrapper, dataPathGlobal, systemVersion, hostname); handleProxy(session, logger); - program.option('-q, --qq [number]', 'QQ号').parse(process.argv); - const cmdOptions = program.opts(); - const quickLoginUin = cmdOptions['qq']; + + let quickLoginUin: string | undefined = undefined; + try { + const args = process.argv; + const qIndex = args.findIndex(arg => arg === '-q' || arg === '--qq'); + if (qIndex !== -1 && qIndex + 1 < args.length) { + quickLoginUin = args[qIndex + 1]; + } + } catch (error) { + logger.logWarn('解析命令行参数失败,无法使用快速登录功能', error); + } + const historyLoginList = (await loginService.getLoginList()).LocalLoginInfoList; const dataTimestape = new Date().getTime().toString(); diff --git a/tests/QQNT.dll b/tests/QQNT.dll new file mode 100644 index 00000000..12c861ba Binary files /dev/null and b/tests/QQNT.dll differ diff --git a/tests/loadNapCat.cjs b/tests/loadNapCat.cjs new file mode 100644 index 00000000..7ba9989b --- /dev/null +++ b/tests/loadNapCat.cjs @@ -0,0 +1,69 @@ +const fs = require('fs-extra'); +const path = require('path'); +const { pathToFileURL } = require('url'); + +const mainPath = process.argv[2]; +if (!mainPath) { + console.error('Please provide the base directory as the first argument.'); + process.exit(1); +} + +// 动态获取 versions 下唯一的版本文件夹,并拼接 resources/app 路径 +const versionsDir = path.join(mainPath, 'versions'); +console.log(`Looking for version folders in: ${versionsDir}`); +const versionFolders = fs.readdirSync(versionsDir).filter(f => fs.statSync(path.join(versionsDir, f)).isDirectory()); +if (versionFolders.length !== 1) { + console.error('versions 文件夹下必须且只能有一个版本目录'); + process.exit(1); +} + +const BASE_DIR = path.join(versionsDir, versionFolders[0], 'resources', 'app'); +const TARGET_DIR = path.join(__dirname, 'run'); +const QQNT_FILE = path.join(__dirname, 'QQNT.dll'); +const NAPCAT_MJS_PATH = path.join(__dirname, '..', 'dist', 'napcat.mjs'); + +const itemsToCopy = [ + 'avif_convert.dll', + 'broadcast_ipc.dll', + 'libglib-2.0-0.dll', + 'libgobject-2.0-0.dll', + 'libvips-42.dll', + 'ncnn.dll', + 'opencv.dll', + 'package.json', + 'QBar.dll', + 'wrapper.node' +]; + +async function copyAll () { + const qqntDllPath = path.join(TARGET_DIR, 'QQNT.dll'); + const configPath = path.join(TARGET_DIR, 'config.json'); + const allItemsExist = await fs.pathExists(qqntDllPath) + && await fs.pathExists(configPath) + && (await Promise.all(itemsToCopy.map(item => fs.pathExists(path.join(TARGET_DIR, item))))).every(exists => exists); + + if (!allItemsExist) { + console.log('Copying required files...'); + await fs.ensureDir(TARGET_DIR); + await fs.copy(QQNT_FILE, qqntDllPath, { overwrite: true }); + await fs.copy(path.join(versionsDir, 'config.json'), configPath, { overwrite: true }); + await Promise.all(itemsToCopy.map(async (item) => { + await fs.copy(path.join(BASE_DIR, item), path.join(TARGET_DIR, item), { overwrite: true }); + console.log(`Copied ${item}`); + })); + console.log('All files copied successfully.'); + } else { + console.log('Files already exist, skipping copy.'); + } + + process.env.NAPCAT_WRAPPER_PATH = path.join(TARGET_DIR, 'wrapper.node'); + process.env.NAPCAT_QQ_PACKAGE_INFO_PATH = path.join(TARGET_DIR, 'package.json'); + process.env.NAPCAT_QQ_VERSION_CONFIG_PATH = path.join(TARGET_DIR, 'config.json'); + process.env.NAPCAT_DISABLE_PIPE = '1'; + process.env.NAPCAT_WORKDIR = path.join(__dirname, 'run'); + + console.log('Loading NapCat module...'); + await import(pathToFileURL(NAPCAT_MJS_PATH).href); +} + +copyAll().catch(console.error); \ No newline at end of file diff --git a/tests/nodeTest.ps1 b/tests/nodeTest.ps1 new file mode 100644 index 00000000..e44f082e --- /dev/null +++ b/tests/nodeTest.ps1 @@ -0,0 +1,8 @@ +[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 +$regPath = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ' +$uninstall = (Get-ItemProperty -Path $regPath -Name UninstallString -ErrorAction Stop).UninstallString +$uninstall = $uninstall.Trim('"') +$qqPath = Split-Path $uninstall -Parent + +Write-Host "QQPath: $qqPath" +node.exe "tests/loadNapCat.cjs" "$qqPath"