Add configurable bypass options and UI

Introduce granular "bypass" configuration to control Napi2Native bypass features and expose it in the WebUI.

Key changes:
- Add bypass defaults to packages/napcat-core/external/napcat.json and BypassOptionsSchema in napcat-core helper config.
- Extend Napi2NativeLoader types: enableAllBypasses now accepts BypassOptions.
- Framework & Shell: load napcat.json (via json5), pass parsed bypass options to native loader, and log the applied config. Add json5 dependency.
- Shell: implement loadBypassConfig with a crash-recovery override (NAPCAT_BYPASS_DISABLE_LEVEL) and add master<->worker IPC (login-success) plus progressive bypass-disable strategy to mitigate repeated crashes before login.
- WebUI backend: add GET/Set endpoints for NapCat config (NapCatConfigRouter) with validation and JSON5-aware defaults.
- WebUI frontend: add BypassConfig page, types, and controller methods to get/set bypass config.
- Update package.json to include json5 and update pnpm lockfile; native binaries (.node / ffmpeg.dll) also updated.

This enables operators to tune bypass behavior per-installation and to have an in-UI control for toggling anti-detection features; it also adds progressive fallback behavior to help recover from crashes caused by bypasses.
This commit is contained in:
手瓜一十雪
2026-02-18 22:09:27 +08:00
parent 9998207346
commit b9f61cc0ee
20 changed files with 541 additions and 15 deletions

View File

@@ -2,7 +2,10 @@ import { NapCatPathWrapper } from 'napcat-common/src/path';
import { InitWebUi, WebUiConfig, webUiRuntimePort } from 'napcat-webui-backend/index';
import { NapCatAdapterManager } from 'napcat-adapter';
import { NativePacketHandler } from 'napcat-core/packet/handler/client';
import { Napi2NativeLoader } from 'napcat-core/packet/handler/napi2nativeLoader';
import { Napi2NativeLoader, BypassOptions } from 'napcat-core/packet/handler/napi2nativeLoader';
import path from 'path';
import fs from 'fs';
import json5 from 'json5';
import { FFmpegService } from 'napcat-core/helper/ffmpeg/ffmpeg';
import { logSubscription, LogWrapper } from 'napcat-core/helper/log';
import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info';
@@ -44,10 +47,29 @@ export async function NCoreInitFramework (
const napi2nativeLoader = new Napi2NativeLoader({ logger }); // 初始化 Napi2NativeLoader 用于后续使用
//console.log('[NapCat] [Napi2NativeLoader]', napi2nativeLoader.nativeExports.enableAllBypasses?.());
if (process.env['NAPCAT_DISABLE_BYPASS'] !== '1') {
const bypassEnabled = napi2nativeLoader.nativeExports.enableAllBypasses?.();
if (bypassEnabled) {
logger.log('[NapCat] Napi2NativeLoader: 已启用Bypass');
// 读取 napcat.json 配置
let bypassOptions: BypassOptions = {
hook: false,
module: false,
window: false,
js: false,
container: false,
maps: false,
};
try {
const configFile = path.join(pathWrapper.configPath, 'napcat.json');
if (fs.existsSync(configFile)) {
const content = fs.readFileSync(configFile, 'utf-8');
const config = json5.parse(content);
if (config.bypass && typeof config.bypass === 'object') {
bypassOptions = { ...bypassOptions, ...config.bypass };
}
}
} catch (e) {
logger.logWarn('[NapCat] 读取 napcat.json bypass 配置失败,已全部禁用:', e);
}
const bypassEnabled = napi2nativeLoader.nativeExports.enableAllBypasses?.(bypassOptions);
logger.log('[NapCat] Napi2NativeLoader: Framework模式Bypass配置:', bypassOptions);
} else {
logger.log('[NapCat] Napi2NativeLoader: Bypass已通过环境变量禁用');
}

View File

@@ -22,7 +22,8 @@
"napcat-adapter": "workspace:*",
"napcat-webui-backend": "workspace:*",
"napcat-vite": "workspace:*",
"napcat-qrcode": "workspace:*"
"napcat-qrcode": "workspace:*",
"json5": "^3.2.2"
},
"devDependencies": {
"@types/node": "^22.0.1"