mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-03-01 00:00:26 +00:00
Refactor bypass defaults and crash handling
Set bypass defaults to disabled and simplify loading: napcat.json default bypass flags changed to false and code now reads bypass options without merging a prior "all enabled" default. Removed the progressive bypass-disable logic and related environment variable usage, and added a log when Napi2NativeLoader enables bypasses. Web UI/backend adjustments: default NapCat config is now generated from the AJV schema; the bypass settings UI defaults to false, adds an o3HookMode toggle, and submits o3HookMode as 0/1. UX fixes: extension tabs made horizontally scrollable with fixed tab sizing, and plugin uninstall flow updated to a single confirmation dialog with an optional checkbox to remove plugin config. Overall changes aim to use safer defaults, simplify crash/restart behavior, and improve configuration and UI clarity.
This commit is contained in:
@@ -49,47 +49,18 @@ import { connectToNamedPipe } from './pipe';
|
||||
* 3: 强制禁用全部 bypass
|
||||
*/
|
||||
function loadBypassConfig (configPath: string, logger: LogWrapper): BypassOptions {
|
||||
const defaultOptions: BypassOptions = {
|
||||
hook: true,
|
||||
window: true,
|
||||
module: true,
|
||||
process: true,
|
||||
container: true,
|
||||
js: true,
|
||||
};
|
||||
|
||||
let options = { ...defaultOptions };
|
||||
let options: BypassOptions = {};
|
||||
try {
|
||||
const configFile = path.join(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') {
|
||||
options = { ...defaultOptions, ...config.bypass };
|
||||
options = { ...config.bypass };
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.logWarn('[NapCat] 读取 bypass 配置失败,使用默认值:', e);
|
||||
}
|
||||
// 根据分步禁用级别覆盖配置
|
||||
const disableLevel = parseInt(process.env['NAPCAT_BYPASS_DISABLE_LEVEL'] || '0', 10);
|
||||
if (disableLevel > 0) {
|
||||
const levelDescriptions = ['全部启用', '禁用 hook', '禁用 hook + module', '全部禁用 bypass'];
|
||||
logger.logWarn(`[NapCat] 崩溃恢复:当前 bypass 禁用级别 ${disableLevel} (${levelDescriptions[disableLevel] ?? '未知'})`);
|
||||
if (disableLevel >= 1) {
|
||||
options.hook = false;
|
||||
}
|
||||
if (disableLevel >= 2) {
|
||||
options.module = false;
|
||||
}
|
||||
if (disableLevel >= 3) {
|
||||
options.hook = false;
|
||||
options.window = false;
|
||||
options.module = false;
|
||||
options.process = false;
|
||||
options.container = false;
|
||||
options.js = false;
|
||||
}
|
||||
logger.logWarn('[NapCat] 读取 bypass 配置失败:', e);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
@@ -65,15 +65,6 @@ const recentCrashTimestamps: number[] = [];
|
||||
const CRASH_TIME_WINDOW = 10000; // 10秒时间窗口
|
||||
const MAX_CRASHES_IN_WINDOW = 3; // 最大崩溃次数
|
||||
|
||||
// 分步禁用策略:记录当前禁用级别 (0-3)
|
||||
// 0: 全部启用
|
||||
// 1: 禁用 hook
|
||||
// 2: 禁用 hook + module
|
||||
// 3: 全部禁用
|
||||
let bypassDisableLevel = 0;
|
||||
|
||||
// 是否已登录成功(登录后不再使用分步禁用策略)
|
||||
let isLoggedIn = false;
|
||||
|
||||
/**
|
||||
* 获取进程类型名称(用于日志)
|
||||
@@ -164,8 +155,6 @@ async function cleanupOrphanedProcesses (excludePids: number[]): Promise<void> {
|
||||
*/
|
||||
export async function restartWorker (secretKey?: string, port?: number): Promise<void> {
|
||||
isRestarting = true;
|
||||
isLoggedIn = false;
|
||||
bypassDisableLevel = 0;
|
||||
|
||||
if (!currentWorker) {
|
||||
logger.logWarn('[NapCat] [Process] 没有运行中的Worker进程');
|
||||
@@ -258,7 +247,6 @@ async function startWorker (passQuickLogin: boolean = true, secretKey?: string,
|
||||
NAPCAT_WORKER_PROCESS: '1',
|
||||
...(secretKey ? { NAPCAT_WEBUI_JWT_SECRET_KEY: secretKey } : {}),
|
||||
...(preferredPort ? { NAPCAT_WEBUI_PREFERRED_PORT: String(preferredPort) } : {}),
|
||||
...(bypassDisableLevel > 0 ? { NAPCAT_BYPASS_DISABLE_LEVEL: String(bypassDisableLevel) } : {}),
|
||||
},
|
||||
stdio: isElectron ? 'pipe' : ['inherit', 'pipe', 'pipe', 'ipc'],
|
||||
});
|
||||
@@ -289,7 +277,6 @@ async function startWorker (passQuickLogin: boolean = true, secretKey?: string,
|
||||
logger.logError(`[NapCat] [${processType}] 重启Worker进程失败:`, e);
|
||||
});
|
||||
} else if (message.type === 'login-success') {
|
||||
isLoggedIn = true;
|
||||
logger.log(`[NapCat] [${processType}] Worker进程已登录成功,切换到正常重试策略`);
|
||||
}
|
||||
}
|
||||
@@ -313,34 +300,13 @@ async function startWorker (passQuickLogin: boolean = true, secretKey?: string,
|
||||
// 记录本次崩溃
|
||||
recentCrashTimestamps.push(now);
|
||||
|
||||
// 登录前:使用分步禁用策略
|
||||
if (!isLoggedIn) {
|
||||
// 每次崩溃提升禁用级别
|
||||
bypassDisableLevel = Math.min(bypassDisableLevel + 1, 3);
|
||||
|
||||
const levelDescriptions = [
|
||||
'全部启用',
|
||||
'禁用 hook',
|
||||
'禁用 hook + module',
|
||||
'全部禁用 bypass'
|
||||
];
|
||||
|
||||
if (bypassDisableLevel >= 3 && recentCrashTimestamps.length >= MAX_CRASHES_IN_WINDOW) {
|
||||
logger.logError(`[NapCat] [${processType}] Worker进程在 ${CRASH_TIME_WINDOW / 1000} 秒内异常退出 ${MAX_CRASHES_IN_WINDOW} 次,已尝试全部禁用策略,主进程退出`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
logger.logWarn(`[NapCat] [${processType}] Worker进程意外退出 (${recentCrashTimestamps.length}/${MAX_CRASHES_IN_WINDOW}),切换到禁用级别 ${bypassDisableLevel}: ${levelDescriptions[bypassDisableLevel]},正在尝试重新拉起...`);
|
||||
} else {
|
||||
// 登录后:使用正常重试策略
|
||||
if (recentCrashTimestamps.length >= MAX_CRASHES_IN_WINDOW) {
|
||||
logger.logError(`[NapCat] [${processType}] Worker进程在 ${CRASH_TIME_WINDOW / 1000} 秒内异常退出 ${MAX_CRASHES_IN_WINDOW} 次,主进程退出`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
logger.logWarn(`[NapCat] [${processType}] Worker进程意外退出 (${recentCrashTimestamps.length}/${MAX_CRASHES_IN_WINDOW}),正在尝试重新拉起...`);
|
||||
if (recentCrashTimestamps.length >= MAX_CRASHES_IN_WINDOW) {
|
||||
logger.logError(`[NapCat] [${processType}] Worker进程在 ${CRASH_TIME_WINDOW / 1000} 秒内异常退出 ${MAX_CRASHES_IN_WINDOW} 次,主进程退出`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
logger.logWarn(`[NapCat] [${processType}] Worker进程意外退出 (${recentCrashTimestamps.length}/${MAX_CRASHES_IN_WINDOW}),正在尝试重新拉起...`);
|
||||
|
||||
startWorker(true).catch(e => {
|
||||
logger.logError(`[NapCat] [${processType}] 重新拉起Worker进程失败:`, e);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user