Pr enhance (#1176)

* fix

* Refactor PacketApi status checks and fix typos

Replaced all usages of PacketApi.available with PacketApi.packetStatus for more accurate status checking. Fixed a typo in getFullQQVesion to getFullQQVersion. Updated plugin_onmessage to fetch and parse messages for a user. These changes improve reliability and consistency in API status handling.

* Fix typo in getFullQQVersion method name

Corrected the method name from getFullQQVesion to getFullQQVersion in multiple locations to ensure consistency and prevent potential runtime errors.

* Remove performance CLI and demo, fix typos, update proto

Deleted the performance CLI and demo files. Fixed a typo in getFullQQVesion to getFullQQVersion across multiple files. Changed the 'time' field type from UINT32 to UINT64 in Oidb.0x9067_202 proto. Commented out performanceMonitorPlugin in vite.config.ts. Removed an unimplemented log statement in NodeIKernelBuddyListener.

* Comment out default plugin adapter registration

The default registration of OB11PluginAdapter in NapCatOneBot11Adapter was commented out, likely to prevent automatic plugin loading or to allow for more flexible plugin management. Also, removed an unnecessary blank line in the plugin_onmessage function.

* fix

* Add shell-analysis mode with performance monitoring

Introduces a new .env.shell-analysis file and a dev:shell-analysis npm script for building in shell-analysis mode. Updates vite.config.ts to support the new mode, enabling the performance monitor plugin with an updated exclude list. Also extends the plugin's exclude patterns to filter out 'packet' files.

* Delete performance-api.ts

* Add commented export for performance-monitor

Added a commented-out export statement for '@/common/performance-monitor' in napcat.ts, possibly for future use or reference. No functional changes to the file.
This commit is contained in:
手瓜一十雪
2025-08-06 20:37:45 +08:00
committed by GitHub
parent beb189bd49
commit 11308d9e01
19 changed files with 769 additions and 120 deletions

View File

@@ -0,0 +1,316 @@
/**
* 性能监控器 - 用于统计函数调用次数、耗时等信息
*/
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);
});
}

View File

