Files
NapCatQQ/packages/napcat-framework/napcat.ts
手瓜一十雪 2f8569f30c Add Registry20 GUID management and DPAPI support
Introduce tools and UI to read, write, backup and restore QQ Registry20 GUIDs using Windows DPAPI. Adds a Python CLI (guid_tool.py) for local Registry20 operations and a new TypeScript package napcat-dpapi with native bindings for DPAPI. Implements Registry20Utils in the webui-backend to protect/unprotect Registry20, plus backup/restore/delete helpers. Exposes new backend API handlers and routes (get/set GUID, backups, restore, reset, restart) and integrates frontend GUIDManager component and qq_manager controller methods. Propagates QQ data path via WebUiDataRuntime (setter/getter) and wires it up in framework/shell; updates Vite alias and package.json to include the new dpapi workspace. Includes native addon binaries for win32 x64/arm64 and basic tsconfig/readme/license for the new package.
2026-02-12 17:08:24 +08:00

118 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 { FFmpegService } from 'napcat-core/helper/ffmpeg/ffmpeg';
import { logSubscription, LogWrapper } from 'napcat-core/helper/log';
import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info';
import { InstanceContext, loadQQWrapper, NapCatCore, NapCatCoreWorkingEnv, NodeIKernelLoginListener, NodeIKernelLoginService, NodeIQQNTWrapperSession, SelfInfo, WrapperNodeApi } from '@/napcat-core';
import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler';
import { statusHelperSubscription } from '@/napcat-core/helper/status';
import { applyPendingUpdates } from '@/napcat-webui-backend/src/api/UpdateNapCat';
import { WebUiDataRuntime } from '@/napcat-webui-backend/src/helper/Data';
// Framework ES入口文件
export async function getWebUiUrl () {
const WebUiConfigData = (await WebUiConfig.GetWebUIConfig());
return 'http://127.0.0.1:' + webUiRuntimePort + '/webui/?token=' + encodeURIComponent(WebUiConfigData.token);
}
export async function NCoreInitFramework (
session: NodeIQQNTWrapperSession,
loginService: NodeIKernelLoginService,
registerInitCallback: (callback: () => void) => void
) {
// 在进入本层前是否登录未进行判断
console.log('NapCat Framework App Loading...');
process.on('uncaughtException', (err) => {
console.log('[NapCat] [Error] Unhandled Exception:', err.message);
});
process.on('unhandledRejection', (reason) => {
console.log('[NapCat] [Error] unhandledRejection:', reason);
});
const pathWrapper = new NapCatPathWrapper();
const logger = new LogWrapper(pathWrapper.logsPath);
await applyPendingUpdates(pathWrapper, logger);
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.QQMainPath, basicInfoWrapper.getFullQQVersion());
const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用
// nativePacketHandler.onAll((packet) => {
// console.log('[Packet]', packet.uin, packet.cmd, packet.hex_data);
// });
await nativePacketHandler.init(basicInfoWrapper.getFullQQVersion());
// 在 init 之后注册监听器
// 初始化 FFmpeg 服务
await FFmpegService.init(pathWrapper.binaryPath, logger);
// 直到登录成功后,执行下一步
// const selfInfo = {
// uid: 'u_FUSS0_x06S_9Tf4na_WpUg',
// uin: '3684714082',
// nick: '',
// online: true
// }
const selfInfo = await new Promise<SelfInfo>((resolve) => {
const loginListener = new NodeIKernelLoginListener();
loginListener.onQRCodeLoginSucceed = async (loginResult) => {
await new Promise<void>(resolve => {
registerInitCallback(() => resolve());
});
resolve({
uid: loginResult.uid,
uin: loginResult.uin,
nick: '', // 获取不到
online: true,
});
};
loginService.addKernelLoginListener(proxiedListenerOf(loginListener, logger));
});
// 过早进入会导致addKernelMsgListener等Listener添加失败
// await sleep(2500);
// 初始化 NapCatFramework
const loaderObject = new NapCatFramework(wrapper, session, logger, selfInfo, basicInfoWrapper, pathWrapper, nativePacketHandler);
await loaderObject.core.initCore();
// 启动WebUi
WebUiDataRuntime.setWorkingEnv(NapCatCoreWorkingEnv.Framework);
WebUiDataRuntime.setQQDataPath(loaderObject.core.dataPath);
InitWebUi(logger, pathWrapper, logSubscription, statusHelperSubscription).then().catch(e => logger.logError(e));
// 使用 NapCatAdapterManager 统一管理协议适配器
const adapterManager = new NapCatAdapterManager(loaderObject.core, loaderObject.context, pathWrapper);
await adapterManager.initAdapters();
// 注册 OneBot 适配器到 WebUiDataRuntime供调试功能使用
const oneBotAdapter = adapterManager.getOneBotAdapter();
if (oneBotAdapter) {
WebUiDataRuntime.setOneBotContext(oneBotAdapter);
}
}
export class NapCatFramework {
public core: NapCatCore;
context: InstanceContext;
constructor (
wrapper: WrapperNodeApi,
session: NodeIQQNTWrapperSession,
logger: LogWrapper,
selfInfo: SelfInfo,
basicInfoWrapper: QQBasicInfoWrapper,
pathWrapper: NapCatPathWrapper,
packetHandler: NativePacketHandler
) {
this.context = {
packetHandler,
workingEnv: NapCatCoreWorkingEnv.Framework,
wrapper,
session,
logger,
basicInfoWrapper,
pathWrapper,
};
this.core = new NapCatCore(this.context, selfInfo);
}
}