mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-02-12 16:00:27 +00:00
Compare commits
29 Commits
copilot/fi
...
v4.9.41
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1259dcea5b | ||
|
|
b4900066b3 | ||
|
|
28acd94cbd | ||
|
|
7aedacb27f | ||
|
|
c9b45ec1a2 | ||
|
|
54cacc30e4 | ||
|
|
9b26fc99d3 | ||
|
|
204846b404 | ||
|
|
3d654791b9 | ||
|
|
63f42f1592 | ||
|
|
0ab0b939da | ||
|
|
522a123f9a | ||
|
|
ec9f8d6e12 | ||
|
|
3c750c75a9 | ||
|
|
5b2b1f499b | ||
|
|
531ffcd55d | ||
|
|
068e4d8bb5 | ||
|
|
5dc33e78ad | ||
|
|
d76a2170a0 | ||
|
|
ec2af3120c | ||
|
|
8de49a3109 | ||
|
|
dbb5a0022e | ||
|
|
cb8c8d6b57 | ||
|
|
93c140ed4e | ||
|
|
457b072f0e | ||
|
|
1869493473 | ||
|
|
f33c66ce15 | ||
|
|
e8d6f86458 | ||
|
|
a000ffdf0d |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -14,4 +14,6 @@ devconfig/*
|
|||||||
*.db
|
*.db
|
||||||
checkVersion.sh
|
checkVersion.sh
|
||||||
bun.lockb
|
bun.lockb
|
||||||
tests/run/
|
tests/run/
|
||||||
|
guild1.db-wal
|
||||||
|
guild1.db-shm
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"name": "NapCatQQ",
|
"name": "NapCatQQ",
|
||||||
"slug": "NapCat.Framework",
|
"slug": "NapCat.Framework",
|
||||||
"description": "高性能的 OneBot 11 协议实现",
|
"description": "高性能的 OneBot 11 协议实现",
|
||||||
"version": "4.9.27",
|
"version": "4.9.40",
|
||||||
"icon": "./logo.png",
|
"icon": "./logo.png",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
|||||||
2
napcat.webui/public/robots.txt
Normal file
2
napcat.webui/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
User-agent: *
|
||||||
|
Disallow: /
|
||||||
30
napiloader/napiLoader-debug.bat
Normal file
30
napiloader/napiLoader-debug.bat
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001
|
||||||
|
set NAPCAT_INJECT_PATH=%cd%\napiloader.dll
|
||||||
|
set NAPCAT_LAUNCHER_PATH=%cd%\napimain.exe
|
||||||
|
set NAPCAT_MAIN_PATH=%cd%\nativeLoader.cjs
|
||||||
|
set NAPCAT_DEBUG_CONSOLE=1
|
||||||
|
:loop_read
|
||||||
|
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
|
||||||
|
set "RetString=%%~b"
|
||||||
|
goto :napcat_boot
|
||||||
|
)
|
||||||
|
|
||||||
|
:napcat_boot
|
||||||
|
for %%a in ("%RetString%") do (
|
||||||
|
set "pathWithoutUninstall=%%~dpa"
|
||||||
|
)
|
||||||
|
|
||||||
|
set "QQPath=%pathWithoutUninstall%QQ.exe"
|
||||||
|
|
||||||
|
if not exist "%QQpath%" (
|
||||||
|
echo provided QQ path is invalid
|
||||||
|
pause
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/%
|
||||||
|
|
||||||
|
"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" "%NAPCAT_MAIN_PATH%"
|
||||||
|
|
||||||
|
pause
|
||||||
27
napiloader/napiLoader.bat
Normal file
27
napiloader/napiLoader.bat
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001
|
||||||
|
set NAPCAT_INJECT_PATH=%cd%\napiloader.dll
|
||||||
|
set NAPCAT_LAUNCHER_PATH=%cd%\napimain.exe
|
||||||
|
set NAPCAT_MAIN_PATH=%cd%\nativeLoader.cjs
|
||||||
|
:loop_read
|
||||||
|
for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do (
|
||||||
|
set "RetString=%%~b"
|
||||||
|
goto :napcat_boot
|
||||||
|
)
|
||||||
|
|
||||||
|
:napcat_boot
|
||||||
|
for %%a in ("%RetString%") do (
|
||||||
|
set "pathWithoutUninstall=%%~dpa"
|
||||||
|
)
|
||||||
|
|
||||||
|
set "QQPath=%pathWithoutUninstall%QQ.exe"
|
||||||
|
|
||||||
|
if not exist "%QQpath%" (
|
||||||
|
echo provided QQ path is invalid
|
||||||
|
pause
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
|
set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/%
|
||||||
|
|
||||||
|
start "" "%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" "%NAPCAT_MAIN_PATH%"
|
||||||
BIN
napiloader/napiloader.dll
Normal file
BIN
napiloader/napiloader.dll
Normal file
Binary file not shown.
BIN
napiloader/napimain.exe
Normal file
BIN
napiloader/napimain.exe
Normal file
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
"name": "napcat",
|
"name": "napcat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "4.9.27",
|
"version": "4.9.40",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:universal": "npm run build:webui && npm run dev:universal || exit 1",
|
"build:universal": "npm run build:webui && npm run dev:universal || exit 1",
|
||||||
"build:framework": "npm run build:webui && npm run dev:framework || exit 1",
|
"build:framework": "npm run build:webui && npm run dev:framework || exit 1",
|
||||||
|
|||||||
@@ -66,13 +66,15 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
|
|||||||
*/
|
*/
|
||||||
async getVideoInfo (videoPath: string): Promise<VideoInfoResult> {
|
async getVideoInfo (videoPath: string): Promise<VideoInfoResult> {
|
||||||
const addon = this.ensureAddon();
|
const addon = this.ensureAddon();
|
||||||
const info = await addon.getVideoInfo(videoPath, 'bmp24');
|
const info = await addon.getVideoInfo(videoPath);
|
||||||
|
|
||||||
|
let format = info.format.includes(',') ? info.format.split(',')[0] ?? info.format : info.format;
|
||||||
|
console.log('[FFmpegAddonAdapter] Detected format:', format);
|
||||||
return {
|
return {
|
||||||
width: info.width,
|
width: info.width,
|
||||||
height: info.height,
|
height: info.height,
|
||||||
duration: info.duration,
|
duration: info.duration,
|
||||||
format: info.format,
|
format: format,
|
||||||
thumbnail: info.image,
|
thumbnail: info.image,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -88,7 +90,7 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
|
|||||||
/**
|
/**
|
||||||
* 转换为 PCM
|
* 转换为 PCM
|
||||||
*/
|
*/
|
||||||
async convertToPCM (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number }> {
|
async convertToPCM (filePath: string, pcmPath: string): Promise<{ result: boolean, sampleRate: number; }> {
|
||||||
const addon = this.ensureAddon();
|
const addon = this.ensureAddon();
|
||||||
const result = await addon.decodeAudioToPCM(filePath, pcmPath, 24000);
|
const result = await addon.decodeAudioToPCM(filePath, pcmPath, 24000);
|
||||||
|
|
||||||
@@ -100,13 +102,8 @@ export class FFmpegAddonAdapter implements IFFmpegAdapter {
|
|||||||
*/
|
*/
|
||||||
async convertFile (inputFile: string, outputFile: string, format: string): Promise<void> {
|
async convertFile (inputFile: string, outputFile: string, format: string): Promise<void> {
|
||||||
const addon = this.ensureAddon();
|
const addon = this.ensureAddon();
|
||||||
|
console.log('[FFmpegAddonAdapter] Converting file:', inputFile, 'to', outputFile, 'as', format);
|
||||||
if (format === 'silk' || format === 'ntsilk') {
|
await addon.decodeAudioToFmt(inputFile, outputFile, format);
|
||||||
// 使用 Addon 的 NTSILK 转换
|
|
||||||
await addon.convertToNTSilkTct(inputFile, outputFile);
|
|
||||||
} else {
|
|
||||||
throw new Error(`Format '${format}' is not supported by FFmpeg Addon`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,23 +49,25 @@ export interface AudioPCMResult {
|
|||||||
* FFmpeg interface providing all audio/video processing methods
|
* FFmpeg interface providing all audio/video processing methods
|
||||||
*/
|
*/
|
||||||
export interface FFmpeg {
|
export interface FFmpeg {
|
||||||
|
convertFile (inputFile: string, outputFile: string, format: string): Promise<{ success: boolean; }>;
|
||||||
/**
|
/**
|
||||||
* Get video information including resolution, duration, format, codec and first frame thumbnail
|
* Get video information including resolution, duration, format, codec and first frame thumbnail
|
||||||
*/
|
*/
|
||||||
getVideoInfo(filePath: string, format?: 'bmp' | 'bmp24'): Promise<VideoInfo>;
|
getVideoInfo (filePath: string, format?: 'bmp' | 'bmp24'): Promise<VideoInfo>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get duration of audio or video file in seconds
|
* Get duration of audio or video file in seconds
|
||||||
*/
|
*/
|
||||||
getDuration(filePath: string): Promise<number>;
|
getDuration (filePath: string): Promise<number>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert audio file to NTSILK format (WeChat voice message format)
|
* Convert audio file to NTSILK format (WeChat voice message format)
|
||||||
*/
|
*/
|
||||||
convertToNTSilkTct(inputPath: string, outputPath: string): Promise<void>;
|
convertToNTSilkTct (inputPath: string, outputPath: string): Promise<void>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode audio file to raw PCM data
|
* Decode audio file to raw PCM data
|
||||||
*/
|
*/
|
||||||
decodeAudioToPCM(filePath: string, pcmPath: string, sampleRate?: number): Promise<{ result: boolean, sampleRate: number }>;
|
decodeAudioToPCM (filePath: string, pcmPath: string, sampleRate?: number): Promise<{ result: boolean, sampleRate: number; }>;
|
||||||
|
decodeAudioToFmt (filePath: string, pcmPath: string, format: string): Promise<{ channels: number; sampleRate: number; format: string; }>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,14 @@ export class FFmpegService {
|
|||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static getAdapterName (): string {
|
||||||
|
if (!this.adapter) {
|
||||||
|
throw new Error('FFmpeg service not initialized. Please call FFmpegService.init() first.');
|
||||||
|
}
|
||||||
|
return this.adapter.name;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取 FFmpeg 适配器
|
* 获取 FFmpeg 适配器
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export const napCatVersion = '4.9.27';
|
export const napCatVersion = '4.9.40';
|
||||||
|
|||||||
@@ -12,4 +12,16 @@ export class NodeIDependsAdapter {
|
|||||||
getGroupCode (_args: unknown) {
|
getGroupCode (_args: unknown) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// onSendMsfReply (_seq: string, _cmd: string, _uk1: number, _uk2: string, _rsp: {
|
||||||
|
// ssoRetCode: 0,
|
||||||
|
// trpcRetCode: 0,
|
||||||
|
// trpcFuncCode: 0,
|
||||||
|
// errorMsg: '',
|
||||||
|
// pbBuffer: Uint8Array,
|
||||||
|
// transInfoMap: Map<unknown, unknown>;
|
||||||
|
// }) {
|
||||||
|
|
||||||
|
// console.log('[NodeIDependsAdapter] onSendMsfReply', _seq, _cmd, _uk1, _uk2, Buffer.from(_rsp.pbBuffer).toString('hex'));
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ export class NTQQFileApi {
|
|||||||
context: InstanceContext;
|
context: InstanceContext;
|
||||||
core: NapCatCore;
|
core: NapCatCore;
|
||||||
rkeyManager: RkeyManager;
|
rkeyManager: RkeyManager;
|
||||||
packetRkey: Array<{ rkey: string; time: number; type: number; ttl: bigint }> | undefined;
|
packetRkey: Array<{ rkey: string; time: number; type: number; ttl: bigint; }> | undefined;
|
||||||
private fetchRkeyFailures: number = 0;
|
private fetchRkeyFailures: number = 0;
|
||||||
private readonly MAX_RKEY_FAILURES: number = 8;
|
private readonly MAX_RKEY_FAILURES: number = 8;
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ export class NTQQFileApi {
|
|||||||
'http://ss.xingzhige.com/music_card/rkey',
|
'http://ss.xingzhige.com/music_card/rkey',
|
||||||
'https://secret-service.bietiaop.com/rkeys',
|
'https://secret-service.bietiaop.com/rkeys',
|
||||||
],
|
],
|
||||||
this.context.logger
|
this.context.logger
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,9 +360,9 @@ export class NTQQFileApi {
|
|||||||
m.elements
|
m.elements
|
||||||
.filter(element =>
|
.filter(element =>
|
||||||
element.elementType === ElementType.PIC ||
|
element.elementType === ElementType.PIC ||
|
||||||
element.elementType === ElementType.VIDEO ||
|
element.elementType === ElementType.VIDEO ||
|
||||||
element.elementType === ElementType.PTT ||
|
element.elementType === ElementType.PTT ||
|
||||||
element.elementType === ElementType.FILE
|
element.elementType === ElementType.FILE
|
||||||
)
|
)
|
||||||
.map(element =>
|
.map(element =>
|
||||||
this.downloadMedia(m.msgId, m.chatType, m.peerUid, element.elementId, '', '', 1000 * 60 * 2, true)
|
this.downloadMedia(m.msgId, m.chatType, m.peerUid, element.elementId, '', '', 1000 * 60 * 2, true)
|
||||||
@@ -376,9 +376,9 @@ export class NTQQFileApi {
|
|||||||
m.elements.forEach(element => {
|
m.elements.forEach(element => {
|
||||||
if (
|
if (
|
||||||
element.elementType === ElementType.PIC ||
|
element.elementType === ElementType.PIC ||
|
||||||
element.elementType === ElementType.VIDEO ||
|
element.elementType === ElementType.VIDEO ||
|
||||||
element.elementType === ElementType.PTT ||
|
element.elementType === ElementType.PTT ||
|
||||||
element.elementType === ElementType.FILE
|
element.elementType === ElementType.FILE
|
||||||
) {
|
) {
|
||||||
switch (element.elementType) {
|
switch (element.elementType) {
|
||||||
case ElementType.PIC:
|
case ElementType.PIC:
|
||||||
|
|||||||
@@ -17,8 +17,14 @@ export class NTQQFriendApi {
|
|||||||
|
|
||||||
async getBuddyV2SimpleInfoMap () {
|
async getBuddyV2SimpleInfoMap () {
|
||||||
const buddyService = this.context.session.getBuddyService();
|
const buddyService = this.context.session.getBuddyService();
|
||||||
const buddyListV2 = await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL);
|
let uids: string[] = [];
|
||||||
const uids = buddyListV2.data.flatMap(item => item.buddyUids);
|
if (this.core.context.basicInfoWrapper.requireMinNTQQBuild('41679')) {
|
||||||
|
const buddyListV2NT = await buddyService.getBuddyListV2('0', true, BuddyListReqType.KNOMAL);
|
||||||
|
uids = buddyListV2NT.data.flatMap(item => item.buddyUids);
|
||||||
|
} else {
|
||||||
|
const buddyListV2 = await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL);
|
||||||
|
uids = buddyListV2.data.flatMap(item => item.buddyUids);
|
||||||
|
}
|
||||||
return await this.core.eventWrapper.callNoListenerEvent(
|
return await this.core.eventWrapper.callNoListenerEvent(
|
||||||
'NodeIKernelProfileService/getCoreAndBaseInfo',
|
'NodeIKernelProfileService/getCoreAndBaseInfo',
|
||||||
'nodeStore',
|
'nodeStore',
|
||||||
@@ -47,10 +53,15 @@ export class NTQQFriendApi {
|
|||||||
|
|
||||||
async getBuddyV2ExWithCate () {
|
async getBuddyV2ExWithCate () {
|
||||||
const buddyService = this.context.session.getBuddyService();
|
const buddyService = this.context.session.getBuddyService();
|
||||||
const buddyListV2 = (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
|
let uids: string[] = [];
|
||||||
const uids = buddyListV2.flatMap(item => {
|
let buddyListV2: Awaited<ReturnType<typeof buddyService.getBuddyListV2>>['data'];
|
||||||
return item.buddyUids;
|
if (this.core.context.basicInfoWrapper.requireMinNTQQBuild('41679')) {
|
||||||
});
|
buddyListV2 = (await buddyService.getBuddyListV2('0', true, BuddyListReqType.KNOMAL)).data;
|
||||||
|
uids = buddyListV2.flatMap(item => item.buddyUids);
|
||||||
|
} else {
|
||||||
|
buddyListV2 = (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
|
||||||
|
uids = buddyListV2.flatMap(item => item.buddyUids);
|
||||||
|
}
|
||||||
const data = await this.core.eventWrapper.callNoListenerEvent(
|
const data = await this.core.eventWrapper.callNoListenerEvent(
|
||||||
'NodeIKernelProfileService/getCoreAndBaseInfo',
|
'NodeIKernelProfileService/getCoreAndBaseInfo',
|
||||||
'nodeStore',
|
'nodeStore',
|
||||||
|
|||||||
12
src/core/external/appid.json
vendored
12
src/core/external/appid.json
vendored
@@ -454,5 +454,17 @@
|
|||||||
"6.9.83-41857": {
|
"6.9.83-41857": {
|
||||||
"appid": 537320186,
|
"appid": 537320186,
|
||||||
"qua": "V1_MAC_NQ_6.9.83_41857_GW_B"
|
"qua": "V1_MAC_NQ_6.9.83_41857_GW_B"
|
||||||
|
},
|
||||||
|
"3.2.21-42086": {
|
||||||
|
"appid": 537320248,
|
||||||
|
"qua": "V1_LNX_NQ_3.2.21_42086_GW_B"
|
||||||
|
},
|
||||||
|
"9.9.23-42086": {
|
||||||
|
"appid": 537320212,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.23_42086_GW_B"
|
||||||
|
},
|
||||||
|
"6.9.85-42086": {
|
||||||
|
"appid": 537320237,
|
||||||
|
"qua": "V1_MAC_NQ_6.9.85_42086_GW_B"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
12
src/core/external/napi2native.json
vendored
12
src/core/external/napi2native.json
vendored
@@ -78,5 +78,17 @@
|
|||||||
"9.9.23-41857-x64": {
|
"9.9.23-41857-x64": {
|
||||||
"send": "0A01394",
|
"send": "0A01394",
|
||||||
"recv": "1D1C4F9"
|
"recv": "1D1C4F9"
|
||||||
|
},
|
||||||
|
"9.9.23-42086-x64": {
|
||||||
|
"send": "0A01814",
|
||||||
|
"recv": "1D1C9B9"
|
||||||
|
},
|
||||||
|
"6.9.85-42086-arm64": {
|
||||||
|
"send": "23B0330",
|
||||||
|
"recv": "0957648"
|
||||||
|
},
|
||||||
|
"3.2.21-42086-x64": {
|
||||||
|
"send": "5B42CF0",
|
||||||
|
"recv": "2FDA6F0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
12
src/core/external/packet.json
vendored
12
src/core/external/packet.json
vendored
@@ -590,5 +590,17 @@
|
|||||||
"3.2.21-41857-arm64": {
|
"3.2.21-41857-arm64": {
|
||||||
"send": "6B159F8",
|
"send": "6B159F8",
|
||||||
"recv": "6B19388"
|
"recv": "6B19388"
|
||||||
|
},
|
||||||
|
"9.9.23-42086-x64": {
|
||||||
|
"send": "2C99800",
|
||||||
|
"recv": "2C9CD80"
|
||||||
|
},
|
||||||
|
"3.2.21-42086-x64": {
|
||||||
|
"send": "A7B1060",
|
||||||
|
"recv": "A7B4AE0"
|
||||||
|
},
|
||||||
|
"3.2.21-42086-arm64": {
|
||||||
|
"send": "6B13038",
|
||||||
|
"recv": "6B169C8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,7 +18,7 @@ export interface NativePacketExportType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type PacketType = 0 | 1; // 0: send, 1: recv
|
export type PacketType = 0 | 1; // 0: send, 1: recv
|
||||||
export type PacketCallback = (data: { type: PacketType, uin: string, cmd: string, seq: number, hex_data: string }) => void;
|
export type PacketCallback = (data: { type: PacketType, uin: string, cmd: string, seq: number, hex_data: string; }) => void;
|
||||||
|
|
||||||
interface ListenerEntry {
|
interface ListenerEntry {
|
||||||
callback: PacketCallback;
|
callback: PacketCallback;
|
||||||
@@ -27,14 +27,30 @@ interface ListenerEntry {
|
|||||||
|
|
||||||
export class NativePacketHandler {
|
export class NativePacketHandler {
|
||||||
private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64'];
|
private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64'];
|
||||||
private readonly MoeHooExport: { exports: NativePacketExportType } = { exports: {} };
|
private readonly MoeHooExport: { exports: NativePacketExportType; } = { exports: {} };
|
||||||
protected readonly logger: LogWrapper;
|
protected readonly logger: LogWrapper;
|
||||||
|
private loaded: boolean = false;
|
||||||
|
|
||||||
// 统一的监听器存储 - key: 'all' | 'type:0' | 'type:1' | 'cmd:xxx' | 'exact:type:cmd'
|
// 统一的监听器存储 - key: 'all' | 'type:0' | 'type:1' | 'cmd:xxx' | 'exact:type:cmd'
|
||||||
private readonly listeners: Map<string, Set<ListenerEntry>> = new Map();
|
private readonly listeners: Map<string, Set<ListenerEntry>> = new Map();
|
||||||
|
|
||||||
constructor ({ logger }: { logger: LogWrapper }) {
|
constructor ({ logger }: { logger: LogWrapper; }) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
try {
|
||||||
|
const platform = process.platform + '.' + process.arch;
|
||||||
|
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './native/packet/MoeHoo.' + platform + '.node');
|
||||||
|
if (!fs.existsSync(moehoo_path)) {
|
||||||
|
this.logger.logWarn(`NativePacketClient: 缺失运行时文件: ${moehoo_path}`);
|
||||||
|
this.loaded = false;
|
||||||
|
}
|
||||||
|
process.dlopen(this.MoeHooExport, moehoo_path, constants.dlopen.RTLD_LAZY);
|
||||||
|
this.loaded = true;
|
||||||
|
this.logger.log('[PacketHandler] 加载成功');
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.logError('NativePacketClient 加载出错:', error);
|
||||||
|
this.loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,10 +166,10 @@ export class NativePacketHandler {
|
|||||||
*/
|
*/
|
||||||
private emitPacket (type: PacketType, uin: string, cmd: string, seq: number, hex_data: string): void {
|
private emitPacket (type: PacketType, uin: string, cmd: string, seq: number, hex_data: string): void {
|
||||||
const keys = [
|
const keys = [
|
||||||
`exact:${type}:${cmd}`, // 精确匹配
|
`exact:${type}:${cmd}`, // 精确匹配
|
||||||
`cmd:${cmd}`, // cmd匹配
|
`cmd:${cmd}`, // cmd匹配
|
||||||
`type:${type}`, // type匹配
|
`type:${type}`, // type匹配
|
||||||
'all', // 全局
|
'all', // 全局
|
||||||
];
|
];
|
||||||
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
@@ -182,6 +198,10 @@ export class NativePacketHandler {
|
|||||||
async init (version: string): Promise<boolean> {
|
async init (version: string): Promise<boolean> {
|
||||||
const version_arch = version + '-' + process.arch;
|
const version_arch = version + '-' + process.arch;
|
||||||
try {
|
try {
|
||||||
|
if (!this.loaded) {
|
||||||
|
this.logger.logWarn('NativePacketClient 未成功加载,无法初始化');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const send = typedOffset[version_arch]?.send;
|
const send = typedOffset[version_arch]?.send;
|
||||||
const recv = typedOffset[version_arch]?.recv;
|
const recv = typedOffset[version_arch]?.recv;
|
||||||
if (!send || !recv) {
|
if (!send || !recv) {
|
||||||
@@ -193,16 +213,11 @@ export class NativePacketHandler {
|
|||||||
this.logger.logWarn(`NativePacketClient: 不支持的平台: ${platform}`);
|
this.logger.logWarn(`NativePacketClient: 不支持的平台: ${platform}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './native/packet/MoeHoo.' + platform + '.node');
|
|
||||||
|
|
||||||
process.dlopen(this.MoeHooExport, moehoo_path, constants.dlopen.RTLD_LAZY);
|
|
||||||
if (!fs.existsSync(moehoo_path)) {
|
|
||||||
this.logger.logWarn(`NativePacketClient: 缺失运行时文件: ${moehoo_path}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.MoeHooExport.exports.initHook?.(send, recv, (type: PacketType, uin: string, cmd: string, seq: number, hex_data: string) => {
|
this.MoeHooExport.exports.initHook?.(send, recv, (type: PacketType, uin: string, cmd: string, seq: number, hex_data: string) => {
|
||||||
this.emitPacket(type, uin, cmd, seq, hex_data);
|
this.emitPacket(type, uin, cmd, seq, hex_data);
|
||||||
}, true);
|
}, true);
|
||||||
|
this.logger.log('[PacketHandler] 初始化成功');
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.logError('NativePacketClient 初始化出错:', error);
|
this.logger.logError('NativePacketClient 初始化出错:', error);
|
||||||
|
|||||||
@@ -3,122 +3,133 @@ import { NodeIKernelBuddyListener } from '@/core/listeners';
|
|||||||
import { BuddyListReqType } from '@/core/types/user';
|
import { BuddyListReqType } from '@/core/types/user';
|
||||||
|
|
||||||
export interface NodeIKernelBuddyService {
|
export interface NodeIKernelBuddyService {
|
||||||
getBuddyListV2(callFrom: string, reqType: BuddyListReqType): Promise<GeneralCallResult & {
|
getBuddyListV2 (callFrom: string, reqType: BuddyListReqType): Promise<GeneralCallResult & {
|
||||||
data: Array<{
|
data: Array<{
|
||||||
categoryId: number,
|
categoryId: number,
|
||||||
categorySortId: number,
|
categorySortId: number,
|
||||||
categroyName: string,
|
categroyName: string,
|
||||||
categroyMbCount: number,
|
categroyMbCount: number,
|
||||||
onlineCount: number,
|
onlineCount: number,
|
||||||
buddyUids: Array<string>
|
buddyUids: Array<string>;
|
||||||
}>
|
}>;
|
||||||
|
}>;
|
||||||
|
getBuddyListV2 (callFrom: string, isPullRefresh: boolean, reqType: BuddyListReqType): Promise<GeneralCallResult & {
|
||||||
|
data: Array<{
|
||||||
|
categoryId: number,
|
||||||
|
categorySortId: number,
|
||||||
|
categroyName: string,
|
||||||
|
categroyMbCount: number,
|
||||||
|
onlineCount: number,
|
||||||
|
buddyUids: Array<string>;
|
||||||
|
}>;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
getBuddyListFromCache(reqType: BuddyListReqType): Promise<Array<
|
|
||||||
{
|
|
||||||
categoryId: number, // 9999为特别关心
|
|
||||||
categorySortId: number, // 排序方式
|
|
||||||
categroyName: string, // 分类名
|
|
||||||
categroyMbCount: number, // 不懂
|
|
||||||
onlineCount: number, // 在线数目
|
|
||||||
buddyUids: Array<string>// Uids
|
|
||||||
}>>;
|
|
||||||
|
|
||||||
addKernelBuddyListener(listener: NodeIKernelBuddyListener): number;
|
getBuddyListFromCache (reqType: BuddyListReqType): Promise<Array<
|
||||||
|
{
|
||||||
|
categoryId: number, // 9999为特别关心
|
||||||
|
categorySortId: number, // 排序方式
|
||||||
|
categroyName: string, // 分类名
|
||||||
|
categroyMbCount: number, // 不懂
|
||||||
|
onlineCount: number, // 在线数目
|
||||||
|
buddyUids: Array<string>;// Uids
|
||||||
|
}>>;
|
||||||
|
|
||||||
getAllBuddyCount(): number;
|
addKernelBuddyListener (listener: NodeIKernelBuddyListener): number;
|
||||||
|
|
||||||
removeKernelBuddyListener(listenerId: number): void;
|
getAllBuddyCount (): number;
|
||||||
|
|
||||||
|
removeKernelBuddyListener (listenerId: number): void;
|
||||||
|
|
||||||
// getBuddyList(nocache: boolean): Promise<GeneralCallResult>;
|
// getBuddyList(nocache: boolean): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
getBuddyNick(uid: number): string;
|
getBuddyNick (uid: number): string;
|
||||||
|
|
||||||
getBuddyRemark(uid: number): string;
|
getBuddyRemark (uid: number): string;
|
||||||
|
|
||||||
setBuddyRemark(param: { uid: string, remark: string, signInfo?: unknown }): void;
|
setBuddyRemark (param: { uid: string, remark: string, signInfo?: unknown; }): void;
|
||||||
|
|
||||||
getAvatarUrl(uid: number): string;
|
getAvatarUrl (uid: number): string;
|
||||||
|
|
||||||
isBuddy(uid: string): boolean;
|
isBuddy (uid: string): boolean;
|
||||||
|
|
||||||
getCategoryNameWithUid(uid: number): string;
|
getCategoryNameWithUid (uid: number): string;
|
||||||
|
|
||||||
getTargetBuddySetting(uid: number): unknown;
|
getTargetBuddySetting (uid: number): unknown;
|
||||||
|
|
||||||
getTargetBuddySettingByType(uid: number, type: number): unknown;
|
getTargetBuddySettingByType (uid: number, type: number): unknown;
|
||||||
|
|
||||||
getBuddyReqUnreadCnt(): number;
|
getBuddyReqUnreadCnt (): number;
|
||||||
|
|
||||||
getBuddyReq(): Promise<GeneralCallResult>;
|
getBuddyReq (): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
delBuddyReq(uid: number): void;
|
delBuddyReq (uid: number): void;
|
||||||
|
|
||||||
clearBuddyReqUnreadCnt(): Promise<GeneralCallResult>;
|
clearBuddyReqUnreadCnt (): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
reqToAddFriends(uid: number, msg: string): void;
|
reqToAddFriends (uid: number, msg: string): void;
|
||||||
|
|
||||||
setSpacePermission(uid: number, permission: number): void;
|
setSpacePermission (uid: number, permission: number): void;
|
||||||
|
|
||||||
approvalFriendRequest(arg: {
|
approvalFriendRequest (arg: {
|
||||||
friendUid: string;
|
friendUid: string;
|
||||||
reqTime: string;
|
reqTime: string;
|
||||||
accept: boolean;
|
accept: boolean;
|
||||||
}): Promise<void>;
|
}): Promise<void>;
|
||||||
|
|
||||||
delBuddy(param: {
|
delBuddy (param: {
|
||||||
friendUid: string;
|
friendUid: string;
|
||||||
tempBlock: boolean;
|
tempBlock: boolean;
|
||||||
tempBothDel: boolean;
|
tempBothDel: boolean;
|
||||||
}): Promise<unknown>;
|
}): Promise<unknown>;
|
||||||
|
|
||||||
delBatchBuddy(uids: number[]): void;
|
delBatchBuddy (uids: number[]): void;
|
||||||
|
|
||||||
getSmartInfos(uid: number): unknown;
|
getSmartInfos (uid: number): unknown;
|
||||||
|
|
||||||
setBuddyCategory(uid: number, category: number): void;
|
setBuddyCategory (uid: number, category: number): void;
|
||||||
|
|
||||||
setBatchBuddyCategory(uids: number[], category: number): void;
|
setBatchBuddyCategory (uids: number[], category: number): void;
|
||||||
|
|
||||||
addCategory(category: string): void;
|
addCategory (category: string): void;
|
||||||
|
|
||||||
delCategory(category: string): void;
|
delCategory (category: string): void;
|
||||||
|
|
||||||
renameCategory(oldCategory: string, newCategory: string): void;
|
renameCategory (oldCategory: string, newCategory: string): void;
|
||||||
|
|
||||||
resortCategory(categorys: string[]): void;
|
resortCategory (categorys: string[]): void;
|
||||||
|
|
||||||
pullCategory(uid: number, category: string): void;
|
pullCategory (uid: number, category: string): void;
|
||||||
|
|
||||||
setTop(uid: number, isTop: boolean): void;
|
setTop (uid: number, isTop: boolean): void;
|
||||||
|
|
||||||
SetSpecialCare(uid: number, isSpecialCare: boolean): void;
|
SetSpecialCare (uid: number, isSpecialCare: boolean): void;
|
||||||
|
|
||||||
setMsgNotify(uid: number, isNotify: boolean): void;
|
setMsgNotify (uid: number, isNotify: boolean): void;
|
||||||
|
|
||||||
hasBuddyList(): boolean;
|
hasBuddyList (): boolean;
|
||||||
|
|
||||||
setBlock(uid: number, isBlock: boolean): void;
|
setBlock (uid: number, isBlock: boolean): void;
|
||||||
|
|
||||||
isBlocked(uid: number): boolean;
|
isBlocked (uid: number): boolean;
|
||||||
|
|
||||||
modifyAddMeSetting(setting: unknown): void;
|
modifyAddMeSetting (setting: unknown): void;
|
||||||
|
|
||||||
getAddMeSetting(): unknown;
|
getAddMeSetting (): unknown;
|
||||||
|
|
||||||
getDoubtBuddyReq(reqId: string, num: number, uk:string): Promise<GeneralCallResult>;
|
getDoubtBuddyReq (reqId: string, num: number, uk: string): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
getDoubtBuddyUnreadNum(): number;
|
getDoubtBuddyUnreadNum (): number;
|
||||||
|
|
||||||
approvalDoubtBuddyReq(uid: string, str1: string, str2: string): void;
|
approvalDoubtBuddyReq (uid: string, str1: string, str2: string): void;
|
||||||
|
|
||||||
delDoubtBuddyReq(uid: number): void;
|
delDoubtBuddyReq (uid: number): void;
|
||||||
|
|
||||||
delAllDoubtBuddyReq(): Promise<GeneralCallResult>;
|
delAllDoubtBuddyReq (): Promise<GeneralCallResult>;
|
||||||
|
|
||||||
reportDoubtBuddyReqUnread(): void;
|
reportDoubtBuddyReqUnread (): void;
|
||||||
|
|
||||||
getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string }>;
|
getBuddyRecommendContactArkJson (uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string; }>;
|
||||||
|
|
||||||
isNull(): boolean;
|
isNull (): boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,24 +5,24 @@ enum ProxyType {
|
|||||||
SOCKET = 2,
|
SOCKET = 2,
|
||||||
}
|
}
|
||||||
export interface NodeIKernelMSFService {
|
export interface NodeIKernelMSFService {
|
||||||
getServerTime(): string;
|
getServerTime (): string;
|
||||||
setNetworkProxy(param: {
|
setNetworkProxy (param: {
|
||||||
userName: string,
|
userName: string,
|
||||||
userPwd: string,
|
userPwd: string,
|
||||||
address: string,
|
address: string,
|
||||||
port: number,
|
port: number,
|
||||||
proxyType: ProxyType,
|
proxyType: ProxyType,
|
||||||
domain: string,
|
domain: string,
|
||||||
isSocket: boolean
|
isSocket: boolean;
|
||||||
}): Promise<GeneralCallResult>;
|
}): Promise<GeneralCallResult>;
|
||||||
getNetworkProxy(): Promise<{
|
getNetworkProxy (): Promise<{
|
||||||
userName: string,
|
userName: string,
|
||||||
userPwd: string,
|
userPwd: string,
|
||||||
address: string,
|
address: string,
|
||||||
port: number,
|
port: number,
|
||||||
proxyType: ProxyType,
|
proxyType: ProxyType,
|
||||||
domain: string,
|
domain: string,
|
||||||
isSocket: boolean
|
isSocket: boolean;
|
||||||
}>;
|
}>;
|
||||||
// http
|
// http
|
||||||
// userName: '',
|
// userName: '',
|
||||||
@@ -40,4 +40,14 @@ export interface NodeIKernelMSFService {
|
|||||||
// proxyType: 2,
|
// proxyType: 2,
|
||||||
// domain: '',
|
// domain: '',
|
||||||
// isSocket: true
|
// isSocket: true
|
||||||
|
sendMsfRequest (seq: string, cmd: string, reqData: Uint8Array, option: {
|
||||||
|
sendTimeout: number,
|
||||||
|
sendTimeoutOnSlowNet: number,
|
||||||
|
resendNum: number,
|
||||||
|
sendOptions: number,
|
||||||
|
reqTargetAccountType: number,
|
||||||
|
account: string,
|
||||||
|
accountType: number,
|
||||||
|
transInfoMap: Map<string, unknown>;
|
||||||
|
}): Promise<Buffer>;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,7 @@ import { FFmpegService } from '@/common/ffmpeg';
|
|||||||
const out_format = ['mp3', 'amr', 'wma', 'm4a', 'spx', 'ogg', 'wav', 'flac'];
|
const out_format = ['mp3', 'amr', 'wma', 'm4a', 'spx', 'ogg', 'wav', 'flac'];
|
||||||
|
|
||||||
type Payload = {
|
type Payload = {
|
||||||
out_format: string
|
out_format: string;
|
||||||
} & GetFilePayload;
|
} & GetFilePayload;
|
||||||
|
|
||||||
export default class GetRecord extends GetFileBase {
|
export default class GetRecord extends GetFileBase {
|
||||||
@@ -28,8 +28,12 @@ export default class GetRecord extends GetFileBase {
|
|||||||
try {
|
try {
|
||||||
await fs.access(outputFile);
|
await fs.access(outputFile);
|
||||||
} catch {
|
} catch {
|
||||||
await this.decodeFile(inputFile, pcmFile);
|
if (FFmpegService.getAdapterName() === 'FFmpegAddon') {
|
||||||
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
|
await FFmpegService.convertFile(inputFile, outputFile, payload.out_format);
|
||||||
|
} else {
|
||||||
|
await this.decodeFile(inputFile, pcmFile);
|
||||||
|
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const base64Data = await fs.readFile(outputFile, { encoding: 'base64' });
|
const base64Data = await fs.readFile(outputFile, { encoding: 'base64' });
|
||||||
res.file = outputFile;
|
res.file = outputFile;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export class SendGroupNotice extends OneBotAction<Payload, null> {
|
|||||||
await checkFileExist(path, 5000);
|
await checkFileExist(path, 5000);
|
||||||
const ImageUploadResult = await this.core.apis.GroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
|
const ImageUploadResult = await this.core.apis.GroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
|
||||||
if (ImageUploadResult.errCode !== 0) {
|
if (ImageUploadResult.errCode !== 0) {
|
||||||
throw new Error(`群公告${payload.image}设置失败,图片上传失败`);
|
throw new Error(`群公告${payload.image}设置失败,图片上传失败 , 错误信息:${ImageUploadResult.errMsg}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink(path).catch(() => { });
|
unlink(path).catch(() => { });
|
||||||
|
|||||||
@@ -47,8 +47,12 @@ export class DownloadFileRecordStream extends BaseDownloadStream<Payload, Downlo
|
|||||||
streamPath = outputFile;
|
streamPath = outputFile;
|
||||||
} catch {
|
} catch {
|
||||||
// 尝试解码 silk 到 pcm 再用 ffmpeg 转换
|
// 尝试解码 silk 到 pcm 再用 ffmpeg 转换
|
||||||
await this.decodeFile(downloadPath, pcmFile);
|
if (FFmpegService.getAdapterName() === 'FFmpegAddon') {
|
||||||
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
|
await FFmpegService.convertFile(downloadPath, outputFile, payload.out_format);
|
||||||
|
} else {
|
||||||
|
await this.decodeFile(downloadPath, pcmFile);
|
||||||
|
await FFmpegService.convertFile(pcmFile, outputFile, payload.out_format);
|
||||||
|
}
|
||||||
streamPath = outputFile;
|
streamPath = outputFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -907,12 +907,12 @@ export class OneBotMsgApi {
|
|||||||
|
|
||||||
async parsePrivateMsgEvent (msg: RawMessage, grayTipElement: GrayTipElement) {
|
async parsePrivateMsgEvent (msg: RawMessage, grayTipElement: GrayTipElement) {
|
||||||
if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
|
if (grayTipElement.subElementType === NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
|
||||||
if (grayTipElement.jsonGrayTipElement.busiId === 1061) {
|
if (grayTipElement.jsonGrayTipElement.busiId.toString() === '1061') {
|
||||||
const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(grayTipElement, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
|
const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(grayTipElement, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
|
||||||
if (PokeEvent) {
|
if (PokeEvent) {
|
||||||
return PokeEvent;
|
return PokeEvent;
|
||||||
}
|
}
|
||||||
} else if (grayTipElement.jsonGrayTipElement.busiId === 19324 && msg.peerUid !== '') {
|
} else if (grayTipElement.jsonGrayTipElement.busiId.toString() === '19324' && msg.peerUid !== '') {
|
||||||
return new OB11FriendAddNoticeEvent(this.core, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
|
return new OB11FriendAddNoticeEvent(this.core, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
tests/QQNT.dll
BIN
tests/QQNT.dll
Binary file not shown.
347
vite.config.ts
347
vite.config.ts
@@ -6,204 +6,205 @@ import { builtinModules } from 'module';
|
|||||||
import { performanceMonitorPlugin } from './vite-plugin-performance-monitor';
|
import { performanceMonitorPlugin } from './vite-plugin-performance-monitor';
|
||||||
//依赖排除
|
//依赖排除
|
||||||
const external = [
|
const external = [
|
||||||
'silk-wasm',
|
'silk-wasm',
|
||||||
'ws',
|
'ws',
|
||||||
'express'
|
'express'
|
||||||
];
|
];
|
||||||
const nodeModules = [...builtinModules, builtinModules.map((m) => `node:${m}`)].flat();
|
const nodeModules = [...builtinModules, builtinModules.map((m) => `node:${m}`)].flat();
|
||||||
|
|
||||||
let startScripts: string[] | undefined = undefined;
|
let startScripts: string[] | undefined = undefined;
|
||||||
if (process.env.NAPCAT_BUILDSYS == 'linux') {
|
if (process.env.NAPCAT_BUILDSYS == 'linux') {
|
||||||
startScripts = [];
|
startScripts = [];
|
||||||
} else if (process.env.NAPCAT_BUILDSYS == 'win32') {
|
} else if (process.env.NAPCAT_BUILDSYS == 'win32') {
|
||||||
startScripts = ['./script/KillQQ.bat'];
|
startScripts = ['./script/KillQQ.bat'];
|
||||||
} else {
|
} else {
|
||||||
startScripts = ['./script/KillQQ.bat'];
|
startScripts = ['./script/KillQQ.bat'];
|
||||||
}
|
}
|
||||||
|
|
||||||
const UniversalBaseConfigPlugin: PluginOption[] = [
|
const UniversalBaseConfigPlugin: PluginOption[] = [
|
||||||
// performanceMonitorPlugin({
|
// performanceMonitorPlugin({
|
||||||
// enabled: process.env.NODE_ENV !== 'production',
|
// enabled: process.env.NODE_ENV !== 'production',
|
||||||
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
|
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
|
||||||
// include: [/\.ts$/, /\.js$/]
|
// include: [/\.ts$/, /\.js$/]
|
||||||
// }),
|
// }),
|
||||||
cp({
|
cp({
|
||||||
targets: [
|
targets: [
|
||||||
{ src: './manifest.json', dest: 'dist' },
|
{ src: './manifest.json', dest: 'dist' },
|
||||||
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
||||||
{ src: './src/native/', dest: 'dist/native', flatten: false },
|
{ src: './src/native/', dest: 'dist/native', flatten: false },
|
||||||
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
|
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
|
||||||
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
|
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
|
||||||
{ src: './src/framework/napcat.cjs', dest: 'dist' },
|
{ src: './src/framework/napcat.cjs', dest: 'dist' },
|
||||||
{ src: './src/framework/preload.cjs', dest: 'dist' },
|
{ src: './src/framework/preload.cjs', dest: 'dist' },
|
||||||
{ src: './src/framework/renderer.js', dest: 'dist' },
|
{ src: './src/framework/renderer.js', dest: 'dist' },
|
||||||
{ src: './package.json', dest: 'dist' },
|
{ src: './package.json', dest: 'dist' },
|
||||||
{ src: './logo.png', dest: 'dist' },
|
{ src: './logo.png', dest: 'dist' },
|
||||||
{ src: './launcher/', dest: 'dist', flatten: true },
|
{ src: './launcher/', dest: 'dist', flatten: true },
|
||||||
...startScripts.map((startScript) => {
|
...startScripts.map((startScript) => {
|
||||||
return { src: startScript, dest: 'dist' };
|
return { src: startScript, dest: 'dist' };
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
nodeResolve(),
|
nodeResolve(),
|
||||||
];
|
];
|
||||||
|
|
||||||
const FrameworkBaseConfigPlugin: PluginOption[] = [
|
const FrameworkBaseConfigPlugin: PluginOption[] = [
|
||||||
// performanceMonitorPlugin({
|
// performanceMonitorPlugin({
|
||||||
// enabled: process.env.NODE_ENV !== 'production',
|
// enabled: process.env.NODE_ENV !== 'production',
|
||||||
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
|
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
|
||||||
// include: [/\.ts$/, /\.js$/]
|
// include: [/\.ts$/, /\.js$/]
|
||||||
// }),
|
// }),
|
||||||
cp({
|
cp({
|
||||||
targets: [
|
targets: [
|
||||||
{ src: './src/native/', dest: 'dist/native', flatten: false },
|
{ src: './napiloader/', dest: 'dist', flatten: true },
|
||||||
{ src: './manifest.json', dest: 'dist' },
|
{ src: './src/native/', dest: 'dist/native', flatten: false },
|
||||||
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
{ src: './manifest.json', dest: 'dist' },
|
||||||
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
|
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
||||||
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
|
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
|
||||||
{ src: './src/framework/napcat.cjs', dest: 'dist' },
|
{ src: './src/framework/liteloader.cjs', dest: 'dist' },
|
||||||
{ src: './src/framework/nativeLoader.cjs', dest: 'dist' },
|
{ src: './src/framework/napcat.cjs', dest: 'dist' },
|
||||||
{ src: './src/framework/preload.cjs', dest: 'dist' },
|
{ src: './src/framework/nativeLoader.cjs', dest: 'dist' },
|
||||||
{ src: './src/framework/renderer.js', dest: 'dist' },
|
{ src: './src/framework/preload.cjs', dest: 'dist' },
|
||||||
{ src: './package.json', dest: 'dist' },
|
{ src: './src/framework/renderer.js', dest: 'dist' },
|
||||||
{ src: './logo.png', dest: 'dist' },
|
{ src: './package.json', dest: 'dist' },
|
||||||
],
|
{ src: './logo.png', dest: 'dist' },
|
||||||
}),
|
],
|
||||||
nodeResolve(),
|
}),
|
||||||
|
nodeResolve(),
|
||||||
];
|
];
|
||||||
|
|
||||||
const ShellBaseConfigPlugin: PluginOption[] = [
|
const ShellBaseConfigPlugin: PluginOption[] = [
|
||||||
// performanceMonitorPlugin({
|
// performanceMonitorPlugin({
|
||||||
// enabled: process.env.NODE_ENV !== 'production',
|
// enabled: process.env.NODE_ENV !== 'production',
|
||||||
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
|
// exclude: [/node_modules/, /\.min\./, /performance-monitor/],
|
||||||
// include: [/\.ts$/, /\.js$/]
|
// include: [/\.ts$/, /\.js$/]
|
||||||
// }),
|
// }),
|
||||||
cp({
|
cp({
|
||||||
targets: [
|
targets: [
|
||||||
{ src: './src/native/', dest: 'dist/native', flatten: false },
|
{ src: './src/native/', dest: 'dist/native', flatten: false },
|
||||||
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
|
{ src: './napcat.webui/dist/', dest: 'dist/static/', flatten: false },
|
||||||
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
{ src: './src/core/external/napcat.json', dest: 'dist/config/' },
|
||||||
{ src: './package.json', dest: 'dist' },
|
{ src: './package.json', dest: 'dist' },
|
||||||
{ src: './launcher/', dest: 'dist', flatten: true },
|
{ src: './launcher/', dest: 'dist', flatten: true },
|
||||||
...startScripts.map((startScript) => {
|
...startScripts.map((startScript) => {
|
||||||
return { src: startScript, dest: 'dist' };
|
return { src: startScript, dest: 'dist' };
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
nodeResolve(),
|
nodeResolve(),
|
||||||
];
|
];
|
||||||
const UniversalBaseConfig = () =>
|
const UniversalBaseConfig = () =>
|
||||||
defineConfig({
|
defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
conditions: ['node', 'default'],
|
conditions: ['node', 'default'],
|
||||||
alias: {
|
alias: {
|
||||||
'@/core': resolve(__dirname, './src/core'),
|
'@/core': resolve(__dirname, './src/core'),
|
||||||
'@': resolve(__dirname, './src'),
|
'@': resolve(__dirname, './src'),
|
||||||
'@webapi': resolve(__dirname, './src/webui/src'),
|
'@webapi': resolve(__dirname, './src/webui/src'),
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
sourcemap: false,
|
||||||
|
target: 'esnext',
|
||||||
|
minify: false,
|
||||||
|
lib: {
|
||||||
|
entry: {
|
||||||
|
napcat: 'src/universal/napcat.ts',
|
||||||
|
'audio-worker': 'src/common/audio-worker.ts',
|
||||||
|
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
|
||||||
},
|
},
|
||||||
build: {
|
formats: ['es'],
|
||||||
sourcemap: false,
|
fileName: (_, entryName) => `${entryName}.mjs`,
|
||||||
target: 'esnext',
|
},
|
||||||
minify: false,
|
rollupOptions: {
|
||||||
lib: {
|
external: [...nodeModules, ...external],
|
||||||
entry: {
|
},
|
||||||
napcat: 'src/universal/napcat.ts',
|
},
|
||||||
'audio-worker': 'src/common/audio-worker.ts',
|
});
|
||||||
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
|
|
||||||
},
|
|
||||||
formats: ['es'],
|
|
||||||
fileName: (_, entryName) => `${entryName}.mjs`,
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external: [...nodeModules, ...external],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const ShellBaseConfig = () =>
|
const ShellBaseConfig = () =>
|
||||||
defineConfig({
|
defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
conditions: ['node', 'default'],
|
conditions: ['node', 'default'],
|
||||||
alias: {
|
alias: {
|
||||||
'@/core': resolve(__dirname, './src/core'),
|
'@/core': resolve(__dirname, './src/core'),
|
||||||
'@': resolve(__dirname, './src'),
|
'@': resolve(__dirname, './src'),
|
||||||
'@webapi': resolve(__dirname, './src/webui/src'),
|
'@webapi': resolve(__dirname, './src/webui/src'),
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
sourcemap: false,
|
||||||
|
target: 'esnext',
|
||||||
|
minify: false,
|
||||||
|
lib: {
|
||||||
|
entry: {
|
||||||
|
napcat: 'src/shell/napcat.ts',
|
||||||
|
'audio-worker': 'src/common/audio-worker.ts',
|
||||||
|
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
|
||||||
},
|
},
|
||||||
build: {
|
formats: ['es'],
|
||||||
sourcemap: false,
|
fileName: (_, entryName) => `${entryName}.mjs`,
|
||||||
target: 'esnext',
|
},
|
||||||
minify: false,
|
rollupOptions: {
|
||||||
lib: {
|
external: [...nodeModules, ...external],
|
||||||
entry: {
|
},
|
||||||
napcat: 'src/shell/napcat.ts',
|
},
|
||||||
'audio-worker': 'src/common/audio-worker.ts',
|
});
|
||||||
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
|
|
||||||
},
|
|
||||||
formats: ['es'],
|
|
||||||
fileName: (_, entryName) => `${entryName}.mjs`,
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external: [...nodeModules, ...external],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const FrameworkBaseConfig = () =>
|
const FrameworkBaseConfig = () =>
|
||||||
defineConfig({
|
defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
conditions: ['node', 'default'],
|
conditions: ['node', 'default'],
|
||||||
alias: {
|
alias: {
|
||||||
'@/core': resolve(__dirname, './src/core'),
|
'@/core': resolve(__dirname, './src/core'),
|
||||||
'@': resolve(__dirname, './src'),
|
'@': resolve(__dirname, './src'),
|
||||||
'@webapi': resolve(__dirname, './src/webui/src'),
|
'@webapi': resolve(__dirname, './src/webui/src'),
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
sourcemap: false,
|
||||||
|
target: 'esnext',
|
||||||
|
minify: false,
|
||||||
|
lib: {
|
||||||
|
entry: {
|
||||||
|
napcat: 'src/framework/napcat.ts',
|
||||||
|
'audio-worker': 'src/common/audio-worker.ts',
|
||||||
|
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
|
||||||
},
|
},
|
||||||
build: {
|
formats: ['es'],
|
||||||
sourcemap: false,
|
fileName: (_, entryName) => `${entryName}.mjs`,
|
||||||
target: 'esnext',
|
},
|
||||||
minify: false,
|
rollupOptions: {
|
||||||
lib: {
|
external: [...nodeModules, ...external],
|
||||||
entry: {
|
},
|
||||||
napcat: 'src/framework/napcat.ts',
|
},
|
||||||
'audio-worker': 'src/common/audio-worker.ts',
|
});
|
||||||
'worker/conoutSocketWorker': 'src/pty/worker/conoutSocketWorker.ts',
|
|
||||||
},
|
|
||||||
formats: ['es'],
|
|
||||||
fileName: (_, entryName) => `${entryName}.mjs`,
|
|
||||||
},
|
|
||||||
rollupOptions: {
|
|
||||||
external: [...nodeModules, ...external],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default defineConfig(({ mode }): UserConfig => {
|
export default defineConfig(({ mode }): UserConfig => {
|
||||||
if (mode === 'shell') {
|
if (mode === 'shell') {
|
||||||
return {
|
return {
|
||||||
...ShellBaseConfig(),
|
...ShellBaseConfig(),
|
||||||
plugins: [...ShellBaseConfigPlugin],
|
plugins: [...ShellBaseConfigPlugin],
|
||||||
};
|
};
|
||||||
} else if (mode == 'universal') {
|
} else if (mode == 'universal') {
|
||||||
return {
|
return {
|
||||||
...UniversalBaseConfig(),
|
...UniversalBaseConfig(),
|
||||||
plugins: [...UniversalBaseConfigPlugin],
|
plugins: [...UniversalBaseConfigPlugin],
|
||||||
};
|
};
|
||||||
} else if (mode == 'shell-analysis') {
|
} else if (mode == 'shell-analysis') {
|
||||||
return {
|
return {
|
||||||
...ShellBaseConfig(),
|
...ShellBaseConfig(),
|
||||||
plugins: [
|
plugins: [
|
||||||
performanceMonitorPlugin({
|
performanceMonitorPlugin({
|
||||||
exclude: [/node_modules/, /\.min\./, /performance-monitor\.ts$/, /packet/],
|
exclude: [/node_modules/, /\.min\./, /performance-monitor\.ts$/, /packet/],
|
||||||
include: [/\.ts$/, /\.js$/]
|
include: [/\.ts$/, /\.js$/]
|
||||||
}),
|
}),
|
||||||
...ShellBaseConfigPlugin
|
...ShellBaseConfigPlugin
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
} else
|
} else
|
||||||
return {
|
return {
|
||||||
...FrameworkBaseConfig(),
|
...FrameworkBaseConfig(),
|
||||||
plugins: [...FrameworkBaseConfigPlugin],
|
plugins: [...FrameworkBaseConfigPlugin],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user