@@ -42,7 +42,7 @@ export class QQBasicInfoWrapper {
return this.isQuickUpdate ? this.QQVersionConfig?.buildId : this.QQPackageInfo?.buildVersion;
}
getFullQQVesion() {
getFullQQVersion() {
const version = this.isQuickUpdate ? this.QQVersionConfig?.curVersion : this.QQPackageInfo?.version;
if (!version) throw new Error('QQ版本获取失败');
return version;
@@ -57,9 +57,9 @@ export class QQBasicInfoWrapper {
//此方法不要直接使用
getQUAFallback() {
const platformMapping: Partial<Record<NodeJS.Platform, string>> = {
win32: `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`,
darwin: `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`,
linux: `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`,
win32: `V1_WIN_${this.getFullQQVersion()}_${this.getQQBuildStr()}_GW_B`,
darwin: `V1_MAC_${this.getFullQQVersion()}_${this.getQQBuildStr()}_GW_B`,
linux: `V1_LNX_${this.getFullQQVersion()}_${this.getQQBuildStr()}_GW_B`,
};
return platformMapping[systemPlatform] ?? (platformMapping.win32)!;
}
@@ -76,7 +76,7 @@ export class QQBasicInfoWrapper {
getAppidV2(): { appid: string; qua: string } {
// 通过已有表 性能好
const appidTbale = AppidTable as unknown as QQAppidTableType;
const fullVersion = this.getFullQQVesion();
const fullVersion = this.getFullQQVersion();
if (fullVersion) {
const data = appidTbale[fullVersion];
if (data) {

View File

@@ -65,7 +65,7 @@ export class NTQQFileApi {
}
async getFileUrl(chatType: ChatType, peer: string, fileUUID?: string, file10MMd5?: string | undefined) {
if (this.core.apis.PacketApi.available) {
if (this.core.apis.PacketApi.packetStatus) {
try {
if (chatType === ChatType.KCHATTYPEGROUP && fileUUID) {
return this.core.apis.PacketApi.pkt.operation.GetGroupFileUrl(+peer, fileUUID);
@@ -80,7 +80,7 @@ export class NTQQFileApi {
}
async getPttUrl(peer: string, fileUUID?: string) {
if (this.core.apis.PacketApi.available && fileUUID) {
if (this.core.apis.PacketApi.packetStatus && fileUUID) {
let appid = new NapProtoMsg(FileId).decode(Buffer.from(fileUUID.replaceAll('-', '+').replaceAll('_', '/'), 'base64')).appid;
try {
if (appid && appid === 1403) {
@@ -108,7 +108,7 @@ export class NTQQFileApi {
}
async getVideoUrlPacket(peer: string, fileUUID?: string) {
if (this.core.apis.PacketApi.available && fileUUID) {
if (this.core.apis.PacketApi.packetStatus && fileUUID) {
let appid = new NapProtoMsg(FileId).decode(Buffer.from(fileUUID.replaceAll('-', '+').replaceAll('_', '/'), 'base64')).appid;
try {
if (appid && appid === 1415) {
@@ -502,7 +502,7 @@ export class NTQQFileApi {
};
try {
if (this.core.apis.PacketApi.available) {
if (this.core.apis.PacketApi.packetStatus) {
const rkey_expired_private = !this.packetRkey || (this.packetRkey[0] && this.packetRkey[0].time + Number(this.packetRkey[0].ttl) < Date.now() / 1000);
const rkey_expired_group = !this.packetRkey || (this.packetRkey[0] && this.packetRkey[0].time + Number(this.packetRkey[0].ttl) < Date.now() / 1000);
if (rkey_expired_private || rkey_expired_group) {

View File

@@ -142,7 +142,6 @@ export class NTQQMsgApi {
}
async queryFirstMsgBySender(peer: Peer, SendersUid: string[]) {
console.log(peer, SendersUid);
return await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
chatInfo: peer,
filterMsgType: [],

View File

@@ -21,20 +21,26 @@ export class NTQQPacketApi {
qqVersion: string | undefined;
pkt!: PacketClientSession;
errStack: string[] = [];
packetStatus: boolean = false;
constructor(context: InstanceContext, core: NapCatCore) {
this.context = context;
this.core = core;
this.logger = core.context.logger;
}
async initApi() {
await this.InitSendPacket(this.context.basicInfoWrapper.getFullQQVesion())
.then()
this.packetStatus = (await this.InitSendPacket(this.context.basicInfoWrapper.getFullQQVersion())
.then((result) => {
return result;
})
.catch((err) => {
this.logger.logError(err);
this.errStack.push(err);
});
return false;
})) && this.pkt?.available;
}
get available(): boolean {
return this.pkt?.available ?? false;
}
@@ -61,6 +67,12 @@ export class NTQQPacketApi {
}
this.pkt = new PacketClientSession(this.core);
await this.pkt.init(process.pid, table.recv, table.send);
try {
await this.pkt.operation.FetchRkey();
} catch (error) {
this.logger.logError('测试Packet状态异常', error);
return false;
}
return true;
}
}

View File

@@ -40,7 +40,6 @@ export class NodeIKernelBuddyListener {
}
onDelBatchBuddyInfos(_arg: unknown): any {
console.log('onDelBatchBuddyInfos not implemented', ...arguments);
}
onDoubtBuddyReqChange(_arg:

View File

@@ -37,7 +37,7 @@ export async function NCoreInitFramework(
const pathWrapper = new NapCatPathWrapper();
const logger = new LogWrapper(pathWrapper.logsPath);
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVesion());
const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVersion());
if (!process.env['NAPCAT_DISABLE_FFMPEG_DOWNLOAD']) {
downloadFFmpegIfNotExists(logger).then(({ path, reset }) => {
if (reset && path) {

View File

@@ -130,7 +130,7 @@ export class SendMsgBase extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
);
if (getSpecialMsgNum(payload, OB11MessageDataType.node)) {
const packetMode = this.core.apis.PacketApi.available;
const packetMode = this.core.apis.PacketApi.packetStatus;
let returnMsgAndResId: { message: RawMessage | null, res_id?: string } | null;
try {
returnMsgAndResId = packetMode

View File

@@ -4,7 +4,7 @@ import { ActionName, BaseCheckResult } from '@/onebot/action/router';
export abstract class GetPacketStatusDepends<PT, RT> extends OneBotAction<PT, RT> {
protected override async check(payload: PT): Promise<BaseCheckResult>{
if (!this.core.apis.PacketApi.available) {
if (!this.core.apis.PacketApi.packetStatus) {
return {
valid: false,
message: 'packetBackend不可用请参照文档 https://napneko.github.io/config/advanced 和启动日志检查packetBackend状态或进行配置' +

View File

@@ -147,7 +147,7 @@ export class OneBotMsgApi {
};
FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileUuid);
FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, element.fileUuid, element.fileName);
if (this.core.apis.PacketApi.available) {
if (this.core.apis.PacketApi.packetStatus) {
let url;
try {
url = await this.core.apis.FileApi.getFileUrl(msg.chatType, msg.peerUid, element.fileUuid, element.file10MMd5)
@@ -391,7 +391,7 @@ export class OneBotMsgApi {
//开始兜底
if (!videoDownUrl) {
if (this.core.apis.PacketApi.available) {
if (this.core.apis.PacketApi.packetStatus) {
try {
videoDownUrl = await this.core.apis.FileApi.getVideoUrlPacket(msg.peerUid, element.fileUuid);
} catch (e) {
@@ -422,7 +422,7 @@ export class OneBotMsgApi {
};
const fileCode = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, '', element.fileName);
let pttUrl = '';
if (this.core.apis.PacketApi.available) {
if (this.core.apis.PacketApi.packetStatus) {
try {
pttUrl = await this.core.apis.FileApi.getPttUrl(msg.peerUid, element.fileUuid);
} catch (e) {

View File

@@ -50,6 +50,7 @@ import {
import { OB11Message } from './types';
import { IOB11NetworkAdapter } from '@/onebot/network/adapter';
import { OB11HttpSSEServerAdapter } from './network/http-server-sse';
import { OB11PluginAdapter } from './network/plugin';
//OneBot实现类
export class NapCatOneBot11Adapter {
@@ -169,7 +170,7 @@ export class NapCatOneBot11Adapter {
this.initBuddyListener();
this.initGroupListener();
WebUiDataRuntime.setQQVersion(this.core.context.basicInfoWrapper.getFullQQVesion());
WebUiDataRuntime.setQQVersion(this.core.context.basicInfoWrapper.getFullQQVersion());
WebUiDataRuntime.setQQLoginInfo(selfInfo);
WebUiDataRuntime.setQQLoginStatus(true);
WebUiDataRuntime.setOnOB11ConfigChanged(async (newConfig) => {

View File

@@ -1,11 +1,16 @@
import { NapCatOneBot11Adapter, OB11Message } from '@/onebot';
import { NapCatCore } from '@/core';
import { ChatType, NapCatCore } from '@/core';
import { ActionMap } from '@/onebot/action';
import { OB11PluginAdapter } from '@/onebot/network/plugin';
export const plugin_onmessage = async (adapter: string, _core: NapCatCore, _obCtx: NapCatOneBot11Adapter, message: OB11Message, action: ActionMap, instance: OB11PluginAdapter) => {
if (message.raw_message === 'ping') {
const ret = await action.get('send_group_msg')?.handle({ group_id: String(message.group_id), message: 'pong' }, adapter, instance.config);
console.log(ret);
const uid = await _core.apis.UserApi.getUidByUinV2(message.sender.user_id.toString());
const msgs = (await _core.apis.MsgApi.queryFirstMsgBySender({
peerUid: message.group_id ? String(message.group_id) : String(uid),
chatType: ChatType.KCHATTYPEGROUP,
}, [uid])).msgList;
console.log('parse message ', message.sender.user_id, msgs.length);
for (const msg of msgs) {
await _obCtx.apis.MsgApi.parseMessageV2(msg)
}
};
}

View File

@@ -80,7 +80,7 @@ async function initializeEngine(
base_path_prefix: '',
platform_type: systemPlatform,
app_type: 4,
app_version: basicInfoWrapper.getFullQQVesion(),
app_version: basicInfoWrapper.getFullQQVersion(),
os_version: systemVersion,
use_xlog: false,
qua: basicInfoWrapper.QQVersionQua ?? '',
@@ -105,7 +105,7 @@ async function initializeLoginService(
appid: basicInfoWrapper.QQVersionAppid ?? '',
platVer: systemVersion,
commonPath: dataPathGlobal,
clientVer: basicInfoWrapper.getFullQQVesion(),
clientVer: basicInfoWrapper.getFullQQVersion(),
hostName: hostname,
});
}
@@ -324,7 +324,7 @@ export async function NCoreInitShell() {
});
}
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVesion());
const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVersion());
const o3Service = wrapper.NodeIO3MiscService.get();
o3Service.addO3MiscListener(new NodeIO3MiscListener());
@@ -363,7 +363,7 @@ export async function NCoreInitShell() {
const sessionConfig = await genSessionConfig(
guid,
basicInfoWrapper.QQVersionAppid,
basicInfoWrapper.getFullQQVesion(),
basicInfoWrapper.getFullQQVersion(),
selfInfo.uin,
selfInfo.uid,
dataPath,

View File

@@ -1,2 +1,4 @@
//export * from '@/common/performance-monitor';
import { NCoreInitShell } from './base';
NCoreInitShell();