Compare commits

...

21 Commits

Author SHA1 Message Date
手瓜一十雪
6aadc2402d Enable o3HookMode and update Win32 native binary
Set o3HookMode to 1 in packages/napcat-core/external/napcat.json to enable O3 hook mode. Replace the prebuilt napi2native.win32.x64.node binary in packages/napcat-native/napi2native to include corresponding native changes for Win32 x64.
2026-02-16 14:58:06 +08:00
手瓜一十雪
eb937b29e4 Enable native verbose logging via env var
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Read NAPCAT_ENABLE_VERBOSE_LOG at startup and call napi2nativeLoader.nativeExports.setVerbose(true) (if available) right after loading the wrapper so native verbose logging can be enabled via environment. Also includes an updated native .node binary.
2026-02-13 19:33:48 +08:00
手瓜一十雪
f44aca9a2f Update napi2native Windows x64 binary
Replace the compiled napi2native.win32.x64.node binary for the Windows x64 build. This updates the native addon artifact (likely rebuilt due to code or build environment changes) so consumers get the latest native implementation.
2026-02-13 19:06:12 +08:00
手瓜一十雪
c34812bc9c Update napi2native Windows x64 binary
Replace the compiled napi2native.win32.x64.node binary in packages/napcat-native/napi2native. This updates the Windows x64 native addon (rebuild/bugfix or dependency-linked binary update); no JS/source changes are included in this diff.
2026-02-13 19:01:37 +08:00
手瓜一十雪
d93b430034 Revert "Enable native verbose logging"
This reverts commit cad567dc3f.
2026-02-13 18:12:11 +08:00
手瓜一十雪
c91e1378cf Increase OpenRouter max_tokens to 5000
Update .github/workflows/release.yml to raise the OpenRouter request max_tokens from 1500 to 5000. This allows the model to generate longer responses during the release workflow; be aware this may increase token usage and cost.
2026-02-13 18:01:36 +08:00
手瓜一十雪
cad567dc3f Enable native verbose logging
Invoke nativeExports.setVerbose(true) immediately after loading the QQ wrapper so the native module emits verbose logs (uses optional chaining so it’s safe if the symbol is absent). Also includes an updated napi2native.win32.x64.node binary. This helps with debugging native bypass behavior.
2026-02-13 17:54:45 +08:00
手瓜一十雪
82c8de00d0 Add env var to disable Napi bypass
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Introduce NAPCAT_DISABLE_BYPASS to conditionally skip calling napi2nativeLoader.nativeExports.enableAllBypasses. Updates in napcat-framework/napcat.ts and napcat-shell/base.ts: bypass is enabled by default, but if NAPCAT_DISABLE_BYPASS is set to '1' the bypass call is skipped and a log message indicates it was disabled via environment variable. Keeps existing log when bypass is successfully enabled.
2026-02-13 15:46:30 +08:00
手瓜一十雪
f17abccfdc Cleanup orphaned Electron child processes
Add cleanupOrphanedProcesses to terminate leftover child processes when running in Electron. The function imports Electron at runtime, uses app.getAppMetrics() to enumerate processes, excludes the main and provided worker PIDs, and sends SIGTERM to stray PIDs while ignoring already-dead processes and API errors. Also invoke this cleanup in restartWorker after starting the new worker to avoid lingering processes after restarts. Includes @ts-ignore for the dynamic Electron import and debug logging on failure.
2026-02-13 15:45:05 +08:00
手瓜一十雪
35af50bb73 Add ffmpeg.dll and update Windows native module
Add ffmpeg.dll to the napi2native package and update the prebuilt Windows x64 native addon (napi2native.win32.x64.node). This bundles the FFmpeg runtime with the native package and includes a rebuilt/updated native binary for Windows x64 to ensure compatibility with the new dependency or recent native changes.
2026-02-13 15:34:49 +08:00
手瓜一十雪
5c72f771c3 Add enableAllBypasses and call on startup
Expose an optional enableAllBypasses export in the Napi2Native loader and invoke it during initialization in both napcat-framework and napcat-shell to enable bypasses (logs when enabled). Pre-initialize native modules earlier in the shell startup flow and await nativePacketHandler.init. Also update config o3HookMode from 1 to 0, apply a small signature whitespace fix in clientContext.sendOidbPacket, and include an updated native binary.
2026-02-13 14:56:18 +08:00
手瓜一十雪
62c9246368 feat: 为反检测做准备 2026-02-13 14:28:25 +08:00
手瓜一十雪
d622178b25 Refine NodeIKernel service interfaces (#1619)
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Add multiple NodeIKernel service interface files and tighten up method signatures and types across napcat-core. New interfaces added (e.g. NodeIKernelAVSDKService, NodeIKernelAddBuddyService, NodeIKernelBdhUploadService, NodeIKernelConfigMgrService, NodeIKernelDirectSessionService, NodeIKernelEmojiService, NodeIKernelFeedService, NodeIKernelFileBridgeClientService, NodeIKernelFileBridgeHostService, etc.). Updated existing interfaces with clearer parameter and return types, consistent spacing/semicolons, improved complex return shapes (AlbumService, CollectionService), listener methods, isNull checks, and many other method signature refinements (Avatar, Buddy, DbTools, ECDH, FileAssistant, FlashTransfer, GroupService, and more) to improve type safety and readability.
2026-02-12 21:47:43 +08:00
手瓜一十雪
9887eb8565 Add Linux machine-info GUID management
Add end-to-end support for reading/writing Linux machine-info and computing GUIDs.

Backend: - Introduce MachineInfoUtils (TS) for machine-info path lookup, ROT13 serialization, read/write/delete, backups, and MD5-based GUID computation. - Add a Python utility (guid.py) for CLI inspection, encode/decode, dump, and GUID computation. - Extend QQLogin API with new handlers: GetPlatformInfo, GetLinuxMAC, SetLinuxMAC, GetLinuxMachineId, ComputeLinuxGUID, GetLinuxMachineInfoBackups, CreateLinuxMachineInfoBackup, RestoreLinuxMachineInfoBackup, ResetLinuxDeviceID. Handlers include automatic backup behavior and error handling.

Router: Register new QQLogin routes for platform info and Linux machine-info operations.

Frontend: - Enhance guid_manager UI to detect platform and provide Linux-specific workflow (display machine-id, show/edit MAC, preview computed GUID via MD5, backup/restore/delete machine-info, and restart actions). - Add client-side MD5 (crypto-js) usage and new QQManager API methods to call the new backend endpoints.

This change enables cross-platform GUID management (Windows and Linux), includes CLI tooling for low-level inspection, and adds frontend workflows for Linux device-id management.
2026-02-12 19:00:36 +08:00
手瓜一十雪
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
林小槐
82d0c51716 feat(webui): 插件商店增加插件详情弹窗并支持通过 url 传递 id 直接打开 (#1615)
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
* feat(webui): 插件商店增加插件详情弹窗并支持通过 url 传递 id 直接打开

* fix(webui):type check
2026-02-11 12:12:06 +08:00
手瓜一十雪
37fb2d68d7 Prefer QQAppId/ marker when parsing AppID
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
Add parseAppidFromMajorV2 to napcat-common to scan a Major file for the "QQAppId/" marker and extract a null-terminated numeric AppID. Update qq-basic-info to import and prefer this new parser (falling back to the existing parseAppidFromMajor). Also correct the getMajorPath argument order when obtaining the major file path. This enables detection of AppID from a newer Major format while preserving legacy fallback behavior.
2026-02-08 09:55:31 +08:00
手瓜一十雪
a240f93784 Add appid entry for 9.9.27-45758
Add a new mapping to packages/napcat-core/external/appid.json for version 9.9.27-45758 (Windows). The entry sets appid to 537340213 and qua to "V1_WIN_NQ_9.9.27_45758_GW_B".
2026-02-08 09:41:14 +08:00
时瑾
172a75b514 fix(webui-backend): sanitize plugin ID to prevent path injection (CodeQL js/path-injection)
Some checks failed
Build NapCat Artifacts / Build-Framework (push) Has been cancelled
Build NapCat Artifacts / Build-Shell (push) Has been cancelled
2026-02-07 13:52:15 +08:00
时瑾
beef1233fa fix(ci): 修复 Update apifox 步骤中因 OpenAPI 文件过大导致的参数列表过长错误 2026-02-07 13:44:25 +08:00
时瑾
8f69e2424a fix(backend): 修复插件列表接口新增字段导致的类型错误 2026-02-07 13:38:53 +08:00
104 changed files with 4543 additions and 984 deletions

View File

@@ -10,7 +10,7 @@ permissions: write-all
env: env:
OPENROUTER_API_URL: https://91vip.futureppo.top/v1/chat/completions OPENROUTER_API_URL: https://91vip.futureppo.top/v1/chat/completions
OPENROUTER_MODEL: "gemini-3-flash-preview" OPENROUTER_MODEL: "deepseek-v3.2-chat"
RELEASE_NAME: "NapCat" RELEASE_NAME: "NapCat"
jobs: jobs:
@@ -396,7 +396,7 @@ jobs:
--arg system "$SYSTEM_PROMPT" \ --arg system "$SYSTEM_PROMPT" \
--arg user "$USER_CONTENT" \ --arg user "$USER_CONTENT" \
--arg model "$OPENROUTER_MODEL" \ --arg model "$OPENROUTER_MODEL" \
'{model: $model, messages:[{role:"system", content:$system},{role:"user", content:$user}], temperature:0.2, max_tokens:1500}') '{model: $model, messages:[{role:"system", content:$system},{role:"user", content:$user}], temperature:0.2, max_tokens:5000}')
echo "=== OpenRouter request body ===" echo "=== OpenRouter request body ==="
echo "$BODY" | jq . echo "$BODY" | jq .
@@ -458,24 +458,23 @@ jobs:
pnpm i pnpm i
pnpm run build:openapi pnpm run build:openapi
# 读取并压缩 openapi.json 内容 # 使用 jq 安全地构建大型 JSON 数据并保存到文件
OPENAPI_CONTENT=$(cat packages/napcat-schema/dist/openapi.json | tr -d '\n\r\t' | sed 's/ */ /g' | sed 's/"/\\"/g') jq -n --rawfile input packages/napcat-schema/dist/openapi.json \
'{
# 构建 JSON 数据 input: $input,
JSON_DATA=$(printf '{ options: {
"input": "%s",
"options": {
"endpointOverwriteBehavior": "OVERWRITE_EXISTING", "endpointOverwriteBehavior": "OVERWRITE_EXISTING",
"schemaOverwriteBehavior": "OVERWRITE_EXISTING", "schemaOverwriteBehavior": "OVERWRITE_EXISTING",
"updateFolderOfChangedEndpoint": true, "updateFolderOfChangedEndpoint": true,
"moduleId": 1140714, "moduleId": 1140714,
"deleteUnmatchedResources": true "deleteUnmatchedResources": true
} }
}' "$OPENAPI_CONTENT") }' > apifox_payload.json
# 通过文件形式发送数据,避免命令行长度限制
curl --location -g --request POST 'https://api.apifox.com/v1/projects/5348325/import-openapi?locale=zh-CN' \ curl --location -g --request POST 'https://api.apifox.com/v1/projects/5348325/import-openapi?locale=zh-CN' \
--header 'X-Apifox-Api-Version: 2024-03-28' \ --header 'X-Apifox-Api-Version: 2024-03-28' \
--header "Authorization: Bearer $APIFOX_TOKEN" \ --header "Authorization: Bearer $APIFOX_TOKEN" \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data-raw "$JSON_DATA" --data-binary @apifox_payload.json

3
.gitignore vendored
View File

@@ -10,6 +10,9 @@ devconfig/*
!.vscode/extensions.json !.vscode/extensions.json
.idea/* .idea/*
# macOS
.DS_Store
# Build # Build
*.db *.db
checkVersion.sh checkVersion.sh

View File

@@ -184,6 +184,35 @@ export function stringifyWithBigInt (obj: any) {
); );
} }
export function parseAppidFromMajorV2 (nodeMajor: string): string | undefined {
const marker = Buffer.from('QQAppId/', 'utf-8');
const filePath = path.resolve(nodeMajor);
const fileContent = fs.readFileSync(filePath);
let searchPosition = 0;
while (true) {
const index = fileContent.indexOf(marker, searchPosition);
if (index === -1) {
break;
}
const start = index + marker.length;
const end = fileContent.indexOf(0x00, start);
if (end === -1) {
break;
}
const content = fileContent.subarray(start, end);
const str = content.toString('utf-8');
if (/^\d+$/.test(str)) {
return str;
}
searchPosition = end + 1;
}
return undefined;
}
export function parseAppidFromMajor (nodeMajor: string): string | undefined { export function parseAppidFromMajor (nodeMajor: string): string | undefined {
const hexSequence = 'A4 09 00 00 00 35'; const hexSequence = 'A4 09 00 00 00 35';
const sequenceBytes = Buffer.from(hexSequence.replace(/ /g, ''), 'hex'); const sequenceBytes = Buffer.from(hexSequence.replace(/ /g, ''), 'hex');

View File

@@ -530,5 +530,9 @@
"3.2.25-45758": { "3.2.25-45758": {
"appid": 537340249, "appid": 537340249,
"qua": "V1_LNX_NQ_3.2.25_45758_GW_B" "qua": "V1_LNX_NQ_3.2.25_45758_GW_B"
},
"9.9.27-45758": {
"appid": 537340213,
"qua": "V1_WIN_NQ_9.9.27_45758_GW_B"
} }
} }

View File

@@ -1,9 +1,9 @@
{ {
"fileLog": false, "fileLog": false,
"consoleLog": true, "consoleLog": true,
"fileLogLevel": "debug", "fileLogLevel": "debug",
"consoleLogLevel": "info", "consoleLogLevel": "info",
"packetBackend": "auto", "packetBackend": "auto",
"packetServer": "", "packetServer": "",
"o3HookMode": 1 "o3HookMode": 1
} }

View File

@@ -1,6 +1,6 @@
import fs from 'node:fs'; import fs from 'node:fs';
import { systemPlatform } from 'napcat-common/src/system'; import { systemPlatform } from 'napcat-common/src/system';
import { getDefaultQQVersionConfigInfo, getQQPackageInfoPath, getQQVersionConfigPath, parseAppidFromMajor } from 'napcat-common/src/helper'; import { getDefaultQQVersionConfigInfo, getQQPackageInfoPath, getQQVersionConfigPath, parseAppidFromMajor, parseAppidFromMajorV2 } from 'napcat-common/src/helper';
import AppidTable from '@/napcat-core/external/appid.json'; import AppidTable from '@/napcat-core/external/appid.json';
import { LogWrapper } from './log'; import { LogWrapper } from './log';
import { getMajorPath } from '@/napcat-core/index'; import { getMajorPath } from '@/napcat-core/index';
@@ -107,7 +107,13 @@ export class QQBasicInfoWrapper {
if (!this.QQMainPath) { if (!this.QQMainPath) {
throw new Error('QQMainPath未定义 无法通过Major获取Appid'); throw new Error('QQMainPath未定义 无法通过Major获取Appid');
} }
const majorPath = getMajorPath(QQVersion, this.QQMainPath); const majorPath = getMajorPath(this.QQMainPath, QQVersion);
// 优先通过 QQAppId/ 标记搜索
const appidV2 = parseAppidFromMajorV2(majorPath);
if (appidV2) {
return appidV2;
}
// 回落到旧方式
const appid = parseAppidFromMajor(majorPath); const appid = parseAppidFromMajor(majorPath);
return appid; return appid;
} }

View File

@@ -33,6 +33,7 @@ import { NodeIKernelMsgListener, NodeIKernelProfileListener } from '@/napcat-cor
import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler'; import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler';
import { NTQQPacketApi } from './apis/packet'; import { NTQQPacketApi } from './apis/packet';
import { NativePacketHandler } from './packet/handler/client'; import { NativePacketHandler } from './packet/handler/client';
import { Napi2NativeLoader } from './packet/handler/napi2nativeLoader';
import { container, ReceiverServiceRegistry } from './packet/handler/serviceRegister'; import { container, ReceiverServiceRegistry } from './packet/handler/serviceRegister';
import { appEvent } from './packet/handler/eventList'; import { appEvent } from './packet/handler/eventList';
import { TypedEventEmitter } from './packet/handler/typeEvent'; import { TypedEventEmitter } from './packet/handler/typeEvent';
@@ -314,6 +315,7 @@ export interface InstanceContext {
readonly basicInfoWrapper: QQBasicInfoWrapper; readonly basicInfoWrapper: QQBasicInfoWrapper;
readonly pathWrapper: NapCatPathWrapper; readonly pathWrapper: NapCatPathWrapper;
readonly packetHandler: NativePacketHandler; readonly packetHandler: NativePacketHandler;
readonly napi2nativeLoader: Napi2NativeLoader;
} }
export interface StableNTApiWrapper { export interface StableNTApiWrapper {

View File

@@ -1,11 +1,8 @@
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import { constants } from 'node:os';
import { LogStack } from '@/napcat-core/packet/context/clientContext'; import { LogStack } from '@/napcat-core/packet/context/clientContext';
import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext'; import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext'; import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
import { OidbPacket, PacketBuf } from '@/napcat-core/packet/transformer/base'; import { OidbPacket, PacketBuf } from '@/napcat-core/packet/transformer/base';
import { Napi2NativeLoader } from '@/napcat-core/packet/handler/napi2nativeLoader';
export interface RecvPacket { export interface RecvPacket {
type: string, // 仅recv type: string, // 仅recv
data: RecvPacketData; data: RecvPacketData;
@@ -17,48 +14,36 @@ export interface RecvPacketData {
data: Buffer; data: Buffer;
} }
// 0 send 1 recv
export interface NativePacketExportType {
initHook?: (send: string, recv: string) => boolean;
}
export class NativePacketClient { export class NativePacketClient {
protected readonly napcore: NapCoreContext; protected readonly napcore: NapCoreContext;
protected readonly logger: PacketLogger; protected readonly logger: PacketLogger;
protected readonly cb = new Map<string, (json: RecvPacketData) => Promise<any> | any>(); // hash-type callback protected readonly cb = new Map<string, (json: RecvPacketData) => Promise<any> | any>(); // hash-type callback
protected readonly napi2nativeLoader: Napi2NativeLoader;
logStack: LogStack; logStack: LogStack;
available: boolean = false; available: boolean = false;
private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64'];
private readonly MoeHooExport: { exports: NativePacketExportType; } = { exports: {} };
constructor (napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack) { constructor (napCore: NapCoreContext, logger: PacketLogger, logStack: LogStack, napi2nativeLoader: Napi2NativeLoader) {
this.napcore = napCore; this.napcore = napCore;
this.logger = logger; this.logger = logger;
this.logStack = logStack; this.logStack = logStack;
this.napi2nativeLoader = napi2nativeLoader;
} }
check (): boolean { check (): boolean {
const platform = process.platform + '.' + process.arch; if (!this.napi2nativeLoader.loaded) {
if (!this.supportedPlatforms.includes(platform)) { this.logStack.pushLogWarn('NativePacketClient: Napi2NativeLoader 未成功加载');
this.logStack.pushLogWarn(`NativePacketClient: 不支持的平台: ${platform}`);
return false;
}
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './native/napi2native/napi2native.' + platform + '.node');
if (!fs.existsSync(moehoo_path)) {
this.logStack.pushLogWarn(`NativePacketClient: 缺失运行时文件: ${moehoo_path}`);
return false; return false;
} }
return true; return true;
} }
async init (_pid: number, recv: string, send: string): Promise<void> { async init (_pid: number, recv: string, send: string): Promise<void> {
const platform = process.platform + '.' + process.arch;
const isNewQQ = this.napcore.basicInfo.requireMinNTQQBuild('40824'); const isNewQQ = this.napcore.basicInfo.requireMinNTQQBuild('40824');
if (isNewQQ) { if (isNewQQ) {
const moehoo_path = path.join(dirname(fileURLToPath(import.meta.url)), './native/napi2native/napi2native.' + platform + '.node'); const success = this.napi2nativeLoader.initHook(send, recv);
process.dlopen(this.MoeHooExport, moehoo_path, constants.dlopen.RTLD_LAZY); if (success) {
this.MoeHooExport?.exports.initHook?.(send, recv); this.available = true;
this.available = true; }
} }
} }

View File

@@ -2,6 +2,7 @@ import { NativePacketClient } from '@/napcat-core/packet/client/nativeClient';
import { OidbPacket } from '@/napcat-core/packet/transformer/base'; import { OidbPacket } from '@/napcat-core/packet/transformer/base';
import { PacketLogger } from '@/napcat-core/packet/context/loggerContext'; import { PacketLogger } from '@/napcat-core/packet/context/loggerContext';
import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext'; import { NapCoreContext } from '@/napcat-core/packet/context/napCoreContext';
import { Napi2NativeLoader } from '@/napcat-core/packet/handler/napi2nativeLoader';
export class LogStack { export class LogStack {
private stack: string[] = []; private stack: string[] = [];
@@ -43,12 +44,14 @@ export class PacketClientContext {
private readonly napCore: NapCoreContext; private readonly napCore: NapCoreContext;
private readonly logger: PacketLogger; private readonly logger: PacketLogger;
private readonly logStack: LogStack; private readonly logStack: LogStack;
private readonly napi2nativeLoader: Napi2NativeLoader;
private readonly _client: NativePacketClient; private readonly _client: NativePacketClient;
constructor (napCore: NapCoreContext, logger: PacketLogger) { constructor (napCore: NapCoreContext, logger: PacketLogger, napi2nativeLoader: Napi2NativeLoader) {
this.napCore = napCore; this.napCore = napCore;
this.logger = logger; this.logger = logger;
this.logStack = new LogStack(logger); this.logStack = new LogStack(logger);
this.napi2nativeLoader = napi2nativeLoader;
this._client = this.newClient(); this._client = this.newClient();
} }
@@ -64,14 +67,14 @@ export class PacketClientContext {
await this._client.init(pid, recv, send); await this._client.init(pid, recv, send);
} }
async sendOidbPacket<T extends boolean = false>(pkt: OidbPacket, rsp?: T, timeout?: number): Promise<T extends true ? Buffer : void> { async sendOidbPacket<T extends boolean = false> (pkt: OidbPacket, rsp?: T, timeout?: number): Promise<T extends true ? Buffer : void> {
const raw = await this._client.sendOidbPacket(pkt, rsp, timeout); const raw = await this._client.sendOidbPacket(pkt, rsp, timeout);
return raw.data as T extends true ? Buffer : void; return raw.data as T extends true ? Buffer : void;
} }
private newClient (): NativePacketClient { private newClient (): NativePacketClient {
this.logger.info('使用 NativePacketClient 作为后端'); this.logger.info('使用 NativePacketClient 作为后端');
const client = new NativePacketClient(this.napCore, this.logger, this.logStack); const client = new NativePacketClient(this.napCore, this.logger, this.logStack, this.napi2nativeLoader);
if (!client.check()) { if (!client.check()) {
throw new Error('[Core] [Packet] NativePacketClient 不可用NapCat.Packet将不会加载'); throw new Error('[Core] [Packet] NativePacketClient 不可用NapCat.Packet将不会加载');
} }

View File

@@ -34,5 +34,9 @@ export class NapCoreContext {
return this.core.configLoader.configData; return this.core.configLoader.configData;
} }
get napi2nativeLoader () {
return this.core.context.napi2nativeLoader;
}
sendSsoCmdReqByContend = (cmd: string, data: Buffer) => this.core.context.session.getMsgService().sendSsoCmdReqByContend(cmd, data); sendSsoCmdReqByContend = (cmd: string, data: Buffer) => this.core.context.session.getMsgService().sendSsoCmdReqByContend(cmd, data);
} }

View File

@@ -18,7 +18,7 @@ export class PacketContext {
this.msgConverter = new PacketMsgConverter(); this.msgConverter = new PacketMsgConverter();
this.napcore = new NapCoreContext(core); this.napcore = new NapCoreContext(core);
this.logger = new PacketLogger(this.napcore); this.logger = new PacketLogger(this.napcore);
this.client = new PacketClientContext(this.napcore, this.logger); this.client = new PacketClientContext(this.napcore, this.logger, this.napcore.napi2nativeLoader);
this.highway = new PacketHighwayContext(this.napcore, this.logger, this.client); this.highway = new PacketHighwayContext(this.napcore, this.logger, this.client);
this.operation = new PacketOperationContext(this); this.operation = new PacketOperationContext(this);
} }

View File

@@ -0,0 +1,81 @@
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import { constants } from 'node:os';
import { LogWrapper } from '../../helper/log';
export interface Napi2NativeExportType {
initHook?: (send: string, recv: string) => boolean;
setVerbose?: (verbose: boolean) => void; // 默认关闭日志
enableAllBypasses?: () => void;
}
export class Napi2NativeLoader {
private readonly supportedPlatforms = ['win32.x64', 'linux.x64', 'linux.arm64', 'darwin.x64', 'darwin.arm64'];
private readonly exports: { exports: Napi2NativeExportType; } = { exports: {} };
protected readonly logger: LogWrapper;
private _loaded: boolean = false;
constructor ({ logger }: { logger: LogWrapper; }) {
this.logger = logger;
this.load();
}
private load (): void {
const platform = process.platform + '.' + process.arch;
if (!this.supportedPlatforms.includes(platform)) {
this.logger.logWarn(`Napi2NativeLoader: 不支持的平台: ${platform}`);
this._loaded = false;
return;
}
const nativeModulePath = path.join(
dirname(fileURLToPath(import.meta.url)),
'./native/napi2native/napi2native.' + platform + '.node'
);
if (!fs.existsSync(nativeModulePath)) {
this.logger.logWarn(`Napi2NativeLoader: 缺失运行时文件: ${nativeModulePath}`);
this._loaded = false;
return;
}
try {
process.dlopen(this.exports, nativeModulePath, constants.dlopen.RTLD_LAZY);
this._loaded = true;
this.logger.log('[Napi2NativeLoader] 加载成功');
} catch (error) {
this.logger.logError('Napi2NativeLoader 加载出错:', error);
this._loaded = false;
}
}
get loaded (): boolean {
return this._loaded;
}
get nativeExports (): Napi2NativeExportType {
return this.exports.exports;
}
/**
* 初始化 Hook
* @param send send 偏移地址
* @param recv recv 偏移地址
* @returns 是否初始化成功
*/
initHook (send: string, recv: string): boolean {
if (!this._loaded) {
this.logger.logWarn('Napi2NativeLoader 未成功加载,无法初始化 Hook');
return false;
}
try {
return this.nativeExports.initHook?.(send, recv) ?? false;
} catch (error) {
this.logger.logError('Napi2NativeLoader initHook 出错:', error);
return false;
}
}
}

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelAVSDKService {
addKernelAVSDKListener (listener: unknown): number;
removeKernelAVSDKListener (listenerId: number): void;
isNull (): boolean;
}

View File

@@ -0,0 +1,15 @@
export interface NodeIKernelAddBuddyService {
addBuddy (arg1: string, arg2: unknown, arg3: unknown): unknown;
getAddBuddyRequestTag (arg1: string, arg2: unknown, arg3: unknown): unknown;
getBuddySetting (arg1: string, arg2: unknown, arg3: unknown): unknown;
getSmartInfo (arg1: string, arg2: unknown, arg3: unknown): unknown;
queryUinSafetyFlag (arg1: string, arg2: unknown, arg3: unknown): unknown;
requestInfoByAccount (arg1: string, arg2: unknown, arg3: unknown): unknown;
isNull (): boolean;
}

View File

@@ -2,17 +2,17 @@ import { AlbumCommentReplyContent, AlbumFeedLikePublish, AlbumListRequest, Album
export interface NodeIKernelAlbumService { export interface NodeIKernelAlbumService {
setAlbumServiceInfo(...args: unknown[]): unknown;// needs 3 arguments setAlbumServiceInfo (arg1: string, arg2: string, arg3: string): unknown;// needs 3 arguments
getMainPage(...args: unknown[]): unknown;// needs 2 arguments getMainPage (arg1: unknown, arg2: unknown): unknown;// needs 2 arguments
getAlbumList(params: { getAlbumList (params: {
qun_id: string, qun_id: string,
attach_info: string, attach_info: string,
seq: number, seq: number,
request_time_line: { request_time_line: {
request_invoke_time: string request_invoke_time: string;
} };
}): Promise<{ }): Promise<{
response: { response: {
seq: number, seq: number,
@@ -21,57 +21,57 @@ export interface NodeIKernelAlbumService {
trace_id: string, trace_id: string,
is_from_cache: boolean, is_from_cache: boolean,
request_time_line: unknown, request_time_line: unknown,
album_list: Array<{ name: string, album_id: string }>, album_list: Array<{ name: string, album_id: string; }>,
attach_info: string, attach_info: string,
has_more: boolean, has_more: boolean,
right: unknown, right: unknown,
banner: unknown banner: unknown;
} };
}> }>;
getAlbumInfo(...args: unknown[]): unknown;// needs 1 arguments getAlbumInfo (arg: unknown): unknown;// needs 1 arguments
deleteAlbum(...args: unknown[]): unknown;// needs 3 arguments deleteAlbum (arg1: number, arg2: string, arg3: string): unknown;// needs 3 arguments
addAlbum(...args: unknown[]): unknown;// needs 2 arguments addAlbum (arg1: unknown, arg2: unknown): unknown;// needs 2 arguments
deleteMedias(seq: number, group_code: string, album_id: string, media_ids: string[], ban_ids: unknown[]): Promise<unknown>;// needs 4 arguments deleteMedias (seq: number, group_code: string, album_id: string, media_ids: string[], ban_ids: unknown[]): Promise<unknown>;// needs 4 arguments
modifyAlbum(...args: unknown[]): unknown;// needs 3 arguments modifyAlbum (arg1: number, arg2: unknown, arg3: Array<unknown>[]): unknown;// needs 3 arguments
getMediaList(param: AlbumListRequest): Promise<{ getMediaList (param: AlbumListRequest): Promise<{
response: { response: {
seq: number, seq: number,
result: number, result: number,
errMs: string, // 没错就是errMs不是errMsg errMs: string, // 没错就是errMs不是errMsg
trace_id: string, trace_id: string,
request_time_line: unknown, request_time_line: unknown,
} };
}>;// needs 1 arguments }>;// needs 1 arguments
quoteToQzone(...args: unknown[]): unknown;// needs 1 arguments quoteToQzone (arg: unknown): unknown;// needs 1 arguments
quoteToQunAlbum(...args: unknown[]): unknown;// needs 1 arguments quoteToQunAlbum (arg: unknown): unknown;// needs 1 arguments
queryQuoteToQunAlbumStatus(...args: unknown[]): unknown;// needs 1 arguments queryQuoteToQunAlbumStatus (arg: unknown): unknown;// needs 1 arguments
getQunFeeds(...args: unknown[]): unknown;// needs 1 arguments getQunFeeds (arg: unknown): unknown;// needs 1 arguments
getQunFeedDetail(...args: unknown[]): unknown;// needs 1 arguments getQunFeedDetail (arg: unknown): unknown;// needs 1 arguments
getQunNoticeList(...args: unknown[]): unknown;// needs 4 arguments getQunNoticeList (arg1: number, arg2: unknown, arg3: string, arg4: string): unknown;// needs 4 arguments
getQunComment(...args: unknown[]): unknown;// needs 1 arguments getQunComment (arg: unknown): unknown;// needs 1 arguments
getQunLikes(...args: unknown[]): unknown;// needs 4 arguments getQunLikes (arg1: number, arg2: unknown, arg3: string, arg4: string): unknown;// needs 4 arguments
deleteQunFeed(...args: unknown[]): unknown;// needs 1 arguments deleteQunFeed (arg: unknown): unknown;// needs 1 arguments
// seq random // seq random
// stCommonExt {"map_info":[],"map_bytes_info":[],"map_user_account":[]} // stCommonExt {"map_info":[],"map_bytes_info":[],"map_user_account":[]}
// qunId string // qunId string
doQunComment(seq: number, ext: { doQunComment (seq: number, ext: {
map_info: unknown[], map_info: unknown[],
map_bytes_info: unknown[], map_bytes_info: unknown[],
map_user_account: unknown[] map_user_account: unknown[];
}, },
qunId: string, qunId: string,
commentType: number, commentType: number,
@@ -79,23 +79,23 @@ export interface NodeIKernelAlbumService {
content: AlbumCommentReplyContent, content: AlbumCommentReplyContent,
): Promise<unknown>;// needs 6 arguments ): Promise<unknown>;// needs 6 arguments
doQunReply(...args: unknown[]): unknown;// needs 7 arguments doQunReply (arg1: number, arg2: unknown, arg3: string, arg4: number, arg5: unknown, arg6: unknown, arg7: unknown): unknown;// needs 7 arguments
doQunLike( doQunLike (
seq: number, seq: number,
ext: { ext: {
map_info: unknown[], map_info: unknown[],
map_bytes_info: unknown[], map_bytes_info: unknown[],
map_user_account: unknown[] map_user_account: unknown[];
}, },
param: { param: {
// {"id":"421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|V5bCgAxMDEyOTU5MjU3e*KqaLVYdic!^||^421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|17560336594^||^1","status":1} // {"id":"421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|V5bCgAxMDEyOTU5MjU3e*KqaLVYdic!^||^421_1_0_1012959257|V61Yiali4PELg90bThrH4Bo2iI1M5Kab|17560336594^||^1","status":1}
id: string, id: string,
status: number status: number;
}, },
like: AlbumFeedLikePublish like: AlbumFeedLikePublish
): Promise<unknown>;// needs 5 arguments ): Promise<unknown>;// needs 5 arguments
getRedPoints(...args: unknown[]): unknown;// needs 3 arguments getRedPoints (arg1: string, arg2: number, arg3: string): unknown;// needs 3 arguments
} }

View File

@@ -13,13 +13,13 @@ export interface NodeIKernelAvatarService {
forceDownloadGroupAvatar(arg1: unknown, arg2: unknown): unknown; forceDownloadGroupAvatar(arg1: unknown, arg2: unknown): unknown;
getGroupPortraitPath(arg1: unknown, arg2: unknown, arg3: unknown): unknown; getGroupPortraitPath(arg1: string, arg2: number, arg3: number): unknown;
forceDownloadGroupPortrait(arg1: unknown, arg2: unknown, arg3: unknown): unknown; forceDownloadGroupPortrait(arg1: string, arg2: number, arg3: number): unknown;
getAvatarPaths(arg1: unknown, arg2: unknown): unknown; getAvatarPaths(arg1: Array<unknown>[], arg2: number): unknown;
getGroupAvatarPaths(arg1: unknown, arg2: unknown): unknown; getGroupAvatarPaths(arg1: Array<unknown>[], arg2: string): unknown;
getConfGroupAvatarPaths(arg: unknown): unknown; getConfGroupAvatarPaths(arg: unknown): unknown;

View File

@@ -0,0 +1,9 @@
export interface NodeIKernelBdhUploadService {
addKernelBdhUploadListener (listener: unknown): number;
removeKernelBdhUploadListener (listenerId: number): void;
setBdhTestEnv (arg1: string, arg2: number): unknown;
isNull (): boolean;
}

View File

@@ -130,5 +130,21 @@ export interface NodeIKernelBuddyService {
getBuddyRecommendContactArkJson (uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string; }>; getBuddyRecommendContactArkJson (uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string; }>;
checkIsBuddyAsync (uid: string): Promise<unknown>;
areBuddies (callFrom: string, uids: string[]): unknown;
getCategoryById (id: number): unknown;
addCategoryV2 (name: string, buddyUids?: unknown): Promise<unknown>;
isNull (): boolean; isNull (): boolean;
getAddFriendBlockedList (): unknown;
getAddFriendBlockedRedPoint (): unknown;
reportAddFriendBlocked (): unknown;
setWXMsgNotify (arg: unknown): unknown;
} }

View File

@@ -1,91 +1,91 @@
import { GeneralCallResult } from './common'; import { GeneralCallResult } from './common';
export interface NodeIKernelCollectionService { export interface NodeIKernelCollectionService {
addKernelCollectionListener(...args: unknown[]): void;// needs 1 arguments addKernelCollectionListener (listener: unknown): void;// needs 1 arguments
removeKernelCollectionListener(listenerId: number): void; removeKernelCollectionListener (listenerId: number): void;
getCollectionItemList(param: { getCollectionItemList (param: {
category: number, category: number,
groupId: number, groupId: number,
forceSync: boolean, forceSync: boolean,
forceFromDb: boolean, forceFromDb: boolean,
timeStamp: string, timeStamp: string,
count: number, count: number,
searchDown: boolean searchDown: boolean;
}): Promise<GeneralCallResult & }): Promise<GeneralCallResult &
{ {
collectionSearchList: { collectionSearchList: {
collectionItemList: Array< collectionItemList: Array<
{ {
cid: string, cid: string,
type: number, type: number,
status: number, status: number,
author: { author: {
type: number, type: number,
numId: string, numId: string,
strId: string, strId: string,
groupId: string, groupId: string,
groupName: string, groupName: string,
uid: string uid: string;
}, },
bid: number, bid: number,
category: number, category: number,
createTime: string, createTime: string,
collectTime: string, collectTime: string,
modifyTime: string, modifyTime: string,
sequence: string, sequence: string,
shareUrl: string, shareUrl: string,
customGroupId: number, customGroupId: number,
securityBeat: boolean, securityBeat: boolean,
summary: { summary: {
textSummary: unknown, textSummary: unknown,
linkSummary: unknown, linkSummary: unknown,
gallerySummary: unknown, gallerySummary: unknown,
audioSummary: unknown, audioSummary: unknown,
videoSummary: unknown, videoSummary: unknown,
fileSummary: unknown, fileSummary: unknown,
locationSummary: unknown, locationSummary: unknown,
richMediaSummary: unknown, richMediaSummary: unknown,
} };
}>, }>,
hasMore: boolean, hasMore: boolean,
bottomTimeStamp: string bottomTimeStamp: string;
} };
} }
>; >;
getCollectionContent(...args: unknown[]): unknown;// needs 5 arguments getCollectionContent (arg1: string, arg2: number, arg3: string, arg4: string, arg5: boolean): unknown;// needs 5 arguments
getCollectionCustomGroupList(...args: unknown[]): unknown;// needs 0 arguments getCollectionCustomGroupList (): unknown;// needs 0 arguments
getCollectionUserInfo(...args: unknown[]): unknown;// needs 0 arguments getCollectionUserInfo (): unknown;// needs 0 arguments
searchCollectionItemList(...args: unknown[]): unknown;// needs 2 arguments searchCollectionItemList (arg1: string, arg2: unknown): unknown;// needs 2 arguments
addMsgToCollection(...args: unknown[]): unknown;// needs 2 arguments addMsgToCollection (arg1: unknown, arg2: unknown): unknown;// needs 2 arguments
collectionArkShare(...args: unknown[]): unknown;// needs 1 arguments collectionArkShare (arg: unknown): unknown;// needs 1 arguments
collectionFileForward(...args: unknown[]): unknown;// needs 3 arguments collectionFileForward (arg1: number, arg2: string, arg3: unknown): unknown;// needs 3 arguments
downloadCollectionFile(...args: unknown[]): unknown;// needs 4 arguments downloadCollectionFile (arg1: string, arg2: string, arg3: unknown, arg4: string): unknown;// needs 4 arguments
downloadCollectionFileThumbPic(...args: unknown[]): unknown;// needs 4 arguments downloadCollectionFileThumbPic (arg1: string, arg2: string, arg3: unknown, arg4: number): unknown;// needs 4 arguments
downloadCollectionPic(...args: unknown[]): unknown;// needs 3 arguments downloadCollectionPic (arg1: string, arg2: string, arg3: unknown): unknown;// needs 3 arguments
cancelDownloadCollectionFile(...args: unknown[]): unknown;// needs 1 arguments cancelDownloadCollectionFile (arg: unknown): unknown;// needs 1 arguments
deleteCollectionItemList(...args: unknown[]): unknown;// needs 1 arguments deleteCollectionItemList (arg: unknown): unknown;// needs 1 arguments
editCollectionItem(...args: unknown[]): unknown;// needs 2 arguments editCollectionItem (arg1: unknown, arg2: unknown): unknown;// needs 2 arguments
getEditPicInfoByPath(...args: unknown[]): unknown;// needs 1 arguments getEditPicInfoByPath (arg: unknown): unknown;// needs 1 arguments
collectionFastUpload(...args: unknown[]): unknown;// needs 1 arguments collectionFastUpload (arg: unknown): unknown;// needs 1 arguments
editCollectionItemAfterFastUpload(...args: unknown[]): unknown;// needs 2 arguments editCollectionItemAfterFastUpload (arg1: unknown, arg2: unknown): unknown;// needs 2 arguments
createNewCollectionItem(...args: unknown[]): unknown;// needs 1 arguments createNewCollectionItem (arg: unknown): unknown;// needs 1 arguments
} }

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelConfigMgrService {
addKernelConfigMgrListener (listener: unknown): number;
removeKernelConfigMgrListener (listenerId: number): void;
isNull (): boolean;
}

View File

@@ -1,9 +1,9 @@
export interface NodeIKernelDbToolsService { export interface NodeIKernelDbToolsService {
depositDatabase(...args: unknown[]): unknown; depositDatabase (arg: unknown): unknown;
backupDatabase(...args: unknown[]): unknown; backupDatabase (arg: unknown): unknown;
retrieveDatabase(...args: unknown[]): unknown; retrieveDatabase (arg: unknown): unknown;
} }

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelDirectSessionService {
addKernelDirectSessionListener (listener: unknown): number;
removeKernelDirectSessionListener (listenerId: number): void;
isNull (): boolean;
}

View File

@@ -1,3 +1,13 @@
export interface NodeIKernelECDHService { export interface NodeIKernelECDHService {
sendOIDBECRequest: (data: Uint8Array) => Promise<Uint8Array>; sendOIDBECRequest: (data: Uint8Array) => Promise<Uint8Array>;
init (): unknown;
setIsDebug (isDebug: boolean): unknown;
setGuid (guid: string): unknown;
sendOIDBRequest (cmd: number, serviceType: number, subCmd: number, data: string, extraData: unknown): Promise<unknown>;
sendSSORequest (cmd: string, serviceType: number, data: string, extraData: unknown): Promise<unknown>;
} }

View File

@@ -0,0 +1,5 @@
export interface NodeIKernelEmojiService {
getAIGCEmojiList (arg1: unknown, arg2: boolean): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,19 @@
export interface NodeIKernelFeedService {
addKernelFeedListener (listener: unknown): number;
removeKernelFeedListener (listenerId: number): void;
getChannelDraft (arg1: string, arg2: number): unknown;
getFeedCount (arg: unknown): unknown;
getFeedLikeUserList (arg1: unknown, arg2: number): unknown;
getFeedRichMediaFilePath (arg1: number, arg2: string, arg3: string, arg4: number, arg5: boolean): unknown;
getJoinedRecommendItems (arg1: unknown, arg2: boolean): unknown;
setChannelDraft (arg1: string, arg2: string, arg3: number): unknown;
isNull (): boolean;
}

View File

@@ -1,37 +1,41 @@
import { NodeIKernelFileAssistantListener } from '@/napcat-core/index'; import { NodeIKernelFileAssistantListener } from '@/napcat-core/index';
export interface NodeIKernelFileAssistantService { export interface NodeIKernelFileAssistantService {
addKernelFileAssistantListener(listener: NodeIKernelFileAssistantListener): unknown; addKernelFileAssistantListener (listener: NodeIKernelFileAssistantListener): unknown;
removeKernelFileAssistantListener(arg1: unknown[]): unknown; removeKernelFileAssistantListener (arg1: unknown[]): unknown;
getFileAssistantList(arg1: unknown[]): unknown; getFileAssistantList (arg1: unknown[]): unknown;
getMoreFileAssistantList(arg1: unknown[]): unknown; getMoreFileAssistantList (arg1: unknown[]): unknown;
getFileSessionList(): unknown; getFileSessionList (): unknown;
searchFile(keywords: string[], params: { resultType: number, pageLimit: number }, resultId: number): number; searchFile (keywords: string[], params: { resultType: number, pageLimit: number; }, resultId: number): number;
resetSearchFileSortType(arg1: unknown, arg2: unknown, arg3: unknown): unknown; resetSearchFileSortType (arg1: number, arg2: number, arg3: number): unknown;
searchMoreFile(arg1: unknown[]): unknown; searchMoreFile (arg1: unknown[]): unknown;
cancelSearchFile(arg1: unknown, arg2: unknown, arg3: unknown): unknown; cancelSearchFile (arg1: number, arg2: number, arg3: string): unknown;
downloadFile(fileIds: string[]): { result: number, errMsg: string }; downloadFile (fileIds: string[]): { result: number, errMsg: string; };
forwardFile(arg1: unknown, arg2: unknown, arg3: unknown): unknown; forwardFile (arg1: unknown, arg2: unknown, arg3: unknown): unknown;
cancelFileAction(arg1: unknown[]): unknown; cancelFileAction (arg1: unknown[]): unknown;
retryFileAction(arg1: unknown[]): unknown; retryFileAction (arg1: unknown[]): unknown;
deleteFile(arg1: unknown[]): unknown; deleteFile (arg1: unknown[]): unknown;
saveAs(arg1: unknown, arg2: unknown): unknown; saveAs (arg1: unknown, arg2: unknown): unknown;
saveAsWithRename(arg1: unknown, arg2: unknown, arg3: unknown): unknown; saveAsWithRename (arg1: string, arg2: string, arg3: string): unknown;
isNull(): boolean; getFilePathCount (arg: unknown): unknown;
updateRecentOperateForMsg (arg: unknown): unknown;
isNull (): boolean;
} }

View File

@@ -0,0 +1,13 @@
export interface NodeIKernelFileBridgeClientService {
addKernelFileBridgeClientListener (listener: unknown): number;
removeKernelFileBridgeClientListener (listenerId: number): void;
getPageContent (arg1: boolean, arg2: string): unknown;
getThumbnail (arg1: boolean, arg2: string, arg3: unknown): unknown;
searchFolderForFiles (arg1: string, arg2: string, arg3: string): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelFileBridgeHostService {
addKernelFileBridgeHostListener (listener: unknown): number;
removeKernelFileBridgeHostListener (listenerId: number): void;
isNull (): boolean;
}

View File

@@ -24,13 +24,13 @@ export interface NodeIKernelFlashTransferService {
seq: number; seq: number;
}>; // 2 arg 重点 // 自动上传 }>; // 2 arg 重点 // 自动上传
createMergeShareTask (...args: unknown[]): unknown; // 2 arg createMergeShareTask (arg1: unknown, arg2: unknown): unknown; // 2 arg
updateFlashTransfer (...args: unknown[]): unknown; // 2 arg updateFlashTransfer (arg1: unknown, arg2: unknown): unknown; // 2 arg
getFileSetList (...args: unknown[]): unknown; // 1 arg getFileSetList (arg: unknown): unknown; // 1 arg
getFileSetListCount (...args: unknown[]): unknown; // 1 arg getFileSetListCount (arg: unknown): unknown; // 1 arg
/** /**
* 获取file set 的信息 * 获取file set 的信息
@@ -50,11 +50,11 @@ export interface NodeIKernelFlashTransferService {
rsp: FileListResponse; rsp: FileListResponse;
}>; // 1 arg 这个方法QQ有bug 并没有,是我参数有问题 }>; // 1 arg 这个方法QQ有bug 并没有,是我参数有问题
getDownloadedFileCount (...args: unknown[]): unknown; // 1 arg getDownloadedFileCount (arg: unknown): unknown; // 1 arg
getLocalFileList (...args: unknown[]): unknown; // 3 arg getLocalFileList (arg1: number, arg2: string, arg3: Array<unknown>[]): unknown; // 3 arg
batchRemoveUserFileSetHistory (...args: unknown[]): unknown; // 1 arg batchRemoveUserFileSetHistory (arg: unknown): unknown; // 1 arg
/** /**
* 获取分享链接 * 获取分享链接
@@ -73,26 +73,26 @@ export interface NodeIKernelFlashTransferService {
fileSetId: string; fileSetId: string;
}>; // 1 arg code == share code }>; // 1 arg code == share code
batchRemoveFile (...args: unknown[]): unknown; // 1 arg batchRemoveFile (arg: unknown): unknown; // 1 arg
checkUploadPathValid (...args: unknown[]): unknown; // 1 arg checkUploadPathValid (arg: unknown): unknown; // 1 arg
cleanFailedFiles (...args: unknown[]): unknown; // 2 arg cleanFailedFiles (arg1: number, arg2: Array<unknown>[]): unknown; // 2 arg
/** /**
* 暂停所有的任务 * 暂停所有的任务
*/ */
resumeAllUnfinishedTasks (): unknown; // 0 arg !! resumeAllUnfinishedTasks (): unknown; // 0 arg !!
addFileSetUploadListener (...args: unknown[]): unknown; // 1 arg addFileSetUploadListener (listener: unknown): unknown; // 1 arg
removeFileSetUploadListener (...args: unknown[]): unknown; // 1 arg removeFileSetUploadListener (listenerId: unknown): unknown; // 1 arg
/** /**
* 开始上传任务 适用于已暂停的 * 开始上传任务 适用于已暂停的
* @param fileSetId * @param fileSetId
*/ */
startFileSetUpload (fileSetId: string): void; // 1 arg 并不是新建任务,应该是暂停后的启动 startFileSetUpload (fileSetId: unknown): void; // 1 arg 并不是新建任务,应该是暂停后的启动
/** /**
* 结束,无法再次启动 * 结束,无法再次启动
@@ -110,27 +110,27 @@ export interface NodeIKernelFlashTransferService {
* 继续上传 * 继续上传
* @param args * @param args
*/ */
resumeFileSetUpload (...args: unknown[]): unknown; // 1 arg 继续 resumeFileSetUpload (fileSetId: unknown): unknown; // 1 arg 继续
pauseFileUpload (...args: unknown[]): unknown; // 1 arg pauseFileUpload (arg: unknown): unknown; // 1 arg
resumeFileUpload (...args: unknown[]): unknown; // 1 arg resumeFileUpload (arg: unknown): unknown; // 1 arg
stopFileUpload (...args: unknown[]): unknown; // 1 arg stopFileUpload (arg: unknown): unknown; // 1 arg
asyncGetThumbnailPath (...args: unknown[]): unknown; // 2 arg asyncGetThumbnailPath (arg1: unknown, arg2: unknown): unknown; // 2 arg
setDownLoadDefaultFileDir (...args: unknown[]): unknown; // 1 arg setDownLoadDefaultFileDir (dir: unknown): unknown; // 1 arg
setFileSetDownloadDir (...args: unknown[]): unknown; // 2 arg setFileSetDownloadDir (arg1: unknown, arg2: unknown): unknown; // 2 arg
getFileSetDownloadDir (...args: unknown[]): unknown; // 1 arg getFileSetDownloadDir (arg: unknown): unknown; // 1 arg
setFlashTransferDir (...args: unknown[]): unknown; // 2 arg setFlashTransferDir (arg1: unknown, arg2: unknown): unknown; // 2 arg
addFileSetDownloadListener (...args: unknown[]): unknown; // 1 arg addFileSetDownloadListener (listener: unknown): unknown; // 1 arg
removeFileSetDownloadListener (...args: unknown[]): unknown; // 1 arg removeFileSetDownloadListener (listenerId: unknown): unknown; // 1 arg
/** /**
* 开始下载file set的函数 同开始上传 * 开始下载file set的函数 同开始上传
@@ -154,13 +154,13 @@ export interface NodeIKernelFlashTransferService {
extraInfo: 0; extraInfo: 0;
}>; // 2 arg }>; // 2 arg
startFileListDownLoad (...args: unknown[]): unknown; // 4 arg // 大概率是选择set里面的部分文件进行下载没必要不想写 startFileListDownLoad (arg1: string, arg2: number, arg3: Array<unknown>[], arg4: unknown): unknown; // 4 arg // 大概率是选择set里面的部分文件进行下载没必要不想写
pauseFileListDownLoad (...args: unknown[]): unknown; // 2 arg pauseFileListDownLoad (arg1: unknown, arg2: unknown): unknown; // 2 arg
resumeFileListDownLoad (...args: unknown[]): unknown; // 2 arg resumeFileListDownLoad (arg1: unknown, arg2: unknown): unknown; // 2 arg
stopFileListDownLoad (...args: unknown[]): unknown; // 2 arg stopFileListDownLoad (arg1: unknown, arg2: unknown): unknown; // 2 arg
startThumbnailListDownload (fileSetId: string): Promise<GeneralCallResult>; // 1 arg // 缩略图下载 startThumbnailListDownload (fileSetId: string): Promise<GeneralCallResult>; // 1 arg // 缩略图下载
@@ -174,31 +174,31 @@ export interface NodeIKernelFlashTransferService {
expireTimestampSeconds: string; expireTimestampSeconds: string;
}>; // 1 arg }>; // 1 arg
startFileListDownLoadBySessionId (...args: unknown[]): unknown; // 2 arg startFileListDownLoadBySessionId (arg1: unknown, arg2: unknown): unknown; // 2 arg
addFileSetSimpleStatusListener (...args: unknown[]): unknown; // 2 arg addFileSetSimpleStatusListener (arg1: unknown, arg2: unknown): unknown; // 2 arg
addFileSetSimpleStatusMonitoring (...args: unknown[]): unknown; // 2 arg addFileSetSimpleStatusMonitoring (arg1: unknown, arg2: unknown): unknown; // 2 arg
removeFileSetSimpleStatusMonitoring (...args: unknown[]): unknown; // 2 arg removeFileSetSimpleStatusMonitoring (arg1: unknown, arg2: unknown): unknown; // 2 arg
removeFileSetSimpleStatusListener (...args: unknown[]): unknown; // 1 arg removeFileSetSimpleStatusListener (arg: unknown): unknown; // 1 arg
addDesktopFileSetSimpleStatusListener (...args: unknown[]): unknown; // 1 arg addDesktopFileSetSimpleStatusListener (arg: unknown): unknown; // 1 arg
addDesktopFileSetSimpleStatusMonitoring (...args: unknown[]): unknown; // 1 arg addDesktopFileSetSimpleStatusMonitoring (arg: unknown): unknown; // 1 arg
removeDesktopFileSetSimpleStatusMonitoring (...args: unknown[]): unknown; // 1 arg removeDesktopFileSetSimpleStatusMonitoring (arg: unknown): unknown; // 1 arg
removeDesktopFileSetSimpleStatusListener (...args: unknown[]): unknown; // 1 arg removeDesktopFileSetSimpleStatusListener (arg: unknown): unknown; // 1 arg
addFileSetSimpleUploadInfoListener (...args: unknown[]): unknown; // 1 arg addFileSetSimpleUploadInfoListener (arg: unknown): unknown; // 1 arg
addFileSetSimpleUploadInfoMonitoring (...args: unknown[]): unknown; // 1 arg addFileSetSimpleUploadInfoMonitoring (arg: unknown): unknown; // 1 arg
removeFileSetSimpleUploadInfoMonitoring (...args: unknown[]): unknown; // 1 arg removeFileSetSimpleUploadInfoMonitoring (arg: unknown): unknown; // 1 arg
removeFileSetSimpleUploadInfoListener (...args: unknown[]): unknown; // 1 arg removeFileSetSimpleUploadInfoListener (arg: unknown): unknown; // 1 arg
/** /**
* 发送闪传消息 * 发送闪传消息
* @param sendArgs * @param sendArgs
@@ -211,9 +211,9 @@ export interface NodeIKernelFlashTransferService {
}; };
}>; // 1 arg 估计是file set id }>; // 1 arg 估计是file set id
addFlashTransferTaskInfoListener (...args: unknown[]): unknown; // 1 arg addFlashTransferTaskInfoListener (listener: unknown): unknown; // 1 arg
removeFlashTransferTaskInfoListener (...args: unknown[]): unknown; // 1 arg removeFlashTransferTaskInfoListener (listenerId: unknown): unknown; // 1 arg
retrieveLocalLastFailedSetTasksInfo (): unknown; // 0 arg retrieveLocalLastFailedSetTasksInfo (): unknown; // 0 arg
@@ -227,77 +227,77 @@ export interface NodeIKernelFlashTransferService {
}; };
}>; // 1 arg }>; // 1 arg
getLocalFileListByStatuses (...args: unknown[]): unknown; // 1 arg getLocalFileListByStatuses (arg: unknown): unknown; // 1 arg
addTransferStateListener (...args: unknown[]): unknown; // 1 arg addTransferStateListener (listener: unknown): unknown; // 1 arg
removeTransferStateListener (...args: unknown[]): unknown; // 1 arg removeTransferStateListener (listenerId: unknown): unknown; // 1 arg
getFileSetFirstClusteringList (...args: unknown[]): unknown; // 3 arg getFileSetFirstClusteringList (arg1: number, arg2: string, arg3: number): unknown; // 3 arg
getFileSetClusteringList (...args: unknown[]): unknown; // 1 arg getFileSetClusteringList (arg: unknown): unknown; // 1 arg
addFileSetClusteringListListener (...args: unknown[]): unknown; // 1 arg addFileSetClusteringListListener (listener: unknown): unknown; // 1 arg
removeFileSetClusteringListListener (...args: unknown[]): unknown; // 1 arg removeFileSetClusteringListListener (listenerId: unknown): unknown; // 1 arg
getFileSetClusteringDetail (...args: unknown[]): unknown; // 1 arg getFileSetClusteringDetail (arg: unknown): unknown; // 1 arg
doAIOFlashTransferBubbleActionWithStatus (...args: unknown[]): unknown; // 4 arg doAIOFlashTransferBubbleActionWithStatus (arg1: string, arg2: number, arg3: number, arg4: unknown): unknown; // 4 arg
getFilesTransferProgress (...args: unknown[]): unknown; // 1 arg getFilesTransferProgress (arg: unknown): unknown; // 1 arg
pollFilesTransferProgress (...args: unknown[]): unknown; // 1 arg pollFilesTransferProgress (arg: unknown): unknown; // 1 arg
cancelPollFilesTransferProgress (...args: unknown[]): unknown; // 1 arg cancelPollFilesTransferProgress (arg: unknown): unknown; // 1 arg
checkDownloadStatusBeforeLocalFileOper (...args: unknown[]): unknown; // 3 arg checkDownloadStatusBeforeLocalFileOper (arg1: number, arg2: string, arg3: string): unknown; // 3 arg
getCompressedFileFolder (...args: unknown[]): unknown; // 1 arg getCompressedFileFolder (arg: unknown): unknown; // 1 arg
addFolderListener (...args: unknown[]): unknown; // 1 arg addFolderListener (listener: unknown): unknown; // 1 arg
removeFolderListener (...args: unknown[]): unknown; removeFolderListener (listenerId: unknown): unknown;
addCompressedFileListener (...args: unknown[]): unknown; addCompressedFileListener (listener: unknown): unknown;
removeCompressedFileListener (...args: unknown[]): unknown; removeCompressedFileListener (listenerId: unknown): unknown;
getFileCategoryList (...args: unknown[]): unknown; getFileCategoryList (arg: unknown): unknown;
addDeviceStatusListener (...args: unknown[]): unknown; addDeviceStatusListener (listener: unknown): unknown;
removeDeviceStatusListener (...args: unknown[]): unknown; removeDeviceStatusListener (listenerId: unknown): unknown;
checkDeviceStatus (...args: unknown[]): unknown; checkDeviceStatus (arg: unknown): unknown;
pauseAllTasks (...args: unknown[]): unknown; // 2 arg pauseAllTasks (arg1: number, arg2: number): unknown; // 2 arg
resumePausedTasksAfterDeviceStatus (...args: unknown[]): unknown; resumePausedTasksAfterDeviceStatus (arg: unknown): unknown;
onSystemGoingToSleep (...args: unknown[]): unknown; onSystemGoingToSleep (arg: unknown): unknown;
onSystemWokeUp (...args: unknown[]): unknown; onSystemWokeUp (arg: unknown): unknown;
getFileMetas (...args: unknown[]): unknown; getFileMetas (arg: unknown): unknown;
addDownloadCntStatisticsListener (...args: unknown[]): unknown; addDownloadCntStatisticsListener (listener: unknown): unknown;
removeDownloadCntStatisticsListener (...args: unknown[]): unknown; removeDownloadCntStatisticsListener (listenerId: unknown): unknown;
detectPrivacyInfoInPaths (...args: unknown[]): unknown; detectPrivacyInfoInPaths (arg: unknown): unknown;
getFileThumbnailUrl (...args: unknown[]): unknown; getFileThumbnailUrl (arg: unknown): unknown;
handleDownloadFinishAfterSaveToAlbum (...args: unknown[]): unknown; handleDownloadFinishAfterSaveToAlbum (arg: unknown): unknown;
checkBatchFilesDownloadStatus (...args: unknown[]): unknown; checkBatchFilesDownloadStatus (arg: unknown): unknown;
onCheckAlbumStorageStatusResult (...args: unknown[]): unknown; onCheckAlbumStorageStatusResult (arg: unknown): unknown;
addFileAlbumStorageListener (...args: unknown[]): unknown; addFileAlbumStorageListener (listener: unknown): unknown;
removeFileAlbumStorageListener (...args: unknown[]): unknown; removeFileAlbumStorageListener (listenerId: unknown): unknown;
refreshFolderStatus (...args: unknown[]): unknown; refreshFolderStatus (arg: unknown): unknown;
} }

View File

@@ -16,29 +16,29 @@ import { GeneralCallResult } from '@/napcat-core/services/common';
export interface NodeIKernelGroupService { export interface NodeIKernelGroupService {
modifyGroupExtInfoV2(groupExtInfo: GroupExtInfo, groupExtFilter: GroupExtFilter): Promise<GeneralCallResult & modifyGroupExtInfoV2 (groupExtInfo: GroupExtInfo, groupExtFilter: GroupExtFilter): Promise<GeneralCallResult &
{ {
result: { result: {
groupCode: string, groupCode: string,
result: number result: number;
} };
}>; }>;
// ---> // --->
// 待启用 For Next Version 3.2.0 // 待启用 For Next Version 3.2.0
// isTroopMember ? 0 : 111 // isTroopMember ? 0 : 111
getGroupMemberMaxNum(groupCode: string, serviceType: number): Promise<unknown>; getGroupMemberMaxNum (groupCode: string, serviceType: number): Promise<unknown>;
getAllGroupPrivilegeFlag(troopUinList: string[], serviceType: number): Promise<unknown>; getAllGroupPrivilegeFlag (troopUinList: string[], serviceType: number): Promise<unknown>;
// <--- // <---
getGroupExt0xEF0Info(enableGroupCodes: string[], bannedGroupCodes: string[], filter: GroupExt0xEF0InfoFilter, forceFetch: boolean): getGroupExt0xEF0Info (enableGroupCodes: string[], bannedGroupCodes: string[], filter: GroupExt0xEF0InfoFilter, forceFetch: boolean):
Promise<GeneralCallResult & { result: { groupExtInfos: Map<string, unknown> } }>; Promise<GeneralCallResult & { result: { groupExtInfos: Map<string, unknown>; }; }>;
kickMemberV2(param: KickMemberV2Req): Promise<GeneralCallResult>; kickMemberV2 (param: KickMemberV2Req): Promise<GeneralCallResult>;
quitGroupV2(param: { groupCode: string; needDeleteLocalMsg: boolean; }): Promise<GeneralCallResult>; quitGroupV2 (param: { groupCode: string; needDeleteLocalMsg: boolean; }): Promise<GeneralCallResult>;
getMemberCommonInfo(Req: { getMemberCommonInfo (Req: {
groupCode: string, groupCode: string,
startUin: string, startUin: string,
identifyFlag: string, identifyFlag: string,
@@ -54,39 +54,39 @@ export interface NodeIKernelGroupService {
memberNum: number, memberNum: number,
filterMethod: string, filterMethod: string,
onlineFlag: string, onlineFlag: string,
realSpecialTitleFlag: number realSpecialTitleFlag: number;
}): Promise<unknown>; }): Promise<unknown>;
getGroupMemberLevelInfo(groupCode: string): Promise<unknown>; getGroupMemberLevelInfo (groupCode: string): Promise<unknown>;
getGroupInfoForJoinGroup(groupCode: string, needPrivilegeFlag: boolean, serviceType: number): Promise<unknown>; getGroupInfoForJoinGroup (groupCode: string, needPrivilegeFlag: boolean, serviceType: number): Promise<unknown>;
getGroupHonorList(req: { groupCodes: Array<string> }): Promise<unknown>; getGroupHonorList (req: { groupCodes: Array<string>; }): Promise<unknown>;
getUinByUids(uins: string[]): Promise<{ getUinByUids (uins: string[]): Promise<{
errCode: number, errCode: number,
errMsg: string, errMsg: string,
uins: Map<string, string> uins: Map<string, string>;
}>; }>;
getUidByUins(uins: string[]): Promise<{ getUidByUins (uins: string[]): Promise<{
errCode: number, errCode: number,
errMsg: string, errMsg: string,
uids: Map<string, string> uids: Map<string, string>;
}>; }>;
checkGroupMemberCache(arrayList: Array<string>): Promise<unknown>; checkGroupMemberCache (arrayList: Array<string>): Promise<unknown>;
getGroupLatestEssenceList(groupCode: string): Promise<unknown>; getGroupLatestEssenceList (groupCode: string): Promise<unknown>;
shareDigest(Req: { shareDigest (Req: {
appId: string, appId: string,
appType: number, appType: number,
msgStyle: number, msgStyle: number,
recvUin: string, recvUin: string,
sendType: number, sendType: number,
clientInfo: { clientInfo: {
platform: number platform: number;
}, },
richMsg: { richMsg: {
usingArk: boolean, usingArk: boolean,
@@ -94,122 +94,122 @@ export interface NodeIKernelGroupService {
summary: string, summary: string,
url: string, url: string,
pictureUrl: string, pictureUrl: string,
brief: string brief: string;
} };
}): Promise<unknown>; }): Promise<unknown>;
isEssenceMsg(req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>; isEssenceMsg (req: { groupCode: string, msgRandom: number, msgSeq: number; }): Promise<unknown>;
queryCachedEssenceMsg(req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<{ items: Array<unknown> }>; queryCachedEssenceMsg (req: { groupCode: string, msgRandom: number, msgSeq: number; }): Promise<{ items: Array<unknown>; }>;
fetchGroupEssenceList(req: { fetchGroupEssenceList (req: {
groupCode: string, groupCode: string,
pageStart: number, pageStart: number,
pageLimit: number pageLimit: number;
}, Arg: unknown): Promise<unknown>; }, Arg: string): Promise<unknown>;
getAllMemberList(groupCode: string, forceFetch: boolean): Promise<{ getAllMemberList (groupCode: string, forceFetch: boolean): Promise<{
errCode: number, errCode: number,
errMsg: string, errMsg: string,
result: { result: {
ids: Array<{ ids: Array<{
uid: string, uid: string,
index: number// 0 index: number;// 0
}>, }>,
infos: Map<string, GroupMember>, infos: Map<string, GroupMember>,
finish: true, finish: true,
hasRobot: false hasRobot: false;
} };
}>; }>;
setHeader(uid: string, path: string): Promise<GeneralCallResult>; setHeader (uid: string, path: string): Promise<GeneralCallResult>;
addKernelGroupListener(listener: NodeIKernelGroupListener): number; addKernelGroupListener (listener: NodeIKernelGroupListener): number;
removeKernelGroupListener(listenerId: number): void; removeKernelGroupListener (listenerId: number): void;
createMemberListScene(groupCode: string, scene: string): string; createMemberListScene (groupCode: string, scene: string): string;
destroyMemberListScene(SceneId: string): void; destroyMemberListScene (SceneId: string): void;
getNextMemberList(sceneId: string, groupMemberInfoListId: { index: number, uid: string } | undefined, num: number): Promise<{ getNextMemberList (sceneId: string, groupMemberInfoListId: { index: number, uid: string; } | undefined, num: number): Promise<{
errCode: number, errCode: number,
errMsg: string, errMsg: string,
result: { ids: string[], infos: Map<string, GroupMember>, finish: boolean, hasRobot: boolean } result: { ids: string[], infos: Map<string, GroupMember>, finish: boolean, hasRobot: boolean; };
}>; }>;
getPrevMemberList(): unknown; getPrevMemberList (): unknown;
monitorMemberList(): unknown; monitorMemberList (): unknown;
searchMember(sceneId: string, keywords: string[]): unknown; searchMember (sceneId: string, keywords: string[]): unknown;
getMemberInfo(group_id: string, uids: string[], forceFetch: boolean): Promise<GeneralCallResult>; getMemberInfo (group_id: string, uids: string[], forceFetch: boolean): Promise<GeneralCallResult>;
kickMember(groupCode: string, memberUids: string[], refuseForever: boolean, kickReason: string): Promise<void>; kickMember (groupCode: string, memberUids: string[], refuseForever: boolean, kickReason: string): Promise<void>;
modifyMemberRole(groupCode: string, uid: string, role: NTGroupMemberRole): void; modifyMemberRole (groupCode: string, uid: string, role: NTGroupMemberRole): void;
modifyMemberCardName(groupCode: string, uid: string, cardName: string): void; modifyMemberCardName (groupCode: string, uid: string, cardName: string): void;
getTransferableMemberInfo(groupCode: string): unknown;// 获取整个群的 getTransferableMemberInfo (groupCode: string): unknown;// 获取整个群的
transferGroup(uid: string): void; transferGroup (uid: string): void;
getGroupList(force: boolean): Promise<GeneralCallResult>; getGroupList (force: boolean): Promise<GeneralCallResult>;
getGroupExtList(force: boolean): Promise<GeneralCallResult>; getGroupExtList (force: boolean): Promise<GeneralCallResult>;
getGroupDetailInfo(groupCode: string, groupInfoSource: GroupInfoSource): Promise<GeneralCallResult>; getGroupDetailInfo (groupCode: string, groupInfoSource: GroupInfoSource): Promise<GeneralCallResult>;
getMemberExtInfo(param: GroupExtParam): Promise<unknown>;// req getMemberExtInfo (param: GroupExtParam): Promise<unknown>;// req
getGroupAllInfo(groupId: string, sourceId: number): Promise<unknown>; getGroupAllInfo (groupId: string, sourceId: number): Promise<unknown>;
getDiscussExistInfo(): unknown; getDiscussExistInfo (): unknown;
getGroupConfMember(): unknown; getGroupConfMember (): unknown;
getGroupMsgMask(): unknown; getGroupMsgMask (): unknown;
getGroupPortrait(): void; getGroupPortrait (): void;
modifyGroupName(groupCode: string, groupName: string, isNormalMember: boolean): Promise<GeneralCallResult>; modifyGroupName (groupCode: string, groupName: string, isNormalMember: boolean): Promise<GeneralCallResult>;
modifyGroupRemark(groupCode: string, remark: string): Promise<GeneralCallResult>; modifyGroupRemark (groupCode: string, remark: string): Promise<GeneralCallResult>;
modifyGroupDetailInfo(groupCode: string, arg: unknown): void; modifyGroupDetailInfo (groupCode: string, arg: unknown): void;
// 第二个参数在大多数情况为0 设置群成员权限 例如上传群文件权限和群成员付费/加入邀请加入时为8 // 第二个参数在大多数情况为0 设置群成员权限 例如上传群文件权限和群成员付费/加入邀请加入时为8
modifyGroupDetailInfoV2(param: GroupDetailInfoV2Param, arg: number): Promise<GeneralCallResult>; modifyGroupDetailInfoV2 (param: GroupDetailInfoV2Param, arg: number): Promise<GeneralCallResult>;
setGroupMsgMask(groupCode: string, arg: unknown): void; setGroupMsgMask (groupCode: string, arg: unknown): void;
changeGroupShieldSettingTemp(groupCode: string, arg: unknown): void; changeGroupShieldSettingTemp (groupCode: string, arg: unknown): void;
inviteToGroup(arg: unknown): void; inviteToGroup (arg: unknown): void;
inviteMembersToGroup(args: unknown[]): void; inviteMembersToGroup (args: unknown[]): void;
inviteMembersToGroupWithMsg(args: unknown): void; inviteMembersToGroupWithMsg (args: unknown): void;
createGroup(arg: unknown): void; createGroup (arg: unknown): void;
createGroupWithMembers(arg: unknown): void; createGroupWithMembers (arg: unknown): void;
quitGroup(groupCode: string): void; quitGroup (groupCode: string): void;
destroyGroup(groupCode: string): void; destroyGroup (groupCode: string): void;
getSingleScreenNotifies(doubt: boolean, startSeq: string, count: number): Promise<GeneralCallResult>; getSingleScreenNotifies (doubt: boolean, startSeq: string, count: number): Promise<GeneralCallResult>;
clearGroupNotifies(groupCode: string): void; clearGroupNotifies (groupCode: string): void;
getGroupNotifiesUnreadCount(doubt: boolean): Promise<GeneralCallResult>; getGroupNotifiesUnreadCount (doubt: boolean): Promise<GeneralCallResult>;
clearGroupNotifiesUnreadCount(doubt: boolean): void; clearGroupNotifiesUnreadCount (doubt: boolean): void;
operateSysNotify( operateSysNotify (
doubt: boolean, doubt: boolean,
operateMsg: { operateMsg: {
operateType: NTGroupRequestOperateTypes, operateType: NTGroupRequestOperateTypes,
@@ -217,80 +217,277 @@ export interface NodeIKernelGroupService {
seq: string, seq: string,
type: GroupNotifyMsgType, type: GroupNotifyMsgType,
groupCode: string, groupCode: string,
postscript: string postscript: string;
} };
}): Promise<void>; }): Promise<void>;
setTop(groupCode: string, isTop: boolean): void; setTop (groupCode: string, isTop: boolean): void;
getGroupBulletin(groupCode: string): unknown; getGroupBulletin (groupCode: string): unknown;
deleteGroupBulletin(groupCode: string, seq: string, noticeId: string): void; deleteGroupBulletin (groupCode: string, seq: string, noticeId: string): void;
publishGroupBulletin(groupCode: string, pskey: string, data: unknown): Promise<GeneralCallResult>; publishGroupBulletin (groupCode: string, pskey: string, data: unknown): Promise<GeneralCallResult>;
publishInstructionForNewcomers(groupCode: string, arg: unknown): void; publishInstructionForNewcomers (groupCode: string, arg: unknown): void;
uploadGroupBulletinPic(groupCode: string, pskey: string, imagePath: string): Promise<GeneralCallResult & { uploadGroupBulletinPic (groupCode: string, pskey: string, imagePath: string): Promise<GeneralCallResult & {
errCode: number; errCode: number;
picInfo?: { picInfo?: {
id: string, id: string,
width: number, width: number,
height: number height: number;
} };
}>; }>;
downloadGroupBulletinRichMedia(groupCode: string): unknown; downloadGroupBulletinRichMedia (groupCode: string): unknown;
getGroupBulletinList(groupCode: string): unknown; getGroupBulletinList (groupCode: string): unknown;
getGroupStatisticInfo(groupCode: string): unknown; getGroupStatisticInfo (groupCode: string): unknown;
getGroupRemainAtTimes(groupCode: string): Promise<Omit<GeneralCallResult, 'result'> & { getGroupRemainAtTimes (groupCode: string): Promise<Omit<GeneralCallResult, 'result'> & {
errCode: number, errCode: number,
atInfo: { atInfo: {
canAtAll: boolean canAtAll: boolean;
RemainAtAllCountForUin: number RemainAtAllCountForUin: number;
RemainAtAllCountForGroup: number RemainAtAllCountForGroup: number;
atTimesMsg: string atTimesMsg: string;
canNotAtAllMsg: '' canNotAtAllMsg: '';
} };
}>; }>;
getJoinGroupNoVerifyFlag(groupCode: string): unknown; getJoinGroupNoVerifyFlag (groupCode: string): unknown;
getGroupArkInviteState(groupCode: string): unknown; getGroupArkInviteState (groupCode: string): unknown;
reqToJoinGroup(groupCode: string, arg: unknown): void; reqToJoinGroup (groupCode: string, arg: unknown): void;
setGroupShutUp(groupCode: string, shutUp: boolean): Promise<GeneralCallResult>; setGroupShutUp (groupCode: string, shutUp: boolean): Promise<GeneralCallResult>;
getGroupShutUpMemberList(groupCode: string): Promise<GeneralCallResult>; getGroupShutUpMemberList (groupCode: string): Promise<GeneralCallResult>;
setMemberShutUp(groupCode: string, memberTimes: { uid: string, timeStamp: number }[]): Promise<GeneralCallResult>; setMemberShutUp (groupCode: string, memberTimes: { uid: string, timeStamp: number; }[]): Promise<GeneralCallResult>;
getGroupRecommendContactArkJson(groupCode: string): Promise<GeneralCallResult & { arkJson: string }>; getGroupRecommendContactArkJson (groupCode: string): Promise<GeneralCallResult & { arkJson: string; }>;
getJoinGroupLink(param: { getJoinGroupLink (param: {
groupCode: string, groupCode: string,
srcId: number, // 73 srcId: number, // 73
needShortUrl: boolean, // true needShortUrl: boolean, // true
additionalParam: string// '' additionalParam: string;// ''
}): Promise<GeneralCallResult & { url?: string }>; }): Promise<GeneralCallResult & { url?: string; }>;
modifyGroupExtInfo(groupCode: string, arg: unknown): void; modifyGroupExtInfo (groupCode: string, arg: unknown): void;
addGroupEssence(param: { addGroupEssence (param: {
groupCode: string groupCode: string;
msgRandom: number, msgRandom: number,
msgSeq: number msgSeq: number;
}): Promise<unknown>; }): Promise<unknown>;
removeGroupEssence(param: { removeGroupEssence (param: {
groupCode: string groupCode: string;
msgRandom: number, msgRandom: number,
msgSeq: number msgSeq: number;
}): Promise<unknown>; }): Promise<unknown>;
isNull(): boolean; isNull (): boolean;
// --- Methods from IDA binary analysis ---
clearGroupNotifyLocalUnreadCount (groupCode: string, arg: number): unknown;
getCardAppList (groupCode: string, arg: boolean): unknown;
getGroupBulletinDetail (arg1: string, arg2: string, arg3: string, arg4: boolean): unknown;
getGroupBulletinReadUsers (arg1: string, arg2: string, arg3: string, arg4: number, arg5: number, arg6: number): unknown;
getGroupDetailInfoByFilter (arg1: unknown, arg2: number, arg3: number, arg4: boolean): unknown;
getGroupDetailInfoForMqq (arg1: string, arg2: number, arg3: number, arg4: boolean): unknown;
getMemberInfoForMqq (arg1: string, arg2: Array<unknown>[], arg3: boolean): unknown;
getMemberInfoForMqqV2 (arg1: string, arg2: Array<unknown>[], arg3: boolean, arg4: string): unknown;
getRecGroups (arg1: string, arg2: unknown, arg3: string): unknown;
getSingleScreenNotifiesV2 (arg1: boolean, arg2: string, arg3: number, arg4: number): unknown;
modifyWxNotifyStatus (arg1: string, arg2: number): unknown;
operateSpecialFocus (arg1: string, arg2: Array<unknown>[], arg3: number): unknown;
remindGroupBulletinRead (arg1: string, arg2: string, arg3: string): unknown;
transferGroupV2 (arg1: string, arg2: string, arg3: string): unknown;
operateSysNotifyV2 (arg1: unknown, arg2: unknown): Promise<unknown>;
getAllMemberListV2 (groupCode: string, arg: unknown): unknown;
createGroupV2 (arg1: unknown, arg2: unknown): unknown;
modifyGroupExtInfoV2 (groupExtInfo: GroupExtInfo, groupExtFilter: GroupExtFilter): Promise<GeneralCallResult & {
result: { groupCode: string, result: number; };
}>;
modifyGroupDetailInfoV2 (param: GroupDetailInfoV2Param, arg: number): Promise<GeneralCallResult>;
setGroupMsgMaskV2 (arg1: unknown, arg2: unknown): unknown;
getGroupSquareRedpointInfo (arg1: unknown, arg2: unknown): unknown;
getGroupSquareHomeHead (arg1: unknown, arg2: unknown): unknown;
getCapsuleApp (arg1: unknown, arg2: unknown): unknown;
getCapsuleAppPro (arg1: unknown, arg2: unknown): unknown;
getMemberInfoCache (arg1: unknown, arg2: unknown): unknown;
getGroupSecLevelInfo (arg1: unknown, arg2: unknown): unknown;
getSubGroupInfo (arg: unknown): unknown;
getSwitchStatusForEssenceMsg (arg: unknown): unknown;
getTeamUpDetail (arg: unknown): unknown;
getTeamUpList (arg: unknown): unknown;
getTeamUpMembers (arg: unknown): unknown;
getTeamUpTemplateList (arg: unknown): unknown;
getTopicPage (arg1: string, arg2: string, arg3: string, arg4: string): unknown;
getTopicRecall (arg: unknown): unknown;
getWxNotifyStatus (arg: unknown): unknown;
getGroupPayToJoinStatus (arg: unknown): unknown;
getGroupSeqAndJoinTimeForGrayTips (arg: unknown): unknown;
getGroupTagRecords (arg: unknown): unknown;
getGroupBindGuilds (arg: unknown): unknown;
getGroupFlagForThirdApp (arg: unknown): unknown;
getGroupMsgLimitFreq (arg: unknown): unknown;
getGroupMedalList (arg: unknown): unknown;
getGroupDBVersion (arg: unknown): unknown;
getGroupInviteNoAuthLimitNum (arg: unknown): unknown;
getAIOBindGuildInfo (arg: unknown): unknown;
getAppCenter (arg: unknown): unknown;
getAICommonVoice (arg: unknown): unknown;
groupBlacklistDelApply (arg: unknown): unknown;
groupBlacklistGetAllApply (arg: unknown): unknown;
fetchGroupNotify (arg: unknown): unknown;
queryJoinGroupCanNoVerify (arg: unknown): unknown;
halfScreenPullNotice (arg: unknown): unknown;
halfScreenReportClick (arg: unknown): unknown;
joinGroup (arg: unknown): unknown;
listAllAIVoice (arg: unknown): unknown;
miniAppGetGroupInfo (arg: unknown): unknown;
postTeamUp (arg: unknown): unknown;
queryAIOBindGuild (arg: unknown): unknown;
removeGroupFromGroupList (arg: unknown): unknown;
saveAIVoice (arg: unknown): unknown;
setActiveExtGroup (arg: unknown): unknown;
setAIOBindGuild (arg: unknown): unknown;
setCapsuleSwitch (arg: unknown): unknown;
setGroupAppList (arg: unknown): unknown;
setGroupGeoInfo (arg: unknown): unknown;
setGroupRelationToGuild (arg: unknown): unknown;
setRcvJoinVerifyMsg (arg: unknown): unknown;
teamUpCreateGroup (arg: unknown): unknown;
teamUpInviteToGroup (arg: unknown): unknown;
teamUpRequestToJoin (arg: unknown): unknown;
teamUpSubmitDeadline (arg: unknown): unknown;
topicFeedback (arg: unknown): unknown;
topicReport (arg: unknown): unknown;
shareTopic (arg: unknown): unknown;
unbindAllGuilds (arg: unknown): unknown;
updateGroupInfoByMqq (arg: unknown): unknown;
updateMemberInfoByMqq (arg: unknown): unknown;
updateTeamUp (arg: unknown): unknown;
applyTeamUp (arg: unknown): unknown;
deleteTeamUp (arg: unknown): unknown;
getFindPageRecommendGroup (arg: unknown): unknown;
getTransferableMemberInfo (groupCode: string): unknown;
createGroupProfileShare (arg: unknown): unknown;
destroyMemberListScene (sceneId: string): void;
clearGroupSquareRedpointCache (arg: unknown): unknown;
checkGroupMemberCache (arrayList: Array<string>): Promise<unknown>;
cleanCapsuleCache (arg: unknown): unknown;
downloadGroupBulletinRichMedia (groupCode: string): unknown;
kickMemberV2 (param: KickMemberV2Req): Promise<GeneralCallResult>;
destroyGroupV2 (arg: unknown): unknown;
quitGroupV2 (param: { groupCode: string; needDeleteLocalMsg: boolean; }): Promise<GeneralCallResult>;
inviteToGroupV2 (arg: unknown): unknown;
getGroupMsgMask (): unknown;
batchQueryCachedGroupDetailInfo (arg: unknown): unknown;
getGroupMemberLevelInfo (groupCode: string): Promise<unknown>;
getIllegalMemberList (arg: unknown): unknown;
getGroupRecommendContactArkJsonToWechat (arg: unknown): unknown;
} }

View File

@@ -0,0 +1,9 @@
export interface NodeIKernelGroupTabService {
addListener (listener: unknown): number;
removeListener (listenerId: number): void;
getGroupTab (arg1: unknown, arg2: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,15 @@
export interface NodeIKernelHandOffService {
addKernelHandOffListener (listener: unknown): number;
removeKernelHandOffListener (listenerId: number): void;
changeHandOffActivities (arg: unknown): unknown;
deleteRecentHandOffActivities (arg: unknown): unknown;
getHandOffActivities (arg: unknown): unknown;
sendCapsulePanelActivities (arg1: string, arg2: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,19 @@
export interface NodeIKernelLiteBusinessService {
addListener (listener: unknown): number;
removeListener (listenerId: number): void;
clearLiteBusiness (arg1: string, arg2: unknown): unknown;
clickLiteAction (arg1: unknown, arg2: unknown): unknown;
exposeLiteAction (arg1: unknown, arg2: unknown): unknown;
getLiteBusiness (arg1: string, arg2: unknown): unknown;
getRevealTofuAuthority (arg: unknown): unknown;
recentRevealExposure (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelLockService {
addKernelLockListener (listener: unknown): number;
removeKernelLockListener (listenerId: number): void;
isNull (): boolean;
}

View File

@@ -63,7 +63,9 @@ export interface QuickLoginResult {
export interface NodeIKernelLoginService { export interface NodeIKernelLoginService {
getMsfStatus: () => number; getMsfStatus: () => number;
setLoginMiscData (arg0: string, value: string): unknown; setLoginMiscData (key: string, value: string): unknown;
getLoginMiscData (key: string): Promise<GeneralCallResult & { value: string; }>;
getMachineGuid (): string; getMachineGuid (): string;
@@ -73,14 +75,12 @@ export interface NodeIKernelLoginService {
addKernelLoginListener (listener: NodeIKernelLoginListener): number; addKernelLoginListener (listener: NodeIKernelLoginListener): number;
removeKernelLoginListener (listener: number): void; removeKernelLoginListener (listenerId: number): void;
initConfig (config: LoginInitConfig): void; initConfig (config: LoginInitConfig): void;
getLoginMiscData (data: string): Promise<GeneralCallResult & { value: string; }>;
getLoginList (): Promise<{ getLoginList (): Promise<{
result: number, // 0是ok result: number,
LocalLoginInfoList: LoginListItem[]; LocalLoginInfoList: LoginListItem[];
}>; }>;
@@ -89,4 +89,32 @@ export interface NodeIKernelLoginService {
passwordLogin (param: PasswordLoginArgType): Promise<QuickLoginResult>; passwordLogin (param: PasswordLoginArgType): Promise<QuickLoginResult>;
getQRCodePicture (): boolean; getQRCodePicture (): boolean;
destroy (): unknown;
cancel (): unknown;
abortPolling (): unknown;
startPolling (): unknown;
deleteLoginInfo (arg: unknown): unknown;
isHasLoginInfo (uin: string): boolean;
loadNoLoginUnitedConfig (arg: unknown): unknown;
loginUnusualDevice (arg: unknown): unknown;
registerUnitedConfigPushGroupList (groupList: unknown): unknown;
resetLoginInfo (arg: unknown): unknown;
setAutoLogin (arg: unknown): unknown;
setRemerberPwd (remember: boolean): unknown;
online (): unknown;
offline (): unknown;
} }

View File

@@ -6,6 +6,9 @@ enum ProxyType {
} }
export interface NodeIKernelMSFService { export interface NodeIKernelMSFService {
getServerTime (): string; getServerTime (): string;
getMsfStatus (): number;
online (): unknown;
offline (): unknown;
setNetworkProxy (param: { setNetworkProxy (param: {
userName: string, userName: string,
userPwd: string, userPwd: string,
@@ -50,4 +53,5 @@ export interface NodeIKernelMSFService {
accountType: number, accountType: number,
transInfoMap: Map<string, unknown>; transInfoMap: Map<string, unknown>;
}): Promise<Buffer>; }): Promise<Buffer>;
onMsfPushForTesting (arg1: unknown, arg2: unknown): unknown;
} }

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelMiniAppService {
addKernelMiniAppListener (listener: unknown): number;
removeKernelMiniAppListener (listenerId: number): void;
isNull (): boolean;
}

View File

@@ -1,27 +1,27 @@
export interface NodeIKernelMsgBackupService { export interface NodeIKernelMsgBackupService {
addKernelMsgBackupListener(listener: unknown): number; addKernelMsgBackupListener (listener: unknown): number;
removeKernelMsgBackupListener(listenerId: number): void; removeKernelMsgBackupListener (listenerId: number): void;
getMsgBackupLocation(...args: unknown[]): unknown;// needs 0 arguments getMsgBackupLocation (): unknown;// needs 0 arguments
setMsgBackupLocation(...args: unknown[]): unknown;// needs 1 arguments setMsgBackupLocation (arg: unknown): unknown;// needs 1 arguments
requestMsgBackup(...args: unknown[]): unknown;// needs 0 arguments requestMsgBackup (): unknown;// needs 0 arguments
requestMsgRestore(...args: unknown[]): unknown;// needs 1 arguments requestMsgRestore (arg: unknown): unknown;// needs 1 arguments
requestMsgMigrate(...args: unknown[]): unknown;// needs 1 arguments requestMsgMigrate (arg: unknown): unknown;// needs 1 arguments
getLocalStorageBackup(...args: unknown[]): unknown;// needs 0 arguments getLocalStorageBackup (): unknown;// needs 0 arguments
deleteLocalBackup(...args: unknown[]): unknown;// needs 1 arguments deleteLocalBackup (arg: unknown): unknown;// needs 1 arguments
clearCache(...args: unknown[]): unknown;// needs 0 arguments clearCache (): unknown;// needs 0 arguments
start(...args: unknown[]): unknown;// needs 1 arguments start (arg: unknown): unknown;// needs 1 arguments
stop(...args: unknown[]): unknown;// needs 1 arguments stop (arg: unknown): unknown;// needs 1 arguments
pause(...args: unknown[]): unknown;// needs 2 arguments pause (arg1: unknown, arg2: unknown): unknown;// needs 2 arguments
} }

View File

@@ -1,7 +1,7 @@
import { ElementType, MessageElement, Peer, RawMessage, FileElement, SendMessageElement } from '@/napcat-core/types'; import { ElementType, MessageElement, Peer, RawMessage, FileElement, SendMessageElement, AvRecordElement, TofuRecordElement } from '@/napcat-core/types';
import { NodeIKernelMsgListener } from '@/napcat-core/listeners/NodeIKernelMsgListener'; import { NodeIKernelMsgListener } from '@/napcat-core/listeners/NodeIKernelMsgListener';
import { GeneralCallResult } from '@/napcat-core/services/common'; import { GeneralCallResult } from '@/napcat-core/services/common';
import { MsgReqType, QueryMsgsParams, TmpChatInfoApi } from '@/napcat-core/types/msg'; import { MsgReqType, QueryMsgsParams, TmpChatInfoApi, MsgTypeFilter, MsgIdentity, SgrpStreamParams, GrayTipJsonInfo, ForwardFileInfo, LocalGrayTipInfo, TokenInfo, BackGroundInfo } from '@/napcat-core/types/msg';
export interface NodeIKernelMsgService { export interface NodeIKernelMsgService {
buildMultiForwardMsg (req: { srcMsgIds: Array<string>, srcContact: Peer; }): Promise<GeneralCallResult & { rspInfo: { elements: unknown; }; }>; buildMultiForwardMsg (req: { srcMsgIds: Array<string>, srcContact: Peer; }): Promise<GeneralCallResult & { rspInfo: { elements: unknown; }; }>;
@@ -10,21 +10,21 @@ export interface NodeIKernelMsgService {
addKernelMsgListener (nodeIKernelMsgListener: NodeIKernelMsgListener): number; addKernelMsgListener (nodeIKernelMsgListener: NodeIKernelMsgListener): number;
sendMsg (msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<unknown, unknown>): Promise<GeneralCallResult>; sendMsg (msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<number, unknown>): Promise<GeneralCallResult>;
recallMsg (peer: Peer, msgIds: string[]): Promise<GeneralCallResult>; recallMsg (peer: Peer, msgIds: string[]): Promise<GeneralCallResult>;
addKernelMsgImportToolListener (arg: unknown): unknown; addKernelMsgImportToolListener (listener: unknown): string;
removeKernelMsgListener (args: unknown): unknown; removeKernelMsgListener (listenerId: string): void;
addKernelTempChatSigListener (...args: unknown[]): unknown; addKernelTempChatSigListener (listener: unknown): string;
removeKernelTempChatSigListener (...args: unknown[]): unknown; removeKernelTempChatSigListener (listenerId: string): void;
setAutoReplyTextList (AutoReplyText: Array<unknown>, i2: number): unknown; setAutoReplyTextList (AutoReplyText: Array<unknown>, i2: number): unknown;
getAutoReplyTextList (...args: unknown[]): unknown; getAutoReplyTextList (): unknown;
getOnLineDev (): void; getOnLineDev (): void;
@@ -52,85 +52,85 @@ export interface NodeIKernelMsgService {
downloadOnlineStatusCommonByUrl (arg0: string, arg1: string): unknown; downloadOnlineStatusCommonByUrl (arg0: string, arg1: string): unknown;
setToken (arg: unknown): unknown; setToken (tokenInfo: TokenInfo): Promise<GeneralCallResult>;
switchForeGround (): unknown; switchForeGround (): unknown;
switchBackGround (arg: unknown): unknown; switchBackGround (info: BackGroundInfo): Promise<GeneralCallResult>;
setTokenForMqq (token: string): unknown; setTokenForMqq (token: string): unknown;
switchForeGroundForMqq (...args: unknown[]): unknown; switchForeGroundForMqq (data: string | Uint8Array): Promise<GeneralCallResult>;
switchBackGroundForMqq (...args: unknown[]): unknown; switchBackGroundForMqq (data: string | Uint8Array): Promise<GeneralCallResult>;
getMsgSetting (...args: unknown[]): unknown; getMsgSetting (): unknown;
setMsgSetting (...args: unknown[]): unknown; setMsgSetting (setting: unknown): unknown;
addSendMsg (...args: unknown[]): unknown; addSendMsg (msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<number, unknown>): unknown;
cancelSendMsg (peer: Peer, msgId: string): Promise<void>; cancelSendMsg (peer: Peer, msgId: string): Promise<void>;
switchToOfflineSendMsg (peer: Peer, MsgId: string): unknown; switchToOfflineSendMsg (peer: Peer, MsgId: string): unknown;
reqToOfflineSendMsg (...args: unknown[]): unknown; reqToOfflineSendMsg (peer: Peer, msgId: string): unknown;
refuseReceiveOnlineFileMsg (peer: Peer, MsgId: string): unknown; refuseReceiveOnlineFileMsg (peer: Peer, MsgId: string): unknown;
resendMsg (peer: Peer, msgId: string): Promise<void>; resendMsg (peer: Peer, msgId: string): Promise<void>;
recallMsg (...args: unknown[]): unknown; reeditRecallMsg (peer: Peer, msgId: string): unknown;
reeditRecallMsg (...args: unknown[]): unknown; forwardMsg (msgIds: string[], peer: Peer, dstPeers: Peer[], commentElements: unknown): Promise<GeneralCallResult>;
forwardMsg (...args: unknown[]): Promise<GeneralCallResult>; forwardMsgWithComment (msgIds: string[], srcContact: Peer, dstContacts: Peer[], commentElements: Array<unknown>, arg5: unknown): unknown;
forwardMsgWithComment (...args: unknown[]): unknown; forwardSubMsgWithComment (msgIds: string[], subMsgIds: string[], srcContact: Peer, dstContacts: Peer[], commentElements: Array<unknown>, arg6: unknown): unknown;
forwardSubMsgWithComment (...args: unknown[]): unknown; forwardRichMsgInVist (richMsgInfos: Array<unknown>, dstContacts: Peer[]): unknown;
forwardRichMsgInVist (...args: unknown[]): unknown; forwardFile (fileInfo: ForwardFileInfo, peer: Peer): unknown;
forwardFile (...args: unknown[]): unknown; multiForwardMsg (peer: Peer, srcContact: Peer, msgIds: string[]): unknown;
multiForwardMsg (...args: unknown[]): unknown; multiForwardMsgWithComment (msgInfos: Array<unknown>, srcContact: Peer, dstContact: Peer, commentElements: Array<unknown>, arg5: unknown): unknown;
multiForwardMsgWithComment (...args: unknown[]): unknown; deleteRecallMsg (peer: Peer, msgId: string): unknown;
deleteRecallMsg (...args: unknown[]): unknown; deleteRecallMsgForLocal (peer: Peer, msgId: string): unknown;
deleteRecallMsgForLocal (...args: unknown[]): unknown; addLocalGrayTipMsg (peer: Peer, grayTipInfo: LocalGrayTipInfo, isUnread: boolean): unknown;
addLocalGrayTipMsg (...args: unknown[]): unknown; addLocalJsonGrayTipMsg (arg1: Peer, arg2: GrayTipJsonInfo, arg3: boolean, arg4: boolean): unknown;
addLocalJsonGrayTipMsg (...args: unknown[]): unknown; addLocalJsonGrayTipMsgExt (arg1: Peer, arg2: MsgIdentity, arg3: GrayTipJsonInfo, arg4: boolean, arg5: boolean): unknown;
addLocalJsonGrayTipMsgExt (...args: unknown[]): unknown; IsLocalJsonTipValid (tipType: number): boolean;
IsLocalJsonTipValid (...args: unknown[]): unknown; addLocalAVRecordMsg (peer: Peer, avRecord: AvRecordElement): unknown;
addLocalAVRecordMsg (...args: unknown[]): unknown; addLocalTofuRecordMsg (peer: Peer, tofuRecord: TofuRecordElement): unknown;
addLocalTofuRecordMsg (...args: unknown[]): unknown;
addLocalRecordMsg (Peer: Peer, msgId: string, ele: MessageElement, attr: Array<unknown> | number, front: boolean): Promise<unknown>; addLocalRecordMsg (Peer: Peer, msgId: string, ele: MessageElement, attr: Array<unknown> | number, front: boolean): Promise<unknown>;
addLocalRecordMsgWithExtInfos (peer: Peer, msgId: string, extInfos: unknown): unknown;
deleteMsg (Peer: Peer, msgIds: Array<string>): Promise<unknown>; deleteMsg (Peer: Peer, msgIds: Array<string>): Promise<unknown>;
updateElementExtBufForUI (...args: unknown[]): unknown; updateElementExtBufForUI (arg1: Peer, arg2: string, arg3: string, arg4: string | Uint8Array): unknown;
updateMsgRecordExtPbBufForUI (...args: unknown[]): unknown; updateMsgRecordExtPbBufForUI (arg1: Peer, arg2: string, arg3: unknown): unknown;
startMsgSync (...args: unknown[]): unknown; startMsgSync (): unknown;
startGuildMsgSync (...args: unknown[]): unknown; startGuildMsgSync (): unknown;
isGuildChannelSync (...args: unknown[]): unknown; isGuildChannelSync (): unknown;
getMsgUniqueId (UniqueId: string): string; getMsgUniqueId (UniqueId: string): string;
isMsgMatched (...args: unknown[]): unknown; isMsgMatched (matchInfo: unknown): unknown;
getOnlineFileMsgs (peer: Peer): Promise<GeneralCallResult & { getOnlineFileMsgs (peer: Peer): Promise<GeneralCallResult & {
msgList: { msgList: {
@@ -147,7 +147,7 @@ export interface NodeIKernelMsgService {
}[]; // 一大坨,懒得写 }[]; // 一大坨,懒得写
}>; }>;
getAllOnlineFileMsgs (...args: unknown[]): unknown; getAllOnlineFileMsgs (): unknown;
getLatestDbMsgs (peer: Peer, cnt: number): Promise<GeneralCallResult & { getLatestDbMsgs (peer: Peer, cnt: number): Promise<GeneralCallResult & {
msgList: RawMessage[]; msgList: RawMessage[];
@@ -171,7 +171,7 @@ export interface NodeIKernelMsgService {
}>; }>;
// @deprecated // @deprecated
getMsgsWithMsgTimeAndClientSeqForC2C (...args: unknown[]): Promise<GeneralCallResult & { msgList: RawMessage[]; }>; getMsgsWithMsgTimeAndClientSeqForC2C (peer: Peer, arg2: string, arg3: string, arg4: number, arg5: boolean, arg6: boolean, arg7: boolean): Promise<GeneralCallResult & { msgList: RawMessage[]; }>;
getMsgsWithStatus (params: { getMsgsWithStatus (params: {
peer: Peer; peer: Peer;
@@ -186,6 +186,7 @@ export interface NodeIKernelMsgService {
getMsgsBySeqRange (peer: Peer, startSeq: string, endSeq: string): Promise<GeneralCallResult & { getMsgsBySeqRange (peer: Peer, startSeq: string, endSeq: string): Promise<GeneralCallResult & {
msgList: RawMessage[]; msgList: RawMessage[];
}>; }>;
// @deprecated // @deprecated
getMsgsBySeqAndCount (peer: Peer, seq: string, count: number, desc: boolean, isReverseOrder: boolean): Promise<GeneralCallResult & { getMsgsBySeqAndCount (peer: Peer, seq: string, count: number, desc: boolean, isReverseOrder: boolean): Promise<GeneralCallResult & {
msgList: RawMessage[]; msgList: RawMessage[];
@@ -211,19 +212,19 @@ export interface NodeIKernelMsgService {
getSourceOfReplyMsgByClientSeqAndTime (peer: Peer, clientSeq: string, time: string, replyMsgId: string): Promise<GeneralCallResult & { msgList: RawMessage[]; }>; getSourceOfReplyMsgByClientSeqAndTime (peer: Peer, clientSeq: string, time: string, replyMsgId: string): Promise<GeneralCallResult & { msgList: RawMessage[]; }>;
getMsgsByTypeFilter (peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilter: { getMsgsByTypeFilter (peer: Peer, msgId: string, cnt: Array<unknown>, queryOrder: boolean, typeFilter: {
type: number, type: number,
subtype: Array<number>; subtype: Array<number>;
}): Promise<GeneralCallResult & { msgList: RawMessage[]; }>; }): Promise<GeneralCallResult & { msgList: RawMessage[]; }>;
getMsgsByTypeFilters (peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilters: Array<{ getMsgsByTypeFilters (peer: Peer, msgId: string, cnt: number, queryOrder: boolean, typeFilters: Array<{
type: number, type: number,
subtype: Array<number>; subtype: Array<number>;
}>): Promise<GeneralCallResult & { msgList: RawMessage[]; }>; }>): Promise<GeneralCallResult & { msgList: RawMessage[]; }>;
getMsgWithAbstractByFilterParam (...args: unknown[]): Promise<GeneralCallResult & { msgList: RawMessage[]; }>; getMsgWithAbstractByFilterParam (arg1: Peer, arg2: string, arg3: string, arg4: number, arg5: MsgTypeFilter): Promise<GeneralCallResult & { msgList: RawMessage[]; }>;
queryMsgsWithFilter (...args: unknown[]): Promise<GeneralCallResult & { msgList: RawMessage[]; }>; queryMsgsWithFilter (msgId: string, msgTime: string, param: QueryMsgsParams): Promise<GeneralCallResult & { msgList: RawMessage[]; }>;
// queryMsgsWithFilterVer2(MsgId: string, MsgTime: string, param: QueryMsgsParams): Promise<unknown>; // queryMsgsWithFilterVer2(MsgId: string, MsgTime: string, param: QueryMsgsParams): Promise<unknown>;
@@ -235,11 +236,11 @@ export interface NodeIKernelMsgService {
msgList: RawMessage[]; msgList: RawMessage[];
}>; }>;
setMsgRichInfoFlag (...args: unknown[]): unknown; setMsgRichInfoFlag (flag: boolean): void;
queryPicOrVideoMsgs (msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): Promise<unknown>; queryPicOrVideoMsgs (msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): Promise<unknown>;
queryPicOrVideoMsgsDesktop (...args: unknown[]): unknown; queryPicOrVideoMsgsDesktop (msgId: string, msgTime: string, msgSeq: string, param: QueryMsgsParams): unknown;
queryEmoticonMsgs (msgId: string, msgTime: string, msgSeq: string, Params: QueryMsgsParams): Promise<unknown>; queryEmoticonMsgs (msgId: string, msgTime: string, msgSeq: string, Params: QueryMsgsParams): Promise<unknown>;
@@ -247,81 +248,81 @@ export interface NodeIKernelMsgService {
queryMsgsAndAbstractsWithFilter (msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): unknown; queryMsgsAndAbstractsWithFilter (msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): unknown;
setFocusOnGuild (...args: unknown[]): unknown; setFocusOnGuild (arg: unknown): unknown;
setFocusSession (...args: unknown[]): unknown; setFocusSession (arg: unknown): unknown;
enableFilterUnreadInfoNotify (...args: unknown[]): unknown; enableFilterUnreadInfoNotify (arg: unknown): unknown;
enableFilterMsgAbstractNotify (...args: unknown[]): unknown; enableFilterMsgAbstractNotify (arg: unknown): unknown;
onScenesChangeForSilenceMode (...args: unknown[]): unknown; onScenesChangeForSilenceMode (arg: unknown): unknown;
getContactUnreadCnt (...args: unknown[]): unknown; getContactUnreadCnt (peers: Peer[]): unknown;
getUnreadCntInfo (...args: unknown[]): unknown; getUnreadCntInfo (arg: unknown): unknown;
getGuildUnreadCntInfo (...args: unknown[]): unknown; getGuildUnreadCntInfo (arg: unknown): unknown;
getGuildUnreadCntTabInfo (...args: unknown[]): unknown; getGuildUnreadCntTabInfo (arg: unknown): unknown;
getAllGuildUnreadCntInfo (...args: unknown[]): unknown; getAllGuildUnreadCntInfo (arg: unknown): unknown;
getAllJoinGuildCnt (...args: unknown[]): unknown; getAllJoinGuildCnt (arg: unknown): unknown;
getAllDirectSessionUnreadCntInfo (...args: unknown[]): unknown; getAllDirectSessionUnreadCntInfo (arg: unknown): unknown;
getCategoryUnreadCntInfo (...args: unknown[]): unknown; getCategoryUnreadCntInfo (arg: unknown): unknown;
getGuildFeedsUnreadCntInfo (...args: unknown[]): unknown; getGuildFeedsUnreadCntInfo (arg: unknown): unknown;
setUnVisibleChannelCntInfo (...args: unknown[]): unknown; setUnVisibleChannelCntInfo (arg: unknown): unknown;
setUnVisibleChannelTypeCntInfo (...args: unknown[]): unknown; setUnVisibleChannelTypeCntInfo (arg: unknown): unknown;
setVisibleGuildCntInfo (...args: unknown[]): unknown; setVisibleGuildCntInfo (arg: unknown): unknown;
setMsgRead (peer: Peer): Promise<GeneralCallResult>; setMsgRead (peer: Peer): Promise<GeneralCallResult>;
setAllC2CAndGroupMsgRead (): Promise<unknown>; setAllC2CAndGroupMsgRead (): Promise<unknown>;
setGuildMsgRead (...args: unknown[]): unknown; setGuildMsgRead (arg: unknown): unknown;
setAllGuildMsgRead (...args: unknown[]): unknown; setAllGuildMsgRead (arg: unknown): unknown;
setMsgReadAndReport (...args: unknown[]): unknown; setMsgReadAndReport (peer: Peer, msg: RawMessage): unknown;
setSpecificMsgReadAndReport (...args: unknown[]): unknown; setSpecificMsgReadAndReport (arg1: Peer, arg2: string): unknown;
setLocalMsgRead (...args: unknown[]): unknown; setLocalMsgRead (peer: Peer): unknown;
setGroupGuildMsgRead (...args: unknown[]): unknown; setGroupGuildMsgRead (arg: unknown): unknown;
getGuildGroupTransData (...args: unknown[]): unknown; getGuildGroupTransData (arg: unknown): unknown;
setGroupGuildBubbleRead (...args: unknown[]): unknown; setGroupGuildBubbleRead (arg: unknown): unknown;
getGuildGroupBubble (...args: unknown[]): unknown; getGuildGroupBubble (arg: unknown): unknown;
fetchGroupGuildUnread (...args: unknown[]): unknown; fetchGroupGuildUnread (arg: unknown): unknown;
setGroupGuildFlag (...args: unknown[]): unknown; setGroupGuildFlag (arg: unknown): unknown;
setGuildUDCFlag (...args: unknown[]): unknown; setGuildUDCFlag (arg: unknown): unknown;
setGuildTabUserFlag (...args: unknown[]): unknown; setGuildTabUserFlag (arg: unknown): unknown;
setBuildMode (flag: number/* 0 1 3 */): unknown; setBuildMode (flag: number/* 0 1 3 */): unknown;
setConfigurationServiceData (...args: unknown[]): unknown; setConfigurationServiceData (arg: unknown): unknown;
setMarkUnreadFlag (...args: unknown[]): unknown; setMarkUnreadFlag (peer: Peer, unread: boolean): unknown;
getChannelEventFlow (...args: unknown[]): unknown; getChannelEventFlow (arg: unknown): unknown;
getMsgEventFlow (...args: unknown[]): unknown; getMsgEventFlow (arg: unknown): unknown;
getRichMediaFilePathForMobileQQSend (...args: unknown[]): unknown; getRichMediaFilePathForMobileQQSend (arg: unknown): unknown;
getRichMediaFilePathForGuild (arg: { getRichMediaFilePathForGuild (arg: {
md5HexStr: string, md5HexStr: string,
@@ -334,15 +335,15 @@ export interface NodeIKernelMsgService {
file_uuid: ''; file_uuid: '';
}): string; }): string;
assembleMobileQQRichMediaFilePath (...args: unknown[]): unknown; assembleMobileQQRichMediaFilePath (arg: unknown): unknown;
getFileThumbSavePathForSend (thumbSize: number, createNeed: boolean): string; getFileThumbSavePathForSend (thumbSize: number, createNeed: boolean): string;
getFileThumbSavePath (...args: unknown[]): unknown; getFileThumbSavePath (arg1: string, arg2: number, arg3: boolean): unknown;
translatePtt2Text (msgId: string, peer: Peer, msgElement: MessageElement): unknown; translatePtt2Text (msgId: string, peer: Peer, msgElement: MessageElement): unknown;
setPttPlayedState (...args: unknown[]): unknown; setPttPlayedState (arg1: string, arg2: Peer, arg3: string): unknown;
fetchFavEmojiList (str: string, num: number, backward: boolean, forceRefresh: boolean): Promise<GeneralCallResult & { fetchFavEmojiList (str: string, num: number, backward: boolean, forceRefresh: boolean): Promise<GeneralCallResult & {
emojiInfoList: Array<{ emojiInfoList: Array<{
@@ -368,49 +369,49 @@ export interface NodeIKernelMsgService {
}>; }>;
}>; }>;
addFavEmoji (...args: unknown[]): unknown; addFavEmoji (arg: unknown): unknown;
fetchMarketEmoticonList (...args: unknown[]): unknown; fetchMarketEmoticonList (arg1: number, arg2: number): unknown;
fetchMarketEmoticonShowImage (...args: unknown[]): unknown; fetchMarketEmoticonShowImage (arg: unknown): unknown;
fetchMarketEmoticonAioImage (...args: unknown[]): unknown; fetchMarketEmoticonAioImage (arg: unknown): unknown;
fetchMarketEmotionJsonFile (...args: unknown[]): unknown; fetchMarketEmotionJsonFile (arg: unknown): unknown;
getMarketEmoticonPath (...args: unknown[]): unknown; getMarketEmoticonPath (arg1: number, arg2: Array<unknown>[], arg3: number): unknown;
getMarketEmoticonPathBySync (...args: unknown[]): unknown; getMarketEmoticonPathBySync (arg1: number, arg2: Array<unknown>[], arg3: number): unknown;
fetchMarketEmoticonFaceImages (...args: unknown[]): unknown; fetchMarketEmoticonFaceImages (arg: unknown): unknown;
fetchMarketEmoticonAuthDetail (...args: unknown[]): unknown; fetchMarketEmoticonAuthDetail (arg: unknown): unknown;
getFavMarketEmoticonInfo (...args: unknown[]): unknown; getFavMarketEmoticonInfo (tabId: number, emojiId: string): unknown;
addRecentUsedFace (...args: unknown[]): unknown; addRecentUsedFace (arg: unknown): unknown;
getRecentUsedFaceList (...args: unknown[]): unknown; getRecentUsedFaceList (arg: unknown): unknown;
getMarketEmoticonEncryptKeys (...args: unknown[]): unknown; getMarketEmoticonEncryptKeys (arg1: number, arg2: Array<unknown>[]): unknown;
downloadEmojiPic (...args: unknown[]): unknown; downloadEmojiPic (arg1: number, arg2: Array<unknown>[], arg3: number, arg4: Map<unknown, unknown>): unknown;
deleteFavEmoji (...args: unknown[]): unknown; deleteFavEmoji (arg: unknown): unknown;
modifyFavEmojiDesc (...args: unknown[]): unknown; modifyFavEmojiDesc (arg: unknown): unknown;
queryFavEmojiByDesc (...args: unknown[]): unknown; queryFavEmojiByDesc (arg: unknown): unknown;
getHotPicInfoListSearchString (...args: unknown[]): unknown; getHotPicInfoListSearchString (arg1: string, arg2: string, arg3: number, arg4: number, arg5: boolean): unknown;
getHotPicSearchResult (...args: unknown[]): unknown; getHotPicSearchResult (arg: unknown): unknown;
getHotPicHotWords (...args: unknown[]): unknown; getHotPicHotWords (arg: unknown): unknown;
getHotPicJumpInfo (...args: unknown[]): unknown; getHotPicJumpInfo (arg: unknown): unknown;
getEmojiResourcePath (...args: unknown[]): unknown; getEmojiResourcePath (arg: unknown): unknown;
JoinDragonGroupEmoji (JoinDragonGroupEmojiReq: { JoinDragonGroupEmoji (JoinDragonGroupEmojiReq: {
latestMsgSeq: string, latestMsgSeq: string,
@@ -419,17 +420,17 @@ export interface NodeIKernelMsgService {
peerContact: Peer; peerContact: Peer;
}): Promise<unknown>; }): Promise<unknown>;
getMsgAbstracts (...args: unknown[]): unknown; getMsgAbstracts (arg: unknown): unknown;
getMsgAbstract (...args: unknown[]): unknown; getMsgAbstract (arg1: Peer, arg2: string): unknown;
getMsgAbstractList (...args: unknown[]): unknown; getMsgAbstractList (arg: unknown): unknown;
getMsgAbstractListBySeqRange (...args: unknown[]): unknown; getMsgAbstractListBySeqRange (arg: unknown): unknown;
refreshMsgAbstracts (...args: unknown[]): unknown; refreshMsgAbstracts (arg: unknown): unknown;
refreshMsgAbstractsByGuildIds (...args: unknown[]): unknown; refreshMsgAbstractsByGuildIds (arg: unknown): unknown;
getRichMediaElement (arg: { getRichMediaElement (arg: {
msgId: string, msgId: string,
@@ -440,7 +441,7 @@ export interface NodeIKernelMsgService {
downloadType: number, downloadType: number,
}): Promise<any>; }): Promise<any>;
cancelGetRichMediaElement (...args: unknown[]): unknown; cancelGetRichMediaElement (arg: unknown): unknown;
refuseGetRichMediaElement (args: { refuseGetRichMediaElement (args: {
msgId: string, msgId: string,
@@ -451,7 +452,7 @@ export interface NodeIKernelMsgService {
downSourceType: number, // 1 downSourceType: number, // 1
}): Promise<void>; }): Promise<void>;
switchToOfflineGetRichMediaElement (...args: unknown[]): unknown; switchToOfflineGetRichMediaElement (arg: unknown): unknown;
downloadRichMedia (args: { downloadRichMedia (args: {
fileModelId: string, fileModelId: string,
@@ -473,21 +474,21 @@ export interface NodeIKernelMsgService {
guildId: string; guildId: string;
}): Promise<unknown>; }): Promise<unknown>;
getFirstUnreadCommonMsg (...args: unknown[]): unknown; getFirstUnreadCommonMsg (arg: unknown): unknown;
getFirstUnreadAtmeMsg (...args: unknown[]): unknown; getFirstUnreadAtmeMsg (peer: Peer): unknown;
getFirstUnreadAtallMsg (...args: unknown[]): unknown; getFirstUnreadAtallMsg (peer: Peer): unknown;
getNavigateInfo (...args: unknown[]): unknown; getNavigateInfo (arg: unknown): unknown;
getChannelFreqLimitInfo (...args: unknown[]): unknown; getChannelFreqLimitInfo (arg: unknown): unknown;
getRecentUseEmojiList (...args: unknown[]): unknown; getRecentUseEmojiList (): unknown;
getRecentEmojiList (...args: unknown[]): unknown; getRecentEmojiList (arg: unknown): unknown;
setMsgEmojiLikes (...args: unknown[]): unknown; setMsgEmojiLikes (peer: Peer, msgSeq: string, emojiId: string, emojiType: string, setOrCancel: boolean): unknown;
getMsgEmojiLikesList (peer: Peer, msgSeq: string, emojiId: string, emojiType: string, cookie: string, bForward: boolean, number: number): Promise<{ getMsgEmojiLikesList (peer: Peer, msgSeq: string, emojiId: string, emojiType: string, cookie: string, bForward: boolean, number: number): Promise<{
result: number, result: number,
@@ -503,7 +504,7 @@ export interface NodeIKernelMsgService {
isFirstPage: boolean; isFirstPage: boolean;
}>; }>;
setMsgEmojiLikesForRole (...args: unknown[]): unknown; setMsgEmojiLikesForRole (arg1: Peer, arg2: string, arg3: string, arg4: string, arg5: string, arg6: string, arg7: boolean, arg8: boolean, arg9: SgrpStreamParams): unknown;
clickInlineKeyboardButton (params: { clickInlineKeyboardButton (params: {
guildId?: string, guildId?: string,
@@ -516,7 +517,7 @@ export interface NodeIKernelMsgService {
chatType: number; // 1私聊 2群 chatType: number; // 1私聊 2群
}): Promise<GeneralCallResult & { status: number, promptText: string, promptType: number, promptIcon: number; }>; }): Promise<GeneralCallResult & { status: number, promptText: string, promptType: number, promptIcon: number; }>;
setCurOnScreenMsg (...args: unknown[]): unknown; setCurOnScreenMsg (arg: unknown): unknown;
setCurOnScreenMsgForMsgEvent (peer: Peer, msgRegList: Map<string, Uint8Array>): void; setCurOnScreenMsgForMsgEvent (peer: Peer, msgRegList: Map<string, Uint8Array>): void;
@@ -524,91 +525,91 @@ export interface NodeIKernelMsgService {
setMiscData (key: string, value: string): unknown; setMiscData (key: string, value: string): unknown;
getBookmarkData (...args: unknown[]): unknown; getBookmarkData (key: string): unknown;
setBookmarkData (...args: unknown[]): unknown; setBookmarkData (key: string, value: string): unknown;
sendShowInputStatusReq (ChatType: number, EventType: number, toUid: string): Promise<unknown>; sendShowInputStatusReq (ChatType: number, EventType: number, toUid: string): Promise<unknown>;
queryCalendar (...args: unknown[]): unknown; queryCalendar (peer: Peer, msgTime: number): unknown;
queryFirstMsgSeq (peer: Peer, ...args: unknown[]): unknown; queryFirstMsgSeq (peer: Peer, msgTime: number): unknown;
queryRoamCalendar (...args: unknown[]): unknown; queryRoamCalendar (peer: Peer, msgTime: number): unknown;
queryFirstRoamMsg (...args: unknown[]): unknown; queryFirstRoamMsg (peer: Peer, msgTime: number): unknown;
fetchLongMsg (peer: Peer, msgId: string): unknown; fetchLongMsg (peer: Peer, msgId: string): unknown;
fetchLongMsgWithCb (...args: unknown[]): unknown; fetchLongMsgWithCb (peer: Peer, msgId: number): unknown;
setIsStopKernelFetchLongMsg (...args: unknown[]): unknown; setIsStopKernelFetchLongMsg (arg: unknown): unknown;
insertGameResultAsMsgToDb (...args: unknown[]): unknown; insertGameResultAsMsgToDb (arg: unknown): unknown;
getMultiMsg (...args: unknown[]): Promise<GeneralCallResult & { getMultiMsg (arg1: Peer, arg2: string, arg3: string): Promise<GeneralCallResult & {
msgList: RawMessage[]; msgList: RawMessage[];
}>; }>;
setDraft (...args: unknown[]): unknown; setDraft (arg1: Peer, arg2: Array<unknown>[]): unknown;
getDraft (...args: unknown[]): unknown; getDraft (peer: Peer): unknown;
deleteDraft (...args: unknown[]): unknown; deleteDraft (peer: Peer): unknown;
getRecentHiddenSesionList (...args: unknown[]): unknown; getRecentHiddenSesionList (): unknown;
setRecentHiddenSession (...args: unknown[]): unknown; setRecentHiddenSession (arg: unknown): unknown;
delRecentHiddenSession (...args: unknown[]): unknown; delRecentHiddenSession (arg: unknown): unknown;
getCurHiddenSession (...args: unknown[]): unknown; getCurHiddenSession (): unknown;
setCurHiddenSession (...args: unknown[]): unknown; setCurHiddenSession (arg: unknown): unknown;
setReplyDraft (...args: unknown[]): unknown; setReplyDraft (arg1: Peer, arg2: string, arg3: Array<unknown>[]): unknown;
getReplyDraft (...args: unknown[]): unknown; getReplyDraft (arg1: Peer, arg2: string): unknown;
deleteReplyDraft (...args: unknown[]): unknown; deleteReplyDraft (arg1: Peer, arg2: string): unknown;
getFirstUnreadAtMsg (peer: Peer): unknown; getFirstUnreadAtMsg (peer: Peer): unknown;
clearMsgRecords (...args: unknown[]): unknown; clearMsgRecords (peer: Peer): unknown;
IsExistOldDb (...args: unknown[]): unknown; IsExistOldDb (): unknown;
canImportOldDbMsg (...args: unknown[]): unknown; canImportOldDbMsg (): unknown;
setPowerStatus (isPowerOn: boolean): unknown; setPowerStatus (isPowerOn: boolean): unknown;
canProcessDataMigration (...args: unknown[]): unknown; canProcessDataMigration (): unknown;
importOldDbMsg (...args: unknown[]): unknown; importOldDbMsg (): unknown;
stopImportOldDbMsgAndroid (...args: unknown[]): unknown; stopImportOldDbMsgAndroid (): unknown;
isMqqDataImportFinished (...args: unknown[]): unknown; isMqqDataImportFinished (): unknown;
getMqqDataImportTableNames (...args: unknown[]): unknown; getMqqDataImportTableNames (): unknown;
getCurChatImportStatusByUin (...args: unknown[]): unknown; getCurChatImportStatusByUin (arg1: unknown, arg2: unknown): unknown;
getDataImportUserLevel (): unknown; getDataImportUserLevel (): unknown;
getMsgQRCode (...args: unknown[]): unknown; getMsgQRCode (): unknown;
getGuestMsgAbstracts (...args: unknown[]): unknown; getGuestMsgAbstracts (arg: unknown): unknown;
getGuestMsgByRange (...args: unknown[]): unknown; getGuestMsgByRange (arg: unknown): unknown;
getGuestMsgAbstractByRange (...args: unknown[]): unknown; getGuestMsgAbstractByRange (arg: unknown): unknown;
registerSysMsgNotification (...args: unknown[]): unknown; registerSysMsgNotification (arg1: number, arg2: string, arg3: Array<unknown>[]): unknown;
unregisterSysMsgNotification (...args: unknown[]): unknown; unregisterSysMsgNotification (arg1: number, arg2: string, arg3: Array<unknown>[]): unknown;
enterOrExitAio (...args: unknown[]): unknown; enterOrExitAio (arg: unknown): unknown;
prepareTempChat (args: unknown): unknown; prepareTempChat (args: unknown): unknown;
@@ -616,66 +617,66 @@ export interface NodeIKernelMsgService {
getTempChatInfo (ChatType: number, Uid: string): Promise<TmpChatInfoApi>; getTempChatInfo (ChatType: number, Uid: string): Promise<TmpChatInfoApi>;
setContactLocalTop (...args: unknown[]): unknown; setContactLocalTop (peer: Peer, isTop: boolean): unknown;
switchAnonymousChat (...args: unknown[]): unknown; switchAnonymousChat (arg1: string, arg2: boolean): unknown;
renameAnonyChatNick (...args: unknown[]): unknown; renameAnonyChatNick (arg: unknown): unknown;
getAnonymousInfo (...args: unknown[]): unknown; getAnonymousInfo (peer: Peer): unknown;
updateAnonymousInfo (...args: unknown[]): unknown; updateAnonymousInfo (peer: Peer, arg2: unknown): unknown;
sendSummonMsg (peer: Peer, MsgElement: unknown, MsgAttributeInfo: unknown): Promise<unknown>;// 频道的东西 sendSummonMsg (peer: Peer, MsgElement: unknown, MsgAttributeInfo: unknown): Promise<unknown>;// 频道的东西
outputGuildUnreadInfo (...args: unknown[]): unknown; outputGuildUnreadInfo (arg: unknown): unknown;
checkMsgWithUrl (...args: unknown[]): unknown; checkMsgWithUrl (arg: unknown): unknown;
checkTabListStatus (...args: unknown[]): unknown; checkTabListStatus (): unknown;
getABatchOfContactMsgBoxInfo (...args: unknown[]): unknown; getABatchOfContactMsgBoxInfo (arg: unknown): unknown;
insertMsgToMsgBox (peer: Peer, msgId: string, arg: 2006): unknown; insertMsgToMsgBox (peer: Peer, msgId: string, arg: 2006): unknown;
isHitEmojiKeyword (...args: unknown[]): unknown; isHitEmojiKeyword (arg: unknown): unknown;
getKeyWordRelatedEmoji (...args: unknown[]): unknown; getKeyWordRelatedEmoji (arg: unknown): unknown;
recordEmoji (...args: unknown[]): unknown; recordEmoji (type: number, emojiList: Array<unknown>): unknown;
fetchGetHitEmotionsByWord (args: unknown): Promise<unknown>;// 表情推荐? fetchGetHitEmotionsByWord (args: unknown): Promise<unknown>;// 表情推荐?
deleteAllRoamMsgs (...args: unknown[]): unknown;// 漫游消息? deleteAllRoamMsgs (arg1: number, arg2: string): unknown;// 漫游消息?
packRedBag (...args: unknown[]): unknown; packRedBag (arg: unknown): unknown;
grabRedBag (...args: unknown[]): unknown; grabRedBag (arg: unknown): unknown;
pullDetail (...args: unknown[]): unknown; pullDetail (arg: unknown): unknown;
selectPasswordRedBag (...args: unknown[]): unknown; selectPasswordRedBag (arg: unknown): unknown;
pullRedBagPasswordList (...args: unknown[]): unknown; pullRedBagPasswordList (): unknown;
requestTianshuAdv (...args: unknown[]): unknown; requestTianshuAdv (arg: unknown): unknown;
tianshuReport (...args: unknown[]): unknown; tianshuReport (arg: unknown): unknown;
tianshuMultiReport (...args: unknown[]): unknown; tianshuMultiReport (arg: unknown): unknown;
GetMsgSubType (a0: number, a1: number): unknown; GetMsgSubType (a0: number, a1: number): unknown;
setIKernelPublicAccountAdapter (...args: unknown[]): unknown; setIKernelPublicAccountAdapter (arg: unknown): unknown;
// tempChatGameSession有关 // tempChatGameSession有关
createUidFromTinyId (fromTinyId: string, toTinyId: string): string; createUidFromTinyId (fromTinyId: string, toTinyId: string): string;
dataMigrationGetDataAvaiableContactList (...args: unknown[]): unknown; dataMigrationGetDataAvaiableContactList (): unknown;
dataMigrationGetMsgList (...args: unknown[]): unknown; dataMigrationGetMsgList (arg1: unknown, arg2: unknown): unknown;
dataMigrationStopOperation (...args: unknown[]): unknown; dataMigrationStopOperation (arg: unknown): unknown;
dataMigrationImportMsgPbRecord (DataMigrationMsgInfo: Array<{ dataMigrationImportMsgPbRecord (DataMigrationMsgInfo: Array<{
extensionData: string;// "Hex" extensionData: string;// "Hex"
@@ -696,38 +697,37 @@ export interface NodeIKernelMsgService {
msgType: number; msgType: number;
}): unknown; }): unknown;
dataMigrationGetResourceLocalDestinyPath (...args: unknown[]): unknown; dataMigrationGetResourceLocalDestinyPath (arg: unknown): unknown;
dataMigrationSetIOSPathPrefix (...args: unknown[]): unknown; dataMigrationSetIOSPathPrefix (arg: unknown): unknown;
getServiceAssistantSwitch (...args: unknown[]): unknown; getServiceAssistantSwitch (arg: unknown): unknown;
setServiceAssistantSwitch (...args: unknown[]): unknown; setServiceAssistantSwitch (arg: unknown): unknown;
setSubscribeFolderUsingSmallRedPoint (...args: unknown[]): unknown; setSubscribeFolderUsingSmallRedPoint (arg: unknown): unknown;
clearGuildNoticeRedPoint (...args: unknown[]): unknown; clearGuildNoticeRedPoint (arg: unknown): unknown;
clearFeedNoticeRedPoint (...args: unknown[]): unknown; clearFeedNoticeRedPoint (arg: unknown): unknown;
clearFeedSquareRead (...args: unknown[]): unknown; clearFeedSquareRead (arg: unknown): unknown;
IsC2CStyleChatType (...args: unknown[]): unknown; IsC2CStyleChatType (chatType: unknown): unknown;
IsTempChatType (uin: number): unknown;// 猜的 IsTempChatType (uin: number): unknown;// 猜的
getGuildInteractiveNotification (...args: unknown[]): unknown; getGuildInteractiveNotification (arg: unknown): unknown;
getGuildNotificationAbstract (...args: unknown[]): unknown; getGuildNotificationAbstract (arg: unknown): unknown;
setFocusOnBase (...args: unknown[]): unknown; setFocusOnBase (arg: unknown): unknown;
queryArkInfo (...args: unknown[]): unknown; queryArkInfo (arg: unknown): unknown;
queryUserSecQuality (...args: unknown[]): unknown; queryUserSecQuality (): unknown;
getGuildMsgAbFlag (...args: unknown[]): unknown; getGuildMsgAbFlag (arg: unknown): unknown;
getGroupMsgStorageTime (): unknown; getGroupMsgStorageTime (): unknown;
} }

View File

@@ -0,0 +1,11 @@
export interface NodeIKernelNearbyProService {
addKernelNearbyProListener (listener: unknown): number;
removeKernelNearbyProListener (listenerId: number): void;
fetchNearbyProUserInfo (arg1: unknown[], arg2: unknown, arg3: boolean): unknown;
setCommonExtInfo (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -14,4 +14,118 @@ export interface NodeIKernelNodeMiscService {
startNewMiniApp (appfile: string, params: string): unknown; startNewMiniApp (appfile: string, params: string): unknown;
getQimei36WithNewSdk (): Promise<string>; getQimei36WithNewSdk (): Promise<string>;
adaptMiniAppShareInfo (arg: unknown): unknown;
addBind (arg1: unknown, arg2: unknown): unknown;
changeSendKey (arg: unknown): unknown;
checkIfHaveAvailableSidecarDevice (arg: unknown): unknown;
clearQzoneUnreadCount (arg: unknown): unknown;
clearQzoneUnreadCountWithRedDot (arg: unknown): unknown;
closeWXMiniApp (arg: unknown): unknown;
delBind (arg: unknown): unknown;
deleteShareFile (arg: unknown): unknown;
dispatchWmpfEvent (arg: unknown): unknown;
doAction (arg1: unknown, arg2: unknown): unknown;
doPostAction (arg1: unknown, arg2: unknown): unknown;
downloadMiniApp (arg: unknown): unknown;
downloadMiniGame (arg: unknown): unknown;
encodeAES (arg1: unknown, arg2: unknown): unknown;
flashWindowInTaskbar (arg1: unknown, arg2: unknown): unknown;
getAppLaunchInfo (arg: unknown): unknown;
getCurWindowInfo (arg: unknown): unknown;
getCurWindowInfoExceptList (arg: unknown): unknown;
getMiniGameV2EngineConfig (arg: unknown): unknown;
getMyAppList (arg: unknown): unknown;
getOpenAuth (arg1: unknown, arg2: unknown): unknown;
getQQlevelInfo (arg: unknown): unknown;
getQzoneUnreadCount (arg: unknown): unknown;
installApp (arg1: unknown, arg2: unknown): unknown;
isAppInstalled (arg: unknown): unknown;
isOldQQRunning (arg: unknown): unknown;
judgeTimingRequest (arg: unknown): unknown;
listenWindowEvents (arg: unknown): unknown;
loginWXMiniApp (arg: unknown): unknown;
openFileAndDirSelectDlg (arg: unknown): unknown;
prefetch (arg: unknown): unknown;
qqConnectBatchShare (arg1: unknown, arg2: unknown): unknown;
qqConnectShare (arg: unknown): unknown;
qqConnectShareCheck (arg: unknown): unknown;
registerSchemes (arg: unknown): unknown;
registerScreenCaptureShortcutWithKeycode (arg: unknown): unknown;
registerScreenRecordShortcutWithKeycode (arg: unknown): unknown;
removeQuarantineAttribute (arg: unknown): unknown;
reportExecuteRequest (arg: unknown): unknown;
scanQBar (arg: unknown): unknown;
sendMessageResponseToWX (arg1: unknown, arg2: unknown): unknown;
sendRequestToApiGateway (arg: unknown): unknown;
sendWXCustomMenuClickedAction (arg1: unknown, arg2: unknown): unknown;
setBackgroudWindowLevel (arg1: unknown, arg2: unknown): unknown;
setMiniGameVersion (arg: unknown): unknown;
setVulkanEnable (arg: unknown): unknown;
setWindowLevelNT (arg1: unknown, arg2: unknown): unknown;
setWindowsMenuInstallStatus (arg: unknown): unknown;
setWXCustomMenuConfig (arg1: unknown, arg2: unknown): unknown;
startNewApp (arg: unknown): unknown;
startScreenCapture (arg1: unknown, arg2: unknown): unknown;
stopFlashWindow (arg: unknown): unknown;
unlistenWindowEvents (arg: unknown): unknown;
unregisterHotkey (arg: unknown): unknown;
writeBitmapToClipboard (arg: unknown): unknown;
writeClipboard (arg1: unknown, arg2: unknown): unknown;
} }

View File

@@ -1,36 +1,29 @@
export interface NodeIKernelOnlineStatusService { export interface NodeIKernelOnlineStatusService {
addKernelOnlineStatusListener(listener: unknown): number; addKernelOnlineStatusListener (listener: unknown): number;
removeKernelOnlineStatusListener(listenerId: number): void; removeKernelOnlineStatusListener (listenerId: number): void;
getShouldShowAIOStatusAnimation(arg: unknown): unknown; getShouldShowAIOStatusAnimation (arg: unknown): unknown;
setReadLikeList(arg: unknown): unknown; setReadLikeList (arg: unknown): unknown;
getLikeList(arg: unknown): unknown; getLikeList (arg: unknown): Promise<unknown>;
setLikeStatus(arg: unknown): unknown; setLikeStatus (arg: unknown): Promise<unknown>;
getAggregationPageEntrance(): unknown; setOnlineStatusLiteBusinessSwitch (enabled: boolean): void;
didClickAggregationPageEntrance(): unknown; getAggregationPageEntrance (): unknown;
getAggregationGroupModels(): unknown; didClickAggregationPageEntrance (): unknown;
// { getAggregationGroupModels (): unknown;
// "businessType": 1,
// "uins": [
// "1627126029",
// "66600000",
// "71702575"
// ]
// }
checkLikeStatus(param: { checkLikeStatus (param: {
businessType: number, businessType: number,
uins: string[] uins: string[];
}): Promise<unknown>; }): Promise<unknown>;
isNull(): boolean; isNull (): boolean;
} }

View File

@@ -0,0 +1,75 @@
export interface NodeIKernelPersonalAlbumService {
addAlbumPermissions (arg: unknown): unknown;
addComment (arg: unknown): unknown;
addReply (arg: unknown): unknown;
createAlbum (arg: unknown): unknown;
delBatchPhoto (arg: unknown): unknown;
deleteAlbum (arg: unknown): unknown;
deleteComment (arg: unknown): unknown;
deleteReply (arg: unknown): unknown;
doLike (arg: unknown): unknown;
editAlbum (arg: unknown): unknown;
editTravelAlbumScence (arg: unknown): unknown;
forwardAlbumToQzone (arg: unknown): unknown;
getAlbumInviteJoinPage (arg: unknown): unknown;
getAlbumJoinApprovalPage (arg: unknown): unknown;
getAlbumList (arg: unknown): unknown;
getAlbumMemberList (arg: unknown): unknown;
getCommentList (arg: unknown): unknown;
getLayerTailpageRecommend (arg: unknown): unknown;
getPhotoList (arg: unknown): unknown;
getPhotoListByTimeLine (arg: unknown): unknown;
getPhotoTabByTimeLine (arg: unknown): unknown;
getShareInfo (arg: unknown): unknown;
getVideoTabByTimeLine (arg: unknown): unknown;
inviteCheckForLoversAlbum (arg: unknown): unknown;
joinShareAlbum (arg: unknown): unknown;
moveBatchPhoto (arg: unknown): unknown;
queryAlbum (arg: unknown): unknown;
quitSharedAlbum (arg: unknown): unknown;
removeAlbumMember (arg: unknown): unknown;
respondToJoinRequest (arg: unknown): unknown;
sendAlbumInvitation (arg: unknown): unknown;
setAlbumServiceInfo (arg1: string, arg2: string, arg3: string): unknown;
setTopAlbum (arg: unknown): unknown;
unLike (arg: unknown): unknown;
updateAlbumMember (arg: unknown): unknown;
verifyAlbumQuestion (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -1,37 +1,37 @@
import { BuddyProfileLikeReq, GeneralCallResult, NTVoteInfo } from '@/napcat-core/index'; import { BuddyProfileLikeReq, GeneralCallResult, NTVoteInfo } from '@/napcat-core/index';
export interface NodeIKernelProfileLikeService { export interface NodeIKernelProfileLikeService {
addKernelProfileLikeListener(listener: unknown): number; addKernelProfileLikeListener (listener: unknown): number;
removeKernelProfileLikeListener(listenerId: unknown): void; removeKernelProfileLikeListener (listenerId: number): void;
setBuddyProfileLike(...args: unknown[]): { result: number, errMsg: string, succCounts: number }; setBuddyProfileLike (arg: unknown): Promise<{ result: number, errMsg: string, succCounts: number; }>;
getBuddyProfileLike(req: BuddyProfileLikeReq): Promise<GeneralCallResult & { getBuddyProfileLike (req: BuddyProfileLikeReq): Promise<GeneralCallResult & {
info: { info: {
userLikeInfos: Array<{ userLikeInfos: Array<{
uid: string, uid: string,
time: string, time: string,
favoriteInfo: { favoriteInfo: {
userInfos: Array<NTVoteInfo>, // 哪些人点我 userInfos: Array<NTVoteInfo>,
total_count: number, total_count: number,
last_time: number, last_time: number,
today_count: number today_count: number;
}, },
voteInfo: { voteInfo: {
total_count: number, total_count: number,
new_count: number, new_count: number,
new_nearby_count: number, new_nearby_count: number,
last_visit_time: number, last_visit_time: number,
userInfos: Array<NTVoteInfo>, // 点过哪些人 userInfos: Array<NTVoteInfo>;
} };
}>, }>,
friendMaxVotes: number, friendMaxVotes: number,
start: number start: number;
} };
}>; }>;
getProfileLikeScidResourceInfo(...args: unknown[]): void; getProfileLikeScidResourceInfo (arg: unknown): void;
isNull(): boolean; isNull (): boolean;
} }

View File

@@ -3,80 +3,94 @@ import { BizKey, ModifyProfileParams, NodeIKernelProfileListener, ProfileBizType
import { GeneralCallResult } from '@/napcat-core/services/common'; import { GeneralCallResult } from '@/napcat-core/services/common';
export interface NodeIKernelProfileService { export interface NodeIKernelProfileService {
getOtherFlag(callfrom: string, uids: string[]): Promise<Map<string, unknown>>; getOtherFlag (callfrom: string, uids: string[]): Promise<Map<string, unknown>>;
getVasInfo(callfrom: string, uids: string[]): Promise<Map<string, unknown>>; getVasInfo (callfrom: string, uids: string[]): Promise<Map<string, unknown>>;
getRelationFlag(callfrom: string, uids: string[]): Promise<Map<string, unknown>>; getRelationFlag (callfrom: string, uids: string[]): Promise<Map<string, unknown>>;
getUidByUin(callfrom: string, uin: Array<string>): Map<string, string>; getUidByUin (callfrom: string, uin: Array<string>): Map<string, string>;
getUinByUid(callfrom: string, uid: Array<string>): Map<string, string>; getUinByUid (callfrom: string, uid: Array<string>): Map<string, string>;
getCoreAndBaseInfo(callfrom: string, uids: string[]): Promise<Map<string, SimpleInfo>>; getCoreAndBaseInfo (callfrom: string, uids: string[]): Promise<Map<string, SimpleInfo>>;
fetchUserDetailInfo(trace: string, uids: string[], source: UserDetailSource, bizType: ProfileBizType[]): Promise<GeneralCallResult & fetchUserDetailInfo (trace: string, uids: string[], source: UserDetailSource, bizType: ProfileBizType[]): Promise<GeneralCallResult &
{ {
source: UserDetailSource, source: UserDetailSource,
// uid -> detail // uid -> detail
detail: Map<string, UserDetailInfoListenerArg>, detail: Map<string, UserDetailInfoListenerArg>,
} }
>; >;
addKernelProfileListener(listener: NodeIKernelProfileListener): number; addKernelProfileListener (listener: NodeIKernelProfileListener): number;
removeKernelProfileListener(listenerId: number): void; removeKernelProfileListener (listenerId: number): void;
prepareRegionConfig(...args: unknown[]): unknown; prepareRegionConfig (): unknown;
getLocalStrangerRemark(): Promise<AnyCnameRecord>; getLocalStrangerRemark (): Promise<AnyCnameRecord>;
enumCountryOptions(): Array<string>; enumCountryOptions (): Array<string>;
enumProvinceOptions(country: string): Array<string>; enumProvinceOptions (country: string): Array<string>;
enumCityOptions(country: string, province: string): unknown; enumCityOptions (country: string, province: string): unknown;
enumAreaOptions(...args: unknown[]): unknown; enumAreaOptions (arg1: string, arg2: string, arg3: string): unknown;
modifySelfProfile(...args: unknown[]): Promise<unknown>; modifySelfProfile (param: unknown): Promise<unknown>;
modifyDesktopMiniProfile(param: ModifyProfileParams): Promise<GeneralCallResult>; modifyDesktopMiniProfile (param: ModifyProfileParams): Promise<GeneralCallResult>;
setNickName(nickName: string): Promise<unknown>; setNickName (nickName: string): Promise<unknown>;
setLongNick(longNick: string): Promise<unknown>; setLongNick (longNick: string): Promise<unknown>;
setBirthday(...args: unknown[]): Promise<unknown>; setBirthday (year: number, month: number, day: number): Promise<unknown>;
setGander(...args: unknown[]): Promise<unknown>; setGander (gender: unknown): Promise<unknown>;
setHeader(arg: string): Promise<GeneralCallResult>; setHeader (arg: string): Promise<GeneralCallResult>;
setRecommendImgFlag(...args: unknown[]): Promise<unknown>; setRecommendImgFlag (flag: unknown): Promise<unknown>;
getUserSimpleInfo(force: boolean, uids: string[]): Promise<unknown>; getUserSimpleInfo (force: boolean, uids: string[]): Promise<unknown>;
getUserDetailInfo(uid: string): Promise<unknown>; getUserDetailInfo (uid: string): Promise<unknown>;
getUserDetailInfoWithBizInfo(uid: string, Biz: BizKey[]): Promise<GeneralCallResult>; getUserDetailInfoWithBizInfo (uid: string, Biz: BizKey[]): Promise<GeneralCallResult>;
getUserDetailInfoByUin(uin: string): Promise<UserDetailInfoByUin>; getUserDetailInfoByUin (uin: string): Promise<UserDetailInfoByUin>;
getZplanAvatarInfos(args: string[]): Promise<unknown>; getZplanAvatarInfos (args: string[]): Promise<unknown>;
getStatus(uid: string): Promise<unknown>; getStatus (uid: string): Promise<unknown>;
startStatusPolling(isForceReset: boolean): Promise<unknown>; startStatusPolling (isForceReset: boolean): Promise<unknown>;
getSelfStatus(): Promise<unknown>; getSelfStatus (): Promise<unknown>;
setdisableEmojiShortCuts(...args: unknown[]): unknown; setdisableEmojiShortCuts (arg: unknown): unknown;
getProfileQzonePicInfo(uid: string, type: number, force: boolean): Promise<unknown>; getProfileQzonePicInfo (uid: string, type: number, force: boolean): Promise<unknown>;
// UserRemarkServiceImpl::getStrangerRemarkByUid [] // UserRemarkServiceImpl::getStrangerRemarkByUid []
getCoreInfo(sceneId: string, arg: unknown[]): unknown; getCoreInfo (sceneId: string, arg: unknown[]): unknown;
isNull(): boolean; isNull (): boolean;
addKernelProfileListenerForUICache (listener: unknown): number;
asyncGetCoreInfo (callfrom: string, uids: string[]): unknown;
getIntimate (uid: string, arg: unknown): unknown;
getStatusInfo (uid: string, arg: unknown): unknown;
getStockLocalData (key: string, arg: unknown): unknown;
updateProfileData (uid: string, data: unknown): unknown;
updateStockLocalData (key: string, data: unknown): unknown;
} }

View File

@@ -0,0 +1,15 @@
export interface NodeIKernelPublicAccountService {
addListener (listener: unknown): number;
removeListener (listenerId: number): void;
follow (arg: unknown): unknown;
queryTemplateInfo (arg: unknown): unknown;
subscribeTemplate (arg: unknown): unknown;
unfollow (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,19 @@
export interface NodeIKernelQQPlayService {
addKernelQQPlayListener (listener: unknown): number;
removeKernelQQPlayListener (listenerId: number): void;
createLnkShortcut (arg1: string, arg2: string, arg3: string, arg4: string): unknown;
getSystemRegValue (arg1: number, arg2: string, arg3: string): unknown;
setSystemRegValue (arg1: number, arg2: string, arg3: string, arg4: string): unknown;
sendMsg2Simulator (arg1: unknown, arg2: unknown): unknown;
setForegroundWindow (arg: unknown): unknown;
startSimulator (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,21 @@
export interface NodeIKernelQiDianService {
addKernelQiDianListener (listener: unknown): number;
removeKernelQiDianListener (listenerId: number): void;
requestExtUinForRemoteControl (arg1: string, arg2: string, arg3: number): unknown;
requestMainUinForRemoteControl (arg: unknown): unknown;
requestNaviConfig (arg: unknown): unknown;
requestQidianUidFromUin (arg: unknown): unknown;
requestWpaCorpInfo (arg: unknown): unknown;
requestWpaSigT (arg1: unknown, arg2: unknown): unknown;
requestWpaUserInfo (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,13 @@
export interface NodeIKernelRDeliveryService {
addDataChangeListener (listener: unknown): number;
removeDataChangeListener (listenerId: number): void;
getRDeliveryDataByKey (arg: unknown): unknown;
requestBatchRemoteDataByScene (arg1: unknown, arg2: unknown): unknown;
requestSingleRemoteDataByKey (arg1: string, arg2: unknown): unknown;
isNull (): boolean;
}

View File

@@ -4,17 +4,19 @@ import { GeneralCallResult } from '@/napcat-core/services/common';
import { FSABRecentContactParams } from '@/napcat-core/types/contact'; import { FSABRecentContactParams } from '@/napcat-core/types/contact';
export interface NodeIKernelRecentContactService { export interface NodeIKernelRecentContactService {
setGuildDisplayStatus(...args: unknown[]): unknown; // 2 arguments setGuildDisplayStatus (arg1: unknown, arg2: unknown): unknown;
setContactListTop(...args: unknown[]): unknown; // 2 arguments setContactListTop (peer: Peer, isTop: boolean): unknown;
updateRecentContactExtBufForUI(...args: unknown[]): unknown; // 2 arguments updateRecentContactExtBufForUI (peer: Peer, extBuf: unknown): unknown;
upsertRecentContactManually(...args: unknown[]): unknown; // 1 arguments upsertRecentContactManually (arg: unknown): unknown;
enterOrExitMsgList(...args: unknown[]): unknown; // 1 arguments manageContactMergeWindow (arg: unknown): unknown;
getRecentContactListSnapShot(count: number): Promise<GeneralCallResult & { enterOrExitMsgList (arg: unknown): unknown;
getRecentContactListSnapShot (count: number): Promise<GeneralCallResult & {
info: { info: {
errCode: number, errCode: number,
errMsg: string, errMsg: string,
@@ -28,56 +30,56 @@ export interface NodeIKernelRecentContactService {
peerUin: string, peerUin: string,
msgTime: string, msgTime: string,
chatType: ChatType, chatType: ChatType,
msgId: string msgId: string;
}> }>;
} };
}>; // 1 arguments }>;
clearMsgUnreadCount(...args: unknown[]): unknown; // 1 arguments clearMsgUnreadCount (peer: Peer): unknown;
getRecentContactListSyncLimit(count: number): unknown; getRecentContactListSyncLimit (count: number): unknown;
jumpToSpecifyRecentContact(...args: unknown[]): unknown; // 1 arguments jumpToSpecifyRecentContact (arg: unknown): unknown;
fetchAndSubscribeABatchOfRecentContact(params: FSABRecentContactParams): unknown; // 1 arguments fetchAndSubscribeABatchOfRecentContact (params: FSABRecentContactParams): unknown;
addRecentContact(peer: Peer): unknown; addRecentContact (peer: Peer): unknown;
deleteRecentContacts(peer: Peer): unknown; // 猜测 deleteRecentContacts (peer: Peer): unknown;
getContacts(peers: Peer[]): Promise<unknown>; getContacts (peers: Peer[]): Promise<unknown>;
setThirdPartyBusinessInfos(...args: unknown[]): unknown; // 1 arguments setThirdPartyBusinessInfos (arg: unknown): unknown;
updateGameMsgConfigs(...args: unknown[]): unknown; // 1 arguments updateGameMsgConfigs (arg: unknown): unknown;
removeKernelRecentContactListener(listenerid: number): unknown; // 1 arguments removeKernelRecentContactListener (listenerId: number): unknown;
addKernelRecentContactListener(listener: NodeIKernelRecentContactListener): void; addKernelRecentContactListener (listener: NodeIKernelRecentContactListener): void;
clearRecentContactsByChatType(...args: unknown[]): unknown; // 1 arguments clearRecentContactsByChatType (chatType: ChatType): unknown;
upInsertModule(...args: unknown[]): unknown; // 1 arguments upInsertModule (arg: unknown): unknown;
jumpToSpecifyRecentContactVer2(...args: unknown[]): unknown; // 1 arguments jumpToSpecifyRecentContactVer2 (arg: unknown): unknown;
deleteRecentContactsVer2(...args: unknown[]): unknown; // 1 arguments deleteRecentContactsVer2 (arg: unknown): unknown;
getRecentContactList(): Promise<unknown>; getRecentContactList (): Promise<unknown>;
getMsgUnreadCount(): unknown; getMsgUnreadCount (): unknown;
clearRecentContacts(): unknown; clearRecentContacts (): unknown;
getServiceAssistantRecentContactInfos(): unknown; getServiceAssistantRecentContactInfos (): unknown;
getRecentContactInfos(): unknown; getRecentContactInfos (): unknown;
getUnreadDetailsInfos(): unknown; getUnreadDetailsInfos (): unknown;
cleanAllModule(): unknown; cleanAllModule (): unknown;
setAllGameMsgRead(): unknown; setAllGameMsgRead (): unknown;
getRecentContactListSync(): unknown; getRecentContactListSync (): unknown;
} }

View File

@@ -0,0 +1,17 @@
export interface NodeIKernelRemotingService {
addKernelRemotingListener (listener: unknown): number;
removeKernelRemotingListener (listenerId: number): void;
accept (arg1: string, arg2: boolean): unknown;
setPenetrateBuffer (arg1: number, arg2: number, arg3: string): unknown;
startRemotingClient (arg: unknown): unknown;
startRemotingInvite (arg: unknown): unknown;
stopRemoting (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -62,7 +62,7 @@ export interface NodeIKernelRichMediaService {
// KHAND, // KHAND,
// KAUTO // KAUTO
// } // }
getVideoPlayUrl(peer: Peer, msgId: string, elemId: string, videoCodecFormat: number, VideoRequestWay: number): Promise<unknown>; getVideoPlayUrl (peer: Peer, msgId: string, elemId: string, videoCodecFormat: number, VideoRequestWay: number): Promise<unknown>;
// exParams (RMReqExParams) // exParams (RMReqExParams)
// this.downSourceType = i2; // this.downSourceType = i2;
@@ -81,9 +81,9 @@ export interface NodeIKernelRichMediaService {
// public static final int KTRIGGERTYPEAUTO = 1; // public static final int KTRIGGERTYPEAUTO = 1;
// public static final int KTRIGGERTYPEMANUAL = 0; // public static final int KTRIGGERTYPEMANUAL = 0;
getVideoPlayUrlV2(peer: Peer, msgId: string, elemId: string, videoCodecFormat: number, exParams: { getVideoPlayUrlV2 (peer: Peer, msgId: string, elemId: string, videoCodecFormat: number, exParams: {
downSourceType: number, downSourceType: number,
triggerType: number triggerType: number;
}): Promise<GeneralCallResult & { }): Promise<GeneralCallResult & {
urlResult: { urlResult: {
v4IpUrl: [], v4IpUrl: [],
@@ -91,15 +91,15 @@ export interface NodeIKernelRichMediaService {
domainUrl: Array<{ domainUrl: Array<{
url: string, url: string,
isHttps: boolean, isHttps: boolean,
httpsDomain: string httpsDomain: string;
}>, }>,
videoCodecFormat: number videoCodecFormat: number;
} };
}>; }>;
getRichMediaFileDir(elementType: number, downType: number, isTemp: boolean): unknown; getRichMediaFileDir (elementType: number, downType: number, isTemp: boolean): unknown;
getVideoPlayUrlInVisit(arg: { getVideoPlayUrlInVisit (arg: {
downloadType: number, downloadType: number,
thumbSize: number, thumbSize: number,
msgId: string, msgId: string,
@@ -111,17 +111,17 @@ export interface NodeIKernelRichMediaService {
peerUid: string, peerUid: string,
guildId: string, guildId: string,
ele: MessageElement, ele: MessageElement,
useHttps: boolean useHttps: boolean;
}): Promise<unknown>; }): Promise<unknown>;
isFileExpired(arg: number): unknown; isFileExpired (arg: number): unknown;
deleteGroupFolder(GroupCode: string, FolderId: string): Promise<GeneralCallResult & { deleteGroupFolder (GroupCode: string, FolderId: string): Promise<GeneralCallResult & {
groupFileCommonResult: { retCode: number, retMsg: string, clientWording: string } groupFileCommonResult: { retCode: number, retMsg: string, clientWording: string; };
}>; }>;
// 参数与getVideoPlayUrlInVisit一样 // 参数与getVideoPlayUrlInVisit一样
downloadRichMediaInVisit(arg: { downloadRichMediaInVisit (arg: {
downloadType: number, downloadType: number,
thumbSize: number, thumbSize: number,
msgId: string, msgId: string,
@@ -133,10 +133,10 @@ export interface NodeIKernelRichMediaService {
peerUid: string, peerUid: string,
guildId: string, guildId: string,
ele: MessageElement, ele: MessageElement,
useHttps: boolean useHttps: boolean;
}): unknown; }): unknown;
downloadFileForModelId(peer: Peer, ModelId: string[], unknown: string): Promise<unknown>; downloadFileForModelId (peer: Peer, ModelId: string[], unknown: string): Promise<unknown>;
// 第三个参数 Array<Type> // 第三个参数 Array<Type>
// this.fileId = ""; // this.fileId = "";
@@ -146,83 +146,83 @@ export interface NodeIKernelRichMediaService {
// this.fileSize = j2; // this.fileSize = j2;
// this.fileModelId = j3; // this.fileModelId = j3;
downloadFileForFileUuid(peer: Peer, uuid: string, arg3: { downloadFileForFileUuid (peer: Peer, uuid: string, arg3: {
fileId: string, fileId: string,
fileName: string, fileName: string,
fileSize: string, fileSize: string,
fileModelId: string fileModelId: string;
}[]): Promise<unknown>; }[]): Promise<unknown>;
downloadFileByUrlList(fileDownloadTyp: UrlFileDownloadType, urlList: Array<string>): unknown; downloadFileByUrlList (fileDownloadTyp: UrlFileDownloadType, urlList: Array<string>): unknown;
downloadFileForFileInfo(fileInfo: CommonFileInfo[], savePath: string): unknown; downloadFileForFileInfo (fileInfo: CommonFileInfo[], savePath: string): unknown;
createGroupFolder(GroupCode: string, FolderName: string): Promise<GeneralCallResult & { createGroupFolder (GroupCode: string, FolderName: string): Promise<GeneralCallResult & {
resultWithGroupItem: { result: unknown, groupItem: Array<unknown> } resultWithGroupItem: { result: unknown, groupItem: Array<unknown>; };
}>; }>;
downloadFile(commonFile: CommonFileInfo, arg2: unknown, arg3: unknown, savePath: string): unknown; downloadFile (arg1: unknown, arg2: number, arg3: number, arg4: string): unknown;
createGroupFolder(arg1: unknown, arg2: unknown): unknown; createGroupFolder (arg1: unknown, arg2: unknown): unknown;
downloadGroupFolder(arg1: unknown, arg2: unknown, arg3: unknown): unknown; downloadGroupFolder (arg1: string, arg2: string, arg3: string): unknown;
renameGroupFolder(arg1: unknown, arg2: unknown, arg3: unknown): unknown; renameGroupFolder (arg1: string, arg2: string, arg3: string): unknown;
deleteGroupFolder(arg1: unknown, arg2: unknown): unknown; deleteGroupFolder (arg1: unknown, arg2: unknown): unknown;
deleteTransferInfo(arg1: unknown, arg2: unknown): unknown; deleteTransferInfo (arg1: unknown, arg2: unknown): unknown;
cancelTransferTask(arg1: unknown, arg2: unknown, arg3: unknown): unknown; cancelTransferTask (arg1: Peer, arg2: Array<unknown>[], arg3: string): unknown;
cancelUrlDownload(arg: unknown): unknown; cancelUrlDownload (arg: unknown): unknown;
updateOnlineVideoElemStatus(arg: unknown): unknown; updateOnlineVideoElemStatus (arg: unknown): unknown;
getGroupSpace(arg: unknown): unknown; getGroupSpace (arg: unknown): unknown;
getGroupFileList(groupCode: string, params: GetFileListParam): Promise<GeneralCallResult & { getGroupFileList (groupCode: string, params: GetFileListParam): Promise<GeneralCallResult & {
groupSpaceResult: { groupSpaceResult: {
retCode: number retCode: number;
retMsg: string retMsg: string;
clientWording: string clientWording: string;
totalSpace: number totalSpace: number;
usedSpace: number usedSpace: number;
allUpload: boolean allUpload: boolean;
} };
}>; }>;
getGroupFileInfo(arg1: unknown, arg2: unknown): unknown; getGroupFileInfo (arg1: unknown, arg2: unknown): unknown;
getGroupTransferList(arg1: unknown, arg2: unknown): unknown; getGroupTransferList (arg1: string, arg2: unknown): unknown;
renameGroupFile(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown; renameGroupFile (arg1: string, arg2: number, arg3: string, arg4: string, arg5: string): unknown;
moveGroupFile(groupCode: string, busId: Array<number>, fileList: Array<string>, currentParentDirectory: string, targetParentDirectory: string): Promise<GeneralCallResult & { moveGroupFile (groupCode: string, busId: Array<number>, fileList: Array<string>, currentParentDirectory: string, targetParentDirectory: string): Promise<GeneralCallResult & {
moveGroupFileResult: { moveGroupFileResult: {
result: { result: {
retCode: number, retCode: number,
retMsg: symbol, retMsg: symbol,
clientWording: string clientWording: string;
}, },
successFileIdList: Array<string>, successFileIdList: Array<string>,
failFileIdList: Array<string> failFileIdList: Array<string>;
} };
}>; }>;
transGroupFile(groupCode: string, fileId: string): Promise<GeneralCallResult & { transGroupFile (groupCode: string, fileId: string): Promise<GeneralCallResult & {
transGroupFileResult: { transGroupFileResult: {
result: { result: {
retCode: number retCode: number;
retMsg: string retMsg: string;
clientWording: string clientWording: string;
} };
saveBusId: number saveBusId: number;
saveFilePath: string saveFilePath: string;
} };
}>; }>;
searchGroupFile( searchGroupFile (
keywords: Array<string>, keywords: Array<string>,
param: { param: {
groupIds: Array<string>, groupIds: Array<string>,
@@ -230,55 +230,57 @@ export interface NodeIKernelRichMediaService {
context: string, context: string,
count: number, count: number,
sortType: number, sortType: number,
groupNames: Array<string> groupNames: Array<string>;
}): Promise<unknown>; }): Promise<unknown>;
searchGroupFileByWord(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown; searchGroupFileByWord (arg1: unknown[], arg2: unknown[], arg3: string, arg4: string, arg5: number): unknown;
deleteGroupFile(GroupCode: string, params: Array<number>, Files: Array<string>): Promise<GeneralCallResult & { deleteGroupFile (GroupCode: string, params: Array<number>, Files: Array<string>): Promise<GeneralCallResult & {
transGroupFileResult: { transGroupFileResult: {
result: unknown result: unknown;
successFileIdList: Array<unknown> successFileIdList: Array<unknown>;
failFileIdList: Array<unknown> failFileIdList: Array<unknown>;
} };
}>; }>;
translateEnWordToZn(words: string[]): Promise<GeneralCallResult & { words: string[] }>; translateEnWordToZn (words: string[]): Promise<GeneralCallResult & { words: string[]; }>;
getScreenOCR(path: string): Promise<unknown>; getScreenOCR (path: string): Promise<unknown>;
batchGetGroupFileCount(Gids: Array<string>): Promise<GeneralCallResult & { batchGetGroupFileCount (Gids: Array<string>): Promise<GeneralCallResult & {
groupCodes: Array<string>, groupCodes: Array<string>,
groupFileCounts: Array<number> groupFileCounts: Array<number>;
}>; }>;
queryPicDownloadSize(arg: unknown): unknown; queryPicDownloadSize (arg: unknown): unknown;
searchGroupFile(arg1: unknown, arg2: unknown): unknown; searchGroupFile (arg1: unknown, arg2: unknown): unknown;
searchMoreGroupFile(arg: unknown): unknown; searchMoreGroupFile (arg: unknown): unknown;
cancelSearcheGroupFile(arg1: unknown, arg2: unknown, arg3: unknown): unknown; cancelSearcheGroupFile (arg1: number, arg2: number, arg3: string): unknown;
onlyDownloadFile(peer: Peer, arg2: unknown, arg3: Array<{ onlyDownloadFile (arg1: Peer, arg2: string, arg3: Array<unknown>[]): unknown;
fileId: string,
fileName: string,
fileSize: string,
fileModelId: string
}
>): unknown;
onlyUploadFile(arg1: unknown, arg2: unknown): unknown; onlyUploadFile (arg1: unknown, arg2: unknown): unknown;
isExtraLargePic(arg1: unknown, arg2: unknown, arg3: unknown): unknown; isExtraLargePic (arg1: unknown, arg2: unknown, arg3: unknown): unknown;
uploadRMFileWithoutMsg(arg: { uploadRMFileWithoutMsg (arg: {
bizType: RMBizTypeEnum, bizType: RMBizTypeEnum,
filePath: string, filePath: string,
peerUid: string, peerUid: string,
transferId: string transferId: string;
useNTV2: string useNTV2: string;
}): Promise<unknown>; }): Promise<unknown>;
isNull(): boolean; isNull (): boolean;
getRichMediaCodecInfo (arg: unknown): unknown;
getScreenOCRWithSourceType (arg1: unknown, arg2: unknown): unknown;
imageTranslate (arg1: string, arg2: string, arg3: number): unknown;
downloadFileByUrl (arg1: number, arg2: string, arg3: boolean): unknown;
} }

View File

@@ -2,47 +2,127 @@ import { NodeIKernelRobotListener } from '@/napcat-core/listeners';
import { GeneralCallResult, Peer } from '..'; import { GeneralCallResult, Peer } from '..';
export interface NodeIKernelRobotService { export interface NodeIKernelRobotService {
fetchGroupRobotStoreDiscovery(arg: unknown): unknown; addKernelRobotListener (listener: NodeIKernelRobotListener): number;
sendGroupRobotStoreSearch(arg: unknown): unknown; removeKernelRobotListener (listenerId: number): void;
fetchGroupRobotStoreCategoryList(arg: unknown): unknown; fetchGroupRobotStoreDiscovery (arg: unknown): unknown;
FetchSubscribeMsgTemplate(arg: unknown): unknown; fetchGroupRobotStoreCategoryList (arg: unknown): unknown;
FetchSubcribeMsgTemplateStatus(arg: unknown): unknown; FetchSubscribeMsgTemplate (arg: unknown): unknown;
SubscribeMsgTemplateSet(arg1: unknown, arg2: unknown): unknown; FetchSubcribeMsgTemplateStatus (arg: unknown): unknown;
fetchRecentUsedRobots(arg: unknown): unknown; SubscribeMsgTemplateSet (arg1: unknown, arg2: unknown): unknown;
fetchShareArkInfo(arg: unknown): unknown; fetchRecentUsedRobots (arg: unknown): unknown;
addKernelRobotListener(Listener: NodeIKernelRobotListener): number; fetchShareArkInfo (arg: unknown): unknown;
removeKernelRobotListener(ListenerId: number): unknown; getAllRobotFriendsFromCache (): Promise<unknown>;
getAllRobotFriendsFromCache(): Promise<unknown>; fetchAllRobots (arg1: boolean, arg2: unknown): unknown;
fetchAllRobots(arg1: unknown, arg2: unknown): unknown; removeAllRecommendCache (): unknown;
removeAllRecommendCache(): unknown; setRobotPickTts (arg1: unknown, arg2: unknown): unknown;
setRobotPickTts(arg1: unknown, arg2: unknown): unknown; getRobotUinRange (data: unknown): Promise<{ response: { robotUinRanges: Array<unknown>; }; }>;
getRobotUinRange(data: unknown): Promise<{ response: { robotUinRanges: Array<unknown> } }>; getRobotFunctions (peer: Peer, params: {
getRobotFunctions(peer: Peer, params: {
uins: Array<string>, uins: Array<string>,
num: 0, num: 0,
client_info: { platform: 4, version: '', build_num: 9999 }, client_info: { platform: 4, version: '', build_num: 9999; },
tinyids: [], tinyids: [],
page: 0, page: 0,
full_fetch: false, full_fetch: false,
scene: 4, scene: 4,
filter: 1, filter: 1,
bkn: '' bkn: '';
}): Promise<GeneralCallResult & { response: { bot_features: Array<unknown>, next_page: number } }>; }): Promise<GeneralCallResult & { response: { bot_features: Array<unknown>, next_page: number; }; }>;
isNull(): boolean; fetchRobotShareLimit (arg1: unknown, arg2: unknown): unknown;
updateGroupRobotProfile (arg1: unknown, arg2: unknown): unknown;
sendCommonRobotToGuild (arg1: unknown, arg2: unknown): unknown;
sendGroupRobotStoreSearch (arg: unknown): unknown;
fetchMyRobotLists (arg: unknown): unknown;
batchGetBotsMenu (arg: unknown): unknown;
fetchAddRobotGroupList (arg: unknown): unknown;
getGuildRobotList (arg: unknown): unknown;
querySessionList (arg: unknown): unknown;
fetchListRobot (arg: unknown): unknown;
subscribeGuildGlobalRobot (arg: unknown): unknown;
addGuildRobot (arg: unknown): unknown;
upMicGuildRobot (arg: unknown): unknown;
downMicGuildRobot (arg: unknown): unknown;
getRedDot (arg: unknown): unknown;
delRedDot (arg: unknown): unknown;
changeMyBot (arg: unknown): unknown;
getAudioLiveRobotStatus (arg: unknown): unknown;
backFlowRobotCoreInfos (arg: unknown): unknown;
batchFetchRobotCoreInfos (arg: unknown): unknown;
queryPicRecomQuestions (arg: unknown): unknown;
delSessionMsgs (arg: unknown): unknown;
fetchMobileRobotRecommendCards (arg: unknown): unknown;
saveSelectedAIModelOrOptIds (arg: unknown): unknown;
setRobotStoryEnter (arg: unknown): unknown;
aiGenAvatar (arg: unknown): unknown;
fetchRobotFeatureWithReq (arg: unknown): unknown;
fetchGroupRobotProfileWithReq (arg: unknown): unknown;
setAddRobotToGroup (arg: unknown): unknown;
setRemoveRobotFromGroup (arg: unknown): unknown;
FetchGroupRobotInfo (arg: unknown): unknown;
fetchGuildRobotInfo (arg: unknown): unknown;
aiGenBotInfo (arg: unknown): unknown;
fetchAiGenTemplateInfo (arg: unknown): unknown;
fetchShareInfo (arg: unknown): unknown;
updateShareInfo (arg: unknown): unknown;
queryGuildGlobalRobotSubscription (arg: unknown): unknown;
resetConversation (arg: unknown): unknown;
setGuildRobotPermission (arg: unknown): unknown;
fetchGuildRobotPermission (arg: unknown): unknown;
editSession (arg: unknown): unknown;
isNull (): boolean;
} }

View File

@@ -3,134 +3,146 @@ import { GeneralCallResult } from './common';
export interface NodeIKernelSearchService { export interface NodeIKernelSearchService {
addKernelSearchListener(listener: unknown): number; addKernelSearchListener (listener: unknown): number;
removeKernelSearchListener(listenerId: number): void; removeKernelSearchListener (listenerId: number): void;
searchStranger(unknown: string, searchStranger: unknown, searchParams: unknown): Promise<unknown>; searchStranger (keyword: string, searchType: unknown, searchParams: unknown): Promise<unknown>;
searchGroup(param: { searchGroup (param: {
keyWords: string, keyWords: string,
groupNum: number, groupNum: number,
exactSearch: boolean, exactSearch: boolean,
penetrate: string penetrate: string;
}): Promise<GeneralCallResult>;// needs 1 arguments }): Promise<GeneralCallResult>;
searchLocalInfo(keywords: string, type: number/* 4 */): unknown; searchLocalInfo (keywords: string, type: number): unknown;
cancelSearchLocalInfo(...args: unknown[]): unknown;// needs 3 arguments cancelSearchLocalInfo (arg1: number, arg2: number, arg3: string): unknown;
searchBuddyChatInfo(...args: unknown[]): unknown;// needs 2 arguments searchBuddyChatInfo (arg1: unknown, arg2: unknown): unknown;
searchMoreBuddyChatInfo(...args: unknown[]): unknown;// needs 1 arguments searchMoreBuddyChatInfo (arg: unknown): unknown;
cancelSearchBuddyChatInfo(...args: unknown[]): unknown;// needs 3 arguments cancelSearchBuddyChatInfo (arg1: number, arg2: number, arg3: string): unknown;
searchContact(...args: unknown[]): unknown;// needs 2 arguments searchContact (arg1: Array<unknown>[], arg2: unknown): unknown;
searchMoreContact(...args: unknown[]): unknown;// needs 1 arguments searchMoreContact (arg: unknown): unknown;
cancelSearchContact(...args: unknown[]): unknown;// needs 3 arguments cancelSearchContact (arg1: number, arg2: number, arg3: string): unknown;
searchGroupChatInfo(...args: unknown[]): unknown;// needs 3 arguments searchGroupChatInfo (arg1: unknown[], arg2: unknown, arg3: number): unknown;
resetSearchGroupChatInfoSortType(...args: unknown[]): unknown;// needs 3 arguments resetSearchGroupChatInfoSortType (arg1: number, arg2: number, arg3: number): unknown;
resetSearchGroupChatInfoFilterMembers(...args: unknown[]): unknown;// needs 3 arguments resetSearchGroupChatInfoFilterMembers (arg1: number, arg2: Array<unknown>[], arg3: number): unknown;
searchMoreGroupChatInfo(...args: unknown[]): unknown;// needs 1 arguments searchMoreGroupChatInfo (arg: unknown): unknown;
cancelSearchGroupChatInfo(...args: unknown[]): unknown;// needs 3 arguments cancelSearchGroupChatInfo (arg1: number, arg2: number, arg3: string): unknown;
searchChatsWithKeywords(...args: unknown[]): unknown;// needs 3 arguments searchChatsWithKeywords (arg1: unknown[], arg2: number, arg3: number): unknown;
searchMoreChatsWithKeywords(...args: unknown[]): unknown;// needs 1 arguments searchMoreChatsWithKeywords (arg: unknown): unknown;
cancelSearchChatsWithKeywords(...args: unknown[]): unknown;// needs 3 arguments cancelSearchChatsWithKeywords (arg1: number, arg2: number, arg3: string): unknown;
searchChatMsgs(...args: unknown[]): unknown;// needs 2 arguments searchChatMsgs (arg1: Array<unknown>[], arg2: unknown): unknown;
searchMoreChatMsgs(...args: unknown[]): unknown;// needs 1 arguments searchMoreChatMsgs (arg: unknown): unknown;
cancelSearchChatMsgs(...args: unknown[]): unknown;// needs 3 arguments cancelSearchChatMsgs (arg1: number, arg2: number, arg3: string): unknown;
searchMsgWithKeywords(keyWords: string[], param: Peer & { searchFields: number, pageLimit: number }): Promise<GeneralCallResult>; searchMsgWithKeywords (keyWords: string[], param: Peer & { searchFields: number, pageLimit: number; }): Promise<GeneralCallResult>;
searchMoreMsgWithKeywords(...args: unknown[]): unknown;// needs 1 arguments searchMoreMsgWithKeywords (arg: unknown): unknown;
cancelSearchMsgWithKeywords(...args: unknown[]): unknown;// needs 3 arguments cancelSearchMsgWithKeywords (arg1: number, arg2: number, arg3: string): unknown;
searchFileWithKeywords(keywords: string[], source: number): Promise<string>;// needs 2 arguments searchFileWithKeywords (keywords: string[], source: number): Promise<string>;
searchMoreFileWithKeywords(...args: unknown[]): unknown;// needs 1 arguments searchMoreFileWithKeywords (arg: unknown): unknown;
cancelSearchFileWithKeywords(...args: unknown[]): unknown;// needs 3 arguments cancelSearchFileWithKeywords (arg1: number, arg2: number, arg3: string): unknown;
searchAtMeChats(...args: unknown[]): unknown;// needs 3 arguments searchFileInFileCenterForPC (arg1: unknown, arg2: unknown): unknown;
searchMoreAtMeChats(...args: unknown[]): unknown;// needs 1 arguments searchMoreFileInFileCenter (arg: unknown): unknown;
cancelSearchAtMeChats(...args: unknown[]): unknown;// needs 3 arguments cancelSearchFileInFileCenter (arg1: number, arg2: number, arg3: string): unknown;
searchChatAtMeMsgs(...args: unknown[]): unknown;// needs 1 arguments searchAtMeChats (arg1: boolean, arg2: number, arg3: number): unknown;
searchMoreChatAtMeMsgs(...args: unknown[]): unknown;// needs 1 arguments searchMoreAtMeChats (arg: unknown): unknown;
cancelSearchChatAtMeMsgs(...args: unknown[]): unknown;// needs 3 arguments cancelSearchAtMeChats (arg1: number, arg2: number, arg3: string): unknown;
addSearchHistory(param: { searchChatAtMeMsgs (arg: unknown): unknown;
type: number, // 4
searchMoreChatAtMeMsgs (arg: unknown): unknown;
cancelSearchChatAtMeMsgs (arg1: number, arg2: number, arg3: string): unknown;
searchRobot (arg: unknown): unknown;
searchCache (arg1: string, arg2: string, arg3: unknown): unknown;
addSearchHistory (param: {
type: number,
contactList: [], contactList: [],
id: number, // -1 id: number,
groupInfos: [], groupInfos: [],
msgs: [], msgs: [],
fileInfos: [ fileInfos: Array<{
{ chatType: ChatType,
chatType: ChatType, buddyChatInfo: Array<{ category_name: string, peerUid: string, peerUin: string, remark: string; }>,
buddyChatInfo: Array<{ category_name: string, peerUid: string, peerUin: string, remark: string }>, discussChatInfo: [],
discussChatInfo: [], groupChatInfo: Array<{
groupChatInfo: Array< groupCode: string,
{ isConf: boolean,
groupCode: string, hasModifyConfGroupFace: boolean,
isConf: boolean, hasModifyConfGroupName: boolean,
hasModifyConfGroupFace: boolean, groupName: string,
hasModifyConfGroupName: boolean, remark: string;
groupName: string, }>,
remark: string dataLineChatInfo: [],
}>, tmpChatInfo: [],
dataLineChatInfo: [], msgId: string,
tmpChatInfo: [], msgSeq: string,
msgId: string, msgTime: string,
msgSeq: string, senderUid: string,
msgTime: string, senderNick: string,
senderUid: string, senderRemark: string,
senderNick: string, senderCard: string,
senderRemark: string, elemId: string,
senderCard: string, elemType: string,
elemId: string, fileSize: string,
elemType: string, // 3 filePath: string,
fileSize: string, fileName: string,
filePath: string, hits: Array<{ start: number, end: number; }>;
fileName: string, }>;
hits: Array<
{
start: 12,
end: 14
}
>
}
]
}): Promise<{ }): Promise<{
result: number, result: number,
errMsg: string, errMsg: string,
id?: number id?: number;
}>; }>;
removeSearchHistory(...args: unknown[]): unknown;// needs 1 arguments removeSearchHistory (arg: unknown): unknown;
searchCache(...args: unknown[]): unknown;// needs 3 arguments addOrUpdateSearchMostUseItem (arg1: unknown, arg2: unknown): unknown;
clearSearchCache(...args: unknown[]): unknown;// needs 1 arguments getSearchMostUseItem (arg: unknown): unknown;
deleteSearchMostUseItem (arg: unknown): unknown;
deleteGroupHistoryFile (arg: unknown): unknown;
clearSearchCache (arg: unknown): unknown;
clearSearchHistory (): unknown;
loadSearchHistory (): unknown;
initTokenizeUtil (): unknown;
} }

View File

@@ -0,0 +1,53 @@
export interface NodeIKernelSettingService {
addKernelSettingListener (listener: unknown): number;
removeKernelSettingListener (listenerId: number): void;
getSettingForBuffer (key: unknown): unknown;
getSettingForNum (key: unknown): unknown;
getSettingForStr (key: unknown): unknown;
setSettingForBuffer (arg: unknown): unknown;
setSettingForNum (arg: unknown): unknown;
setSettingForStr (arg: unknown): unknown;
setAutoLoginSwitch (enabled: boolean): unknown;
setNeedConfirmSwitch (enabled: boolean): unknown;
setPrivacySetting (arg: unknown): unknown;
setSelfStartSwitch (enabled: boolean): unknown;
modifyAccount (arg: unknown): unknown;
verifyNewAccount (arg: unknown): unknown;
openUrlWithQQBrowser (url: string): unknown;
openUrlInIM (url: string): unknown;
clearCache (arg: unknown): unknown;
destroyAccount (): unknown;
isQQBrowserInstall (): boolean;
getSelfStartSwitch (): unknown;
getAutoLoginSwitch (): unknown;
getNeedConfirmSwitch (): unknown;
getPrivacySetting (): unknown;
scanCache (): unknown;
getQQBrowserSwitchFromQldQQ (): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,21 @@
export interface NodeIKernelSkinService {
addKernelSkinListener (listener: unknown): number;
removeKernelSkinListener (listenerId: number): void;
getRecommendAIOColor (arg1: unknown, arg2: unknown): unknown;
getRecommendBubbleColor (arg1: unknown, arg2: unknown): unknown;
getThemeInfoFromImage (arg: unknown): unknown;
previewTheme (arg1: number, arg2: unknown, arg3: unknown): unknown;
setTemplateCustomPrimaryColor (arg1: unknown, arg2: unknown): unknown;
setThemeInfo (arg1: number, arg2: unknown, arg3: unknown): unknown;
uploadImage (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -36,15 +36,15 @@ export interface NodeIKernelStorageCleanService {
reportData (): unknown; reportData (): unknown;
getChatCacheInfo (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown): unknown; getChatCacheInfo (tableType: number, pageSize: number, order: number, startPosition: number): Promise<unknown>;
getFileCacheInfo (arg1: unknown, arg2: unknown, arg3: unknown, arg44: unknown, args5: unknown): unknown; getFileCacheInfo (fileType: number, restart: boolean, pageSize: number, lastRecord: number, param: unknown): Promise<unknown>;
clearChatCacheInfo (arg1: unknown, arg2: unknown): unknown; clearChatCacheInfo (chatInfoList: unknown[], clearKeys: number[]): Promise<unknown>;
clearCacheDataByKeys (keys: Array<string>): Promise<GeneralCallResult>; clearCacheDataByKeys (keys: Array<string>): Promise<GeneralCallResult>;
setSilentScan (is_silent: boolean): unknown; setSilentScan (isSilent: boolean): unknown;
closeCleanWindow (): unknown; closeCleanWindow (): unknown;

View File

@@ -0,0 +1,17 @@
export interface NodeIKernelThirdPartySigService {
addOnSigChangeListener (listener: unknown): number;
removeSigChangeListener (listenerId: number): void;
initConfig (arg: unknown): unknown;
delThirdPartySigByUin (arg: unknown): unknown;
getOpenIDByUin (arg1: string, arg2: number, arg3: string): unknown;
getPT4tokenByUin (arg1: string, arg2: number, arg3: Array<unknown>[]): unknown;
getThirdPartySigByUin (arg1: string, arg2: number, arg3: number, arg4: number, arg5: string, arg6: string): unknown;
isNull (): boolean;
}

View File

@@ -1,8 +1,8 @@
export interface NodeIKernelTianShuService { export interface NodeIKernelTianShuService {
addKernelTianShuListener(listener:unknown): number; addKernelTianShuListener (listener: unknown): number;
removeKernelTianShuListener(listenerId:number): void; removeKernelTianShuListener (listenerId: number): void;
reportTianShuNumeralRed(...args: unknown[]): unknown;// needs 1 arguments reportTianShuNumeralRed (arg: unknown): unknown;// needs 1 arguments
} }

View File

@@ -2,11 +2,11 @@ import { ForceFetchClientKeyRetType } from './common';
export interface NodeIKernelTicketService { export interface NodeIKernelTicketService {
addKernelTicketListener(listener: unknown): number; addKernelTicketListener (listener: unknown): number;
removeKernelTicketListener(listenerId: number): void; removeKernelTicketListener (listenerId: number): void;
forceFetchClientKey(arg: string): Promise<ForceFetchClientKeyRetType>; forceFetchClientKey (arg: string): Promise<ForceFetchClientKeyRetType>;
isNull(): boolean; isNull (): boolean;
} }

View File

@@ -2,21 +2,19 @@ import { GeneralCallResult } from './common';
export interface NodeIKernelTipOffService { export interface NodeIKernelTipOffService {
addKernelTipOffListener(listener: unknown): number; addKernelTipOffListener (listener: unknown): number;
removeKernelTipOffListener(listenerId: unknown): void; removeKernelTipOffListener (listenerId: number): void;
tipOffSendJsData(args: unknown[]): Promise<unknown>;// 2 tipOffSendJsData (arg1: unknown, arg2: unknown): Promise<unknown>;
getPskey(domainList: string[], nocache: boolean): Promise<GeneralCallResult & { getPskey (domainList: string[], nocache: boolean): Promise<GeneralCallResult & {
domainPskeyMap: Map<string, string> domainPskeyMap: Map<string, string>;
}>; }>;
tipOffSendJsData(args: unknown[]): Promise<unknown>;// 2 tipOffMsgs (arg: unknown): Promise<unknown>;
tipOffMsgs(args: unknown[]): Promise<unknown>;// 1 encodeUinAesInfo (arg1: unknown, arg2: unknown): Promise<unknown>;
encodeUinAesInfo(args: unknown[]): Promise<unknown>;// 2 isNull (): boolean;
isNull(): boolean;
} }

View File

@@ -0,0 +1,23 @@
export interface NodeIKernelUnifySearchService {
checkAIAuth (arg: unknown): unknown;
getNetResultTabs (arg: unknown): unknown;
getNetSugWords (arg: unknown): unknown;
getSearchAppendingInfo (arg: unknown): unknown;
getSearchBoxSugWords (arg: unknown): unknown;
search (arg: unknown): unknown;
unifySearch (arg: unknown): unknown;
unifySearchDiscovery (arg: unknown): unknown;
unifySearchDiscoveryInCache (arg: unknown): unknown;
wxSearchReport (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -1,17 +1,17 @@
export interface NodeIKernelUnitedConfigService { export interface NodeIKernelUnitedConfigService {
addKernelUnitedConfigListener(listener:unknown): number; addKernelUnitedConfigListener (listener: unknown): number;
removeKernelUnitedConfigListener(listenerId:number): void; removeKernelUnitedConfigListener (listenerId: number): void;
fetchUnitedSwitchConfig(...args: unknown[]): unknown;// needs 1 arguments fetchUnitedSwitchConfig (configIds: string[]): void;
isUnitedConfigSwitchOn(...args: unknown[]): unknown;// needs 1 arguments isUnitedConfigSwitchOn (configId: string): boolean;
registerUnitedConfigPushGroupList(...args: unknown[]): unknown;// needs 1 arguments registerUnitedConfigPushGroupList (groupList: string[]): void;
fetchUnitedCommendConfig(ids: `${string}`[]): void fetchUnitedCommendConfig (ids: string[]): void;
loadUnitedConfig(id: string): Promise<unknown> loadUnitedConfig (id: string): Promise<unknown>;
} }

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelVasSystemUpdateService {
getResPath (arg: unknown): unknown;
isExist (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,37 @@
export interface NodeIKernelWiFiPhotoClientService {
addKernelWiFiPhotoClientListener (listener: unknown): number;
removeKernelWiFiPhotoClientListener (listenerId: number): void;
cancelGetPhoto (arg1: unknown, arg2: unknown): unknown;
cancelGetPhotoThumbBatch (arg: unknown): unknown;
cancelRequest (arg: unknown): unknown;
connectToHostForTest (arg: unknown): unknown;
deletePhotoBatch (arg: unknown): unknown;
disconnect (arg: unknown): unknown;
getAlbumFileSavePath (arg: unknown): unknown;
getAllPhotoSimpleInfo (arg: unknown): unknown;
getPhotoAndSaveAs (arg1: string, arg2: string, arg3: string): unknown;
getPhotoBatch (arg1: unknown, arg2: unknown): unknown;
getPhotoInfoBatch (arg1: unknown, arg2: unknown): unknown;
getPhotoSimpleInfoForFirstView (arg1: string, arg2: number): unknown;
getPhotoThumbBatchWithConfig (arg1: unknown, arg2: unknown): unknown;
getWiFiPhotoDownFileInfos (arg1: string, arg2: Array<unknown>[]): unknown;
resumeUncompleteDownloadRecords (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,15 @@
export interface NodeIKernelWiFiPhotoHostService {
addKernelWiFiPhotoHostListener (listener: unknown): number;
removeKernelWiFiPhotoHostListener (listenerId: number): void;
acceptRequest (arg1: number, arg2: unknown): unknown;
disconnect (arg: unknown): unknown;
rejectRequest (arg1: number, arg2: number): unknown;
setAlbumAccessDelegate (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -0,0 +1,7 @@
export interface NodeIKernelYellowFaceForManagerService {
download (arg1: string, arg2: string, arg3: string, arg4: boolean): unknown;
setHistory (arg: unknown): unknown;
isNull (): boolean;
}

View File

@@ -1,11 +1,15 @@
import { NodeIO3MiscListener } from '@/napcat-core/listeners/NodeIO3MiscListener'; import { NodeIO3MiscListener } from '@/napcat-core/listeners/NodeIO3MiscListener';
export interface NodeIO3MiscService { export interface NodeIO3MiscService {
get(): NodeIO3MiscService; get (): NodeIO3MiscService;
addO3MiscListener(listeners: NodeIO3MiscListener): number; addO3MiscListener (listener: NodeIO3MiscListener): number;
setAmgomDataPiece(appid: string, dataPiece: Uint8Array): void; removeO3MiscListener (listenerId: number): void;
reportAmgomWeather(type: string, uk2: string, arg: Array<string>): void; passthroughO3Data (arg1: unknown, arg2: unknown): unknown;
reportAmgomWeather (arg1: unknown, arg2: unknown, arg3: unknown): unknown;
setAmgomDataPiece (appid: string, dataPiece: Uint8Array): void;
} }

View File

@@ -1,5 +1,11 @@
export interface NodeIYellowFaceService { export interface NodeIYellowFaceService {
download(resourceConfigJson: string, resourceDir: string, cacheDir: string, force: boolean): void; addListener (listener: unknown): number;
setHistory(fullMd5: string): void; removeListener (listenerId: number): void;
download (resourceConfigJson: string, resourceDir: string, cacheDir: string, force: boolean): void;
setHistory (fullMd5: string): void;
update (arg: unknown): unknown;
} }

View File

@@ -36,6 +36,36 @@ export * from './NodeIKernelDbToolsService';
export * from './NodeIKernelTipOffService'; export * from './NodeIKernelTipOffService';
export * from './NodeIKernelSearchService'; export * from './NodeIKernelSearchService';
export * from './NodeIKernelCollectionService'; export * from './NodeIKernelCollectionService';
// === New service exports from IDA analysis ===
export * from './NodeIKernelSettingService';
export * from './NodeIKernelQiDianService';
export * from './NodeIKernelSkinService';
export * from './NodeIKernelQQPlayService';
export * from './NodeIKernelRDeliveryService';
export * from './NodeIKernelRemotingService';
export * from './NodeIKernelLiteBusinessService';
export * from './NodeIKernelGroupTabService';
export * from './NodeIKernelLockService';
export * from './NodeIKernelHandOffService';
export * from './NodeIKernelMiniAppService';
export * from './NodeIKernelPublicAccountService';
export * from './NodeIKernelThirdPartySigService';
export * from './NodeIKernelUnifySearchService';
export * from './NodeIKernelVasSystemUpdateService';
export * from './NodeIKernelPersonalAlbumService';
export * from './NodeIKernelConfigMgrService';
export * from './NodeIKernelFeedService';
export * from './NodeIKernelBdhUploadService';
export * from './NodeIKernelDirectSessionService';
export * from './NodeIKernelFileBridgeClientService';
export * from './NodeIKernelFileBridgeHostService';
export * from './NodeIKernelWiFiPhotoHostService';
export * from './NodeIKernelWiFiPhotoClientService';
export * from './NodeIKernelEmojiService';
export * from './NodeIKernelNearbyProService';
export * from './NodeIKernelAVSDKService';
export * from './NodeIKernelAddBuddyService';
export * from './NodeIKernelYellowFaceForManagerService';
export type ServiceNamingMapping = { export type ServiceNamingMapping = {
NodeIKernelAvatarService: NodeIKernelAvatarService; NodeIKernelAvatarService: NodeIKernelAvatarService;
@@ -53,6 +83,6 @@ export type ServiceNamingMapping = {
NodeIKernelRichMediaService: NodeIKernelRichMediaService; NodeIKernelRichMediaService: NodeIKernelRichMediaService;
NodeIKernelDbToolsService: NodeIKernelDbToolsService; NodeIKernelDbToolsService: NodeIKernelDbToolsService;
NodeIKernelTipOffService: NodeIKernelTipOffService; NodeIKernelTipOffService: NodeIKernelTipOffService;
NodeIKernelSearchService: NodeIKernelSearchService, NodeIKernelSearchService: NodeIKernelSearchService;
NodeIKernelCollectionService: NodeIKernelCollectionService; NodeIKernelCollectionService: NodeIKernelCollectionService;
}; };

View File

@@ -323,7 +323,7 @@ export interface FlashTransferInfo {
id: string; id: string;
urls: FlashTransferIcon[]; urls: FlashTransferIcon[];
localCachePath: string; localCachePath: string;
} };
} }
/** /**
@@ -337,7 +337,7 @@ export interface MarkdownElement {
mdExtType?: number; mdExtType?: number;
mdExtInfo?: { mdExtInfo?: {
flashTransferInfo: FlashTransferInfo; flashTransferInfo: FlashTransferInfo;
} };
} }
/** /**
@@ -550,6 +550,96 @@ export interface QueryMsgsParams {
isIncludeCurrent: boolean; isIncludeCurrent: boolean;
} }
/**
* 消息引用标识msgId + msgSeq + msgTime
*/
export interface MsgRef {
msgId: string;
msgSeq: string;
msgTime: string;
}
/**
* 消息完整标识含cliSeq和msgRandom
*/
export interface MsgIdentity {
msgId: string;
msgSeq: string;
cliSeq: string;
msgTime: string;
msgRandom: string;
}
/**
* 灰条JSON消息信息
*/
export interface GrayTipJsonInfo {
busiId: number | string;
jsonStr: string;
recentAbstract: string;
isServer: boolean;
xmlToJsonParam?: unknown;
}
/**
* 转发文件信息
*/
export interface ForwardFileInfo {
targetMsgId: string;
targetElemId: string;
commonFileInfo: unknown;
}
/**
* 本地灰条提示信息
*/
export interface LocalGrayTipInfo {
type: number;
robot?: unknown;
direct?: unknown;
extraJson: string;
}
/**
* Token设置信息
*/
export interface TokenInfo {
tokenType: number;
apnsToken?: string | Uint8Array;
voipToken?: string | Uint8Array;
profileId?: string;
}
/**
* 后台切换时的未读计数信息
*/
export interface BackGroundInfo {
c2cUnreadCnt: number;
groupUnreadCnt: number;
guildUnreadCnt: number;
guildPsvboxUnreadCnt: number;
verifyUnreadCnt: number;
contactUnreadCnt: number;
groupUnreadCodes: string[];
}
/**
* 消息类型过滤参数
*/
export interface MsgTypeFilter {
filterMsgType: Array<{ type: number; subType: Array<number>; }>;
filterSendersUid: string[];
}
/**
* 空间流参数
*/
export interface SgrpStreamParams {
sgrpStreamPginSourceName: string;
sgrpVisitFrom: string;
sgrpSessionId: string;
}
/** /**
* 临时聊天信息API接口 * 临时聊天信息API接口
*/ */

View File

@@ -29,6 +29,28 @@ import { NodeIkernelTestPerformanceService } from './services/NodeIkernelTestPer
import { NodeIKernelECDHService } from './services/NodeIKernelECDHService'; import { NodeIKernelECDHService } from './services/NodeIKernelECDHService';
import { NodeIO3MiscService } from './services/NodeIO3MiscService'; import { NodeIO3MiscService } from './services/NodeIO3MiscService';
import { NodeIKernelFlashTransferService } from './services/NodeIKernelFlashTransferService'; import { NodeIKernelFlashTransferService } from './services/NodeIKernelFlashTransferService';
import { NodeIKernelOnlineStatusService } from './services/NodeIKernelOnlineStatusService';
import { NodeIKernelBaseEmojiService } from './services/NodeIKernelBaseEmojiService';
import { NodeIKernelSettingService } from './services/NodeIKernelSettingService';
import { NodeIKernelFileAssistantService } from './services/NodeIKernelFileAssistantService';
import { NodeIKernelDbToolsService } from './services/NodeIKernelDbToolsService';
import { NodeIYellowFaceService } from './services/NodeIYellowFaceService';
import { NodeIKernelQiDianService } from './services/NodeIKernelQiDianService';
import { NodeIKernelSkinService } from './services/NodeIKernelSkinService';
import { NodeIKernelQQPlayService } from './services/NodeIKernelQQPlayService';
import { NodeIKernelRDeliveryService } from './services/NodeIKernelRDeliveryService';
import { NodeIKernelRemotingService } from './services/NodeIKernelRemotingService';
import { NodeIKernelLiteBusinessService } from './services/NodeIKernelLiteBusinessService';
import { NodeIKernelGroupTabService } from './services/NodeIKernelGroupTabService';
import { NodeIKernelLockService } from './services/NodeIKernelLockService';
import { NodeIKernelHandOffService } from './services/NodeIKernelHandOffService';
import { NodeIKernelMiniAppService } from './services/NodeIKernelMiniAppService';
import { NodeIKernelPublicAccountService } from './services/NodeIKernelPublicAccountService';
import { NodeIKernelThirdPartySigService } from './services/NodeIKernelThirdPartySigService';
import { NodeIKernelUnifySearchService } from './services/NodeIKernelUnifySearchService';
import { NodeIKernelVasSystemUpdateService } from './services/NodeIKernelVasSystemUpdateService';
import { NodeIKernelPersonalAlbumService } from './services/NodeIKernelPersonalAlbumService';
import { NodeIKernelConfigMgrService } from './services/NodeIKernelConfigMgrService';
export interface NodeQQNTWrapperUtil { export interface NodeQQNTWrapperUtil {
get (): NodeQQNTWrapperUtil; get (): NodeQQNTWrapperUtil;
@@ -39,46 +61,46 @@ export interface NodeQQNTWrapperUtil {
getSsoCmdOfOidbReq (arg1: number, arg2: number): unknown; getSsoCmdOfOidbReq (arg1: number, arg2: number): unknown;
getSsoBufferOfOidbReq (...args: unknown[]): unknown; // 有点看不懂参数定义 待补充 好像是三个参数 getSsoBufferOfOidbReq (arg1: unknown, arg2: unknown, arg3: unknown): unknown;
getOidbRspInfo (arg: string): unknown; // 可能是错的 getOidbRspInfo (arg: string): unknown;
getFileSize (path: string): Promise<number>; // 直接的猜测 getFileSize (path: string): Promise<number>;
genFileMd5Buf (arg: string): unknown; // 可能是错的 genFileMd5Buf (arg: string): unknown;
genFileMd5Hex (path: string): unknown; // 直接的猜测 genFileMd5Hex (path: string): unknown;
genFileShaBuf (path: string): unknown; // 直接的猜测 genFileShaBuf (path: string): unknown;
genFileCumulateSha1 (path: string): unknown; // 直接的猜测 genFileCumulateSha1 (path: string): unknown;
genFileShaHex (path: string): unknown; // 直接的猜测 genFileShaHex (path: string): unknown;
fileIsExist (path: string): unknown; fileIsExist (path: string): unknown;
startTrace (path: string): unknown; // 可能是错的 startTrace (path: string): unknown;
copyFile (src: string, dst: string): unknown; copyFile (src: string, dst: string): unknown;
genFileShaAndMd5Hex (path: string, unknown: number): unknown; // 可能是错的 genFileShaAndMd5Hex (path: string, unknown: number): unknown;
setTraceInfo (unknown: unknown): unknown; setTraceInfo (unknown: unknown): unknown;
encodeOffLine (unknown: unknown): unknown; encodeOffLine (unknown: unknown): unknown;
decodeOffLine (arg: string): unknown; // 可能是错的 传递hex decodeOffLine (arg: string): unknown;
DecoderRecentInfo (arg: string): unknown; // 可能是错的 传递hex DecoderRecentInfo (arg: string): unknown;
getPinyin (arg0: string, arg1: boolean): unknown; getPinyin (arg0: string, arg1: boolean): unknown;
matchInPinyin (arg0: unknown[], arg1: string): unknown; // 参数特复杂 arg0是个复杂数据类型 getPinyinExt (arg0: string, arg1: boolean): unknown;
matchInPinyin (arg0: unknown[], arg1: string): unknown;
makeDirByPath (arg0: string): unknown; makeDirByPath (arg0: string): unknown;
emptyWorkingSet (arg0: number): unknown; // 参数是UINT32
runProcess (arg0: string, arg1: boolean): unknown; runProcess (arg0: string, arg1: boolean): unknown;
runProcessArgs (arg0: string, arg1: { [key: string]: string; }, arg2: boolean): unknown; runProcessArgs (arg0: string, arg1: { [key: string]: string; }, arg2: boolean): unknown;
@@ -141,6 +163,24 @@ export interface NodeQQNTWrapperUtil {
isNull (): unknown; isNull (): unknown;
deletePath (path: string): unknown;
calculateDirectoryTotalSize (path: string): unknown;
GetBaseEmojiPathByIds (arg: unknown): unknown;
SetMobileBaseEmojiPath (arg0: unknown, arg1: unknown): unknown;
setCreateThumbailSupportedFileExtensions (arg0: unknown, arg1: unknown): unknown;
setFileDropNativeWindowHide (arg: unknown): unknown;
setFileDropWindowNativeWindowHandle (arg: unknown): unknown;
startListenFileDragEvent (arg: unknown): unknown;
stopAccessingSecurityScopedResource (arg: unknown): unknown;
createThumbnailImage ( createThumbnailImage (
serviceName: string, serviceName: string,
filePath: string, filePath: string,
@@ -180,6 +220,43 @@ export interface NodeIQQNTWrapperSession {
startNT (): void; startNT (): void;
// === Session lifecycle ===
close (arg: unknown): void;
onLine (arg: unknown): void;
offLine (arg: unknown): void;
disableIpDirect (arg: unknown): void;
getAccountPath (arg: unknown): string;
updateTicket (arg: unknown): void;
// === SSO/Network dispatch ===
onDispatchPush (arg1: unknown, arg2: unknown): void;
onDispatchPushWithJson (arg1: unknown, arg2: unknown): void;
onDispatchRequestReply (arg1: unknown, arg2: unknown, arg3: unknown): void;
onMsfPush (arg1: unknown, arg2: unknown, arg3: unknown): void;
onNetReply (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown): void;
onSendOidbReply (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): void;
onSendSSOReply (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): void;
onUIConfigUpdate (arg1: unknown, arg2: unknown): void;
setOnMsfStatusChanged (arg1: unknown, arg2: unknown, arg3: unknown): void;
setOnNetworkChanged (arg: unknown): void;
setOnWeakNetChanged (arg: unknown): void;
// === Service getters ===
getBdhUploadService (): unknown; getBdhUploadService (): unknown;
getECDHService (): NodeIKernelECDHService; getECDHService (): NodeIKernelECDHService;
@@ -220,47 +297,47 @@ export interface NodeIQQNTWrapperSession {
getDirectSessionService (): unknown; getDirectSessionService (): unknown;
getRDeliveryService (): unknown; getRDeliveryService (): NodeIKernelRDeliveryService;
getAvatarService (): NodeIKernelAvatarService; getAvatarService (): NodeIKernelAvatarService;
getFeedChannelService (): unknown; getFeedChannelService (): unknown;
getYellowFaceService (): unknown; getYellowFaceService (): NodeIYellowFaceService;
getCollectionService (): NodeIKernelCollectionService; getCollectionService (): NodeIKernelCollectionService;
getSettingService (): unknown; getSettingService (): NodeIKernelSettingService;
getQiDianService (): unknown; getQiDianService (): NodeIKernelQiDianService;
getFileAssistantService (): unknown; getFileAssistantService (): NodeIKernelFileAssistantService;
getGuildService (): unknown; getGuildService (): unknown;
getSkinService (): unknown; getSkinService (): NodeIKernelSkinService;
getTestPerformanceService (): NodeIkernelTestPerformanceService; getTestPerformanceService (): NodeIkernelTestPerformanceService;
getQQPlayService (): unknown; getQQPlayService (): NodeIKernelQQPlayService;
getDbToolsService (): unknown; getDbToolsService (): NodeIKernelDbToolsService;
getUixConvertService (): NodeIKernelUixConvertService; getUixConvertService (): NodeIKernelUixConvertService;
getOnlineStatusService (): unknown; getOnlineStatusService (): NodeIKernelOnlineStatusService;
getRemotingService (): unknown; getRemotingService (): NodeIKernelRemotingService;
getGroupTabService (): unknown; getGroupTabService (): NodeIKernelGroupTabService;
getGroupSchoolService (): unknown; getGroupSchoolService (): unknown;
getLiteBusinessService (): unknown; getLiteBusinessService (): NodeIKernelLiteBusinessService;
getGuildMsgService (): unknown; getGuildMsgService (): unknown;
getLockService (): unknown; getLockService (): NodeIKernelLockService;
getMSFService (): NodeIKernelMSFService; getMSFService (): NodeIKernelMSFService;
@@ -270,7 +347,29 @@ export interface NodeIQQNTWrapperSession {
getRecentContactService (): NodeIKernelRecentContactService; getRecentContactService (): NodeIKernelRecentContactService;
getConfigMgrService (): unknown; getConfigMgrService (): NodeIKernelConfigMgrService;
getBaseEmojiService (): NodeIKernelBaseEmojiService;
getHandOffService (): NodeIKernelHandOffService;
getMiniAppService (): NodeIKernelMiniAppService;
getPublicAccountService (): NodeIKernelPublicAccountService;
getThirdPartySigService (): NodeIKernelThirdPartySigService;
getUnifySearchService (): NodeIKernelUnifySearchService;
getVasSystemUpdateService (): NodeIKernelVasSystemUpdateService;
getPersonalAlbumService (): NodeIKernelPersonalAlbumService;
getGProGuildMsgService (): unknown;
getFileBridgeHostService (): unknown;
getWiFiPhotoClientService (): unknown;
} }
export interface EnginInitDesktopConfig { export interface EnginInitDesktopConfig {
@@ -291,6 +390,14 @@ export interface NodeIQQNTWrapperEngine {
get (): NodeIQQNTWrapperEngine; get (): NodeIQQNTWrapperEngine;
initWithDeskTopConfig (config: EnginInitDesktopConfig, nodeIGlobalAdapter: NodeIGlobalAdapter): void; initWithDeskTopConfig (config: EnginInitDesktopConfig, nodeIGlobalAdapter: NodeIGlobalAdapter): void;
initWithMobileConfig (config: unknown, nodeIGlobalAdapter: NodeIGlobalAdapter): void;
initLog (arg: unknown): void;
setLogLevel (arg: unknown): void;
onSendSSOReply (arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): void;
} }
export interface WrapperNodeApi { export interface WrapperNodeApi {

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Xavier Monin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,4 @@
# @primno/dpapi
## 协议与说明
全部遵守原仓库要求

View File

@@ -0,0 +1,65 @@
/**
* napcat-dpapi - Windows DPAPI wrapper
*
* Loads the native @primno+dpapi.node addon from the runtime
* native/dpapi/ directory using process.dlopen, consistent
* with how other native modules (ffmpeg, packet, pty) are loaded.
*/
import { fileURLToPath } from 'node:url';
import path, { dirname } from 'node:path';
export type DataProtectionScope = 'CurrentUser' | 'LocalMachine';
export interface DpapiBindings {
protectData (dataToEncrypt: Uint8Array, optionalEntropy: Uint8Array | null, scope: DataProtectionScope): Uint8Array;
unprotectData (encryptData: Uint8Array, optionalEntropy: Uint8Array | null, scope: DataProtectionScope): Uint8Array;
}
let dpapiBindings: DpapiBindings | null = null;
let loadError: Error | null = null;
function getAddonPath (): string {
// At runtime, import.meta.url resolves to dist/ directory.
// Native files are at dist/native/dpapi/{platform}-{arch}/@primno+dpapi.node
const importDir = dirname(fileURLToPath(import.meta.url));
const platform = process.platform; // 'win32'
const arch = process.arch; // 'x64' or 'arm64'
return path.join(importDir, 'native', 'dpapi', `${platform}-${arch}`, '@primno+dpapi.node');
}
function loadDpapi (): DpapiBindings {
if (dpapiBindings) {
return dpapiBindings;
}
if (loadError) {
throw loadError;
}
try {
const addonPath = getAddonPath();
const nativeModule: { exports: DpapiBindings } = { exports: {} as DpapiBindings };
process.dlopen(nativeModule, addonPath);
dpapiBindings = nativeModule.exports;
return dpapiBindings;
} catch (e) {
loadError = e as Error;
throw new Error(`Failed to load DPAPI native addon: ${(e as Error).message}`);
}
}
export const isPlatformSupported = process.platform === 'win32';
export function protectData (data: Uint8Array, optionalEntropy: Uint8Array | null, scope: DataProtectionScope): Uint8Array {
return loadDpapi().protectData(data, optionalEntropy, scope);
}
export function unprotectData (data: Uint8Array, optionalEntropy: Uint8Array | null, scope: DataProtectionScope): Uint8Array {
return loadDpapi().unprotectData(data, optionalEntropy, scope);
}
export const Dpapi = {
protectData,
unprotectData,
};
export default Dpapi;

View File

@@ -0,0 +1,18 @@
{
"name": "napcat-dpapi",
"version": "0.0.1",
"private": true,
"type": "module",
"main": "index.ts",
"exports": {
".": {
"import": "./index.ts"
}
},
"devDependencies": {
"@types/node": "^22.0.1"
},
"engines": {
"node": ">=18.0.0"
}
}

View File

@@ -0,0 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "."
},
"include": [
"./**/*.ts"
]
}

View File

@@ -2,6 +2,7 @@ import { NapCatPathWrapper } from 'napcat-common/src/path';
import { InitWebUi, WebUiConfig, webUiRuntimePort } from 'napcat-webui-backend/index'; import { InitWebUi, WebUiConfig, webUiRuntimePort } from 'napcat-webui-backend/index';
import { NapCatAdapterManager } from 'napcat-adapter'; import { NapCatAdapterManager } from 'napcat-adapter';
import { NativePacketHandler } from 'napcat-core/packet/handler/client'; import { NativePacketHandler } from 'napcat-core/packet/handler/client';
import { Napi2NativeLoader } from 'napcat-core/packet/handler/napi2nativeLoader';
import { FFmpegService } from 'napcat-core/helper/ffmpeg/ffmpeg'; import { FFmpegService } from 'napcat-core/helper/ffmpeg/ffmpeg';
import { logSubscription, LogWrapper } from 'napcat-core/helper/log'; import { logSubscription, LogWrapper } from 'napcat-core/helper/log';
import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info'; import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info';
@@ -40,6 +41,16 @@ export async function NCoreInitFramework (
const basicInfoWrapper = new QQBasicInfoWrapper({ logger }); const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.QQMainPath, basicInfoWrapper.getFullQQVersion()); const wrapper = loadQQWrapper(basicInfoWrapper.QQMainPath, basicInfoWrapper.getFullQQVersion());
const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用 const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用
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');
}
} else {
logger.log('[NapCat] Napi2NativeLoader: Bypass已通过环境变量禁用');
}
// nativePacketHandler.onAll((packet) => { // nativePacketHandler.onAll((packet) => {
// console.log('[Packet]', packet.uin, packet.cmd, packet.hex_data); // console.log('[Packet]', packet.uin, packet.cmd, packet.hex_data);
// }); // });
@@ -73,11 +84,12 @@ export async function NCoreInitFramework (
// 过早进入会导致addKernelMsgListener等Listener添加失败 // 过早进入会导致addKernelMsgListener等Listener添加失败
// await sleep(2500); // await sleep(2500);
// 初始化 NapCatFramework // 初始化 NapCatFramework
const loaderObject = new NapCatFramework(wrapper, session, logger, selfInfo, basicInfoWrapper, pathWrapper, nativePacketHandler); const loaderObject = new NapCatFramework(wrapper, session, logger, selfInfo, basicInfoWrapper, pathWrapper, nativePacketHandler, napi2nativeLoader);
await loaderObject.core.initCore(); await loaderObject.core.initCore();
// 启动WebUi // 启动WebUi
WebUiDataRuntime.setWorkingEnv(NapCatCoreWorkingEnv.Framework); WebUiDataRuntime.setWorkingEnv(NapCatCoreWorkingEnv.Framework);
WebUiDataRuntime.setQQDataPath(loaderObject.core.dataPath);
InitWebUi(logger, pathWrapper, logSubscription, statusHelperSubscription).then().catch(e => logger.logError(e)); InitWebUi(logger, pathWrapper, logSubscription, statusHelperSubscription).then().catch(e => logger.logError(e));
// 使用 NapCatAdapterManager 统一管理协议适配器 // 使用 NapCatAdapterManager 统一管理协议适配器
const adapterManager = new NapCatAdapterManager(loaderObject.core, loaderObject.context, pathWrapper); const adapterManager = new NapCatAdapterManager(loaderObject.core, loaderObject.context, pathWrapper);
@@ -100,10 +112,12 @@ export class NapCatFramework {
selfInfo: SelfInfo, selfInfo: SelfInfo,
basicInfoWrapper: QQBasicInfoWrapper, basicInfoWrapper: QQBasicInfoWrapper,
pathWrapper: NapCatPathWrapper, pathWrapper: NapCatPathWrapper,
packetHandler: NativePacketHandler packetHandler: NativePacketHandler,
napi2nativeLoader: Napi2NativeLoader
) { ) {
this.context = { this.context = {
packetHandler, packetHandler,
napi2nativeLoader,
workingEnv: NapCatCoreWorkingEnv.Framework, workingEnv: NapCatCoreWorkingEnv.Framework,
wrapper, wrapper,
session, session,

Binary file not shown.

View File

@@ -30,6 +30,7 @@ import { NodeIO3MiscListener } from 'napcat-core/listeners/NodeIO3MiscListener';
import { sleep } from 'napcat-common/src/helper'; import { sleep } from 'napcat-common/src/helper';
import { FFmpegService } from '@/napcat-core/helper/ffmpeg/ffmpeg'; import { FFmpegService } from '@/napcat-core/helper/ffmpeg/ffmpeg';
import { NativePacketHandler } from 'napcat-core/packet/handler/client'; import { NativePacketHandler } from 'napcat-core/packet/handler/client';
import { Napi2NativeLoader } from 'napcat-core/packet/handler/napi2nativeLoader';
import { logSubscription, LogWrapper } from '@/napcat-core/helper/log'; import { logSubscription, LogWrapper } from '@/napcat-core/helper/log';
import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler'; import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler';
import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info'; import { QQBasicInfoWrapper } from '@/napcat-core/helper/qq-basic-info';
@@ -387,20 +388,31 @@ export async function NCoreInitShell () {
handleUncaughtExceptions(logger); handleUncaughtExceptions(logger);
await applyPendingUpdates(pathWrapper, logger); await applyPendingUpdates(pathWrapper, logger);
// 提前初始化 Native 模块(在登录前加载)
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const nativePacketHandler = new NativePacketHandler({ logger });
const napi2nativeLoader = new Napi2NativeLoader({ logger });
await nativePacketHandler.init(basicInfoWrapper.getFullQQVersion());
// 初始化 FFmpeg 服务 // 初始化 FFmpeg 服务
await FFmpegService.init(pathWrapper.binaryPath, logger); await FFmpegService.init(pathWrapper.binaryPath, logger);
if (!(process.env['NAPCAT_DISABLE_PIPE'] === '1' || process.env['NAPCAT_WORKER_PROCESS'] === '1')) { if (!(process.env['NAPCAT_DISABLE_PIPE'] === '1' || process.env['NAPCAT_WORKER_PROCESS'] === '1')) {
await connectToNamedPipe(logger).catch(e => logger.logError('命名管道连接失败', e)); await connectToNamedPipe(logger).catch(e => logger.logError('命名管道连接失败', e));
} }
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
const wrapper = loadQQWrapper(basicInfoWrapper.QQMainPath, basicInfoWrapper.getFullQQVersion()); const wrapper = loadQQWrapper(basicInfoWrapper.QQMainPath, basicInfoWrapper.getFullQQVersion());
const nativePacketHandler = new NativePacketHandler({ logger }); // 初始化 NativePacketHandler 用于后续使用 if (process.env['NAPCAT_ENABLE_VERBOSE_LOG'] === '1') {
napi2nativeLoader.nativeExports.setVerbose?.(true);
// nativePacketHandler.onAll((packet) => { }
// console.log('[Packet]', packet.uin, packet.cmd, packet.hex_data); // wrapper.node 加载后立刻启用 Bypass可通过环境变量禁用
// }); if (process.env['NAPCAT_DISABLE_BYPASS'] !== '1') {
await nativePacketHandler.init(basicInfoWrapper.getFullQQVersion()); const bypassEnabled = napi2nativeLoader.nativeExports.enableAllBypasses?.();
if (bypassEnabled) {
logger.log('[NapCat] Napi2NativeLoader: 已启用Bypass');
}
} else {
logger.log('[NapCat] Napi2NativeLoader: Bypass已通过环境变量禁用');
}
const o3Service = wrapper.NodeIO3MiscService.get(); const o3Service = wrapper.NodeIO3MiscService.get();
o3Service.addO3MiscListener(new NodeIO3MiscListener()); o3Service.addO3MiscListener(new NodeIO3MiscListener());
@@ -425,6 +437,7 @@ export async function NCoreInitShell () {
} }
} }
const [dataPath, dataPathGlobal] = getDataPaths(wrapper); const [dataPath, dataPathGlobal] = getDataPaths(wrapper);
WebUiDataRuntime.setQQDataPath(dataPath);
const systemPlatform = getPlatformType(); const systemPlatform = getPlatformType();
if (!basicInfoWrapper.QQVersionAppid || !basicInfoWrapper.QQVersionQua) throw new Error('QQVersionAppid or QQVersionQua is not defined'); if (!basicInfoWrapper.QQVersionAppid || !basicInfoWrapper.QQVersionQua) throw new Error('QQVersionAppid or QQVersionQua is not defined');
@@ -487,7 +500,8 @@ export async function NCoreInitShell () {
selfInfo, selfInfo,
basicInfoWrapper, basicInfoWrapper,
pathWrapper, pathWrapper,
nativePacketHandler nativePacketHandler,
napi2nativeLoader
).InitNapCat(); ).InitNapCat();
} }
@@ -502,10 +516,12 @@ export class NapCatShell {
selfInfo: SelfInfo, selfInfo: SelfInfo,
basicInfoWrapper: QQBasicInfoWrapper, basicInfoWrapper: QQBasicInfoWrapper,
pathWrapper: NapCatPathWrapper, pathWrapper: NapCatPathWrapper,
packetHandler: NativePacketHandler packetHandler: NativePacketHandler,
napi2nativeLoader: Napi2NativeLoader
) { ) {
this.context = { this.context = {
packetHandler, packetHandler,
napi2nativeLoader,
workingEnv: NapCatCoreWorkingEnv.Shell, workingEnv: NapCatCoreWorkingEnv.Shell,
wrapper, wrapper,
session, session,

View File

@@ -113,6 +113,42 @@ function forceKillProcess (pid: number): void {
} }
} }
/**
* 清理进程树中的残留子进程Electron 模式专用)
* 排除当前主进程和新 worker 进程
*/
async function cleanupOrphanedProcesses (excludePids: number[]): Promise<void> {
if (!isElectron) return;
try {
// 使用 Electron 的 app.getAppMetrics() 获取所有相关进程
// @ts-ignore - electron 运行时存在但类型声明可能缺失
const electron = await import('electron');
if (electron.app && typeof electron.app.getAppMetrics === 'function') {
const metrics = electron.app.getAppMetrics();
const mainPid = process.pid;
for (const metric of metrics) {
const pid = metric.pid;
// 排除主进程、新 worker 进程和明确排除的 PID
if (pid === mainPid || excludePids.includes(pid)) {
continue;
}
// 尝试终止残留进程
try {
process.kill(pid, 'SIGTERM');
logger.log(`[NapCat] [Process] 已清理残留进程: PID ${pid} (${metric.type})`);
} catch {
// 进程可能已经不存在,忽略错误
}
}
}
} catch (error) {
// Electron API 不可用或出错,静默忽略
logger.logDebug?.('[NapCat] [Process] 清理残留进程时出错:', error);
}
}
/** /**
* 重启 Worker 进程 * 重启 Worker 进程
*/ */
@@ -166,6 +202,13 @@ export async function restartWorker (secretKey?: string, port?: number): Promise
// 5. 启动新进程(重启模式不传递快速登录参数,传递密钥和端口) // 5. 启动新进程(重启模式不传递快速登录参数,传递密钥和端口)
await startWorker(false, secretKey, port); await startWorker(false, secretKey, port);
// 6. Electron 模式下清理可能残留的子进程
if (isElectron && currentWorker?.pid) {
const excludePids = [process.pid, currentWorker.pid];
await cleanupOrphanedProcesses(excludePids);
}
isRestarting = false; isRestarting = false;
} }

View File

@@ -45,6 +45,7 @@ const ShellBaseConfig = (source_map: boolean = false) =>
'@/napcat-common': resolve(__dirname, '../napcat-common'), '@/napcat-common': resolve(__dirname, '../napcat-common'),
'@/napcat-onebot': resolve(__dirname, '../napcat-onebot'), '@/napcat-onebot': resolve(__dirname, '../napcat-onebot'),
'@/napcat-pty': resolve(__dirname, '../napcat-pty'), '@/napcat-pty': resolve(__dirname, '../napcat-pty'),
'@/napcat-dpapi': resolve(__dirname, '../napcat-dpapi'),
'@/napcat-webui-backend': resolve(__dirname, '../napcat-webui-backend'), '@/napcat-webui-backend': resolve(__dirname, '../napcat-webui-backend'),
'@/napcat-image-size': resolve(__dirname, '../napcat-image-size'), '@/napcat-image-size': resolve(__dirname, '../napcat-image-size'),
'@/napcat-protocol': resolve(__dirname, '../napcat-protocol'), '@/napcat-protocol': resolve(__dirname, '../napcat-protocol'),

View File

@@ -26,6 +26,7 @@
"json5": "^2.2.3", "json5": "^2.2.3",
"multer": "^2.0.1", "multer": "^2.0.1",
"napcat-common": "workspace:*", "napcat-common": "workspace:*",
"napcat-dpapi": "workspace:*",
"napcat-pty": "workspace:*", "napcat-pty": "workspace:*",
"ws": "^8.18.3" "ws": "^8.18.3"
}, },

View File

@@ -75,6 +75,8 @@ export const GetPluginListHandler: RequestHandler = async (_req, res) => {
status: string; status: string;
hasConfig: boolean; hasConfig: boolean;
hasPages: boolean; hasPages: boolean;
homepage?: string;
repository?: string;
}> = new Array(); }> = new Array();
// 收集所有插件的扩展页面 // 收集所有插件的扩展页面

View File

@@ -27,6 +27,22 @@ const PLUGIN_STORE_SOURCES = [
// 插件目录 - 使用 pathWrapper // 插件目录 - 使用 pathWrapper
const getPluginsDir = () => webUiPathWrapper.pluginPath; const getPluginsDir = () => webUiPathWrapper.pluginPath;
/**
* 验证插件 ID防止路径注入攻击
*/
function validatePluginId (id: any): string {
if (typeof id !== 'string') {
throw new Error('Invalid plugin ID');
}
// 仅允许字母、数字、点、下划线、连字符,禁止路径遍历字符
// 通过 path.basename 进一步确保不包含路径分隔符
const safeId = path.basename(id);
if (!/^[a-zA-Z0-9._-]+$/.test(safeId) || safeId !== id) {
throw new Error('Invalid plugin ID format');
}
return safeId;
}
// 插件列表缓存 // 插件列表缓存
let pluginListCache: PluginStoreList | null = null; let pluginListCache: PluginStoreList | null = null;
let cacheTimestamp: number = 0; let cacheTimestamp: number = 0;
@@ -197,13 +213,15 @@ async function downloadFile (
* 解压插件到指定目录 * 解压插件到指定目录
*/ */
async function extractPlugin (zipPath: string, pluginId: string): Promise<void> { async function extractPlugin (zipPath: string, pluginId: string): Promise<void> {
// 验证 pluginId 确保安全
const safeId = validatePluginId(pluginId);
const PLUGINS_DIR = getPluginsDir(); const PLUGINS_DIR = getPluginsDir();
const pluginDir = path.join(PLUGINS_DIR, pluginId); const pluginDir = path.join(PLUGINS_DIR, safeId);
const dataDir = path.join(pluginDir, 'data'); const dataDir = path.join(pluginDir, 'data');
const tempDataDir = path.join(PLUGINS_DIR, `${pluginId}.data.backup`); const tempDataDir = path.join(PLUGINS_DIR, `${safeId}.data.backup`);
console.log(`[extractPlugin] PLUGINS_DIR: ${PLUGINS_DIR}`); console.log(`[extractPlugin] PLUGINS_DIR: ${PLUGINS_DIR}`);
console.log(`[extractPlugin] pluginId: ${pluginId}`); console.log(`[extractPlugin] pluginId: ${safeId}`);
console.log(`[extractPlugin] Target directory: ${pluginDir}`); console.log(`[extractPlugin] Target directory: ${pluginDir}`);
console.log(`[extractPlugin] Zip file: ${zipPath}`); console.log(`[extractPlugin] Zip file: ${zipPath}`);
@@ -288,7 +306,7 @@ export const GetPluginStoreListHandler: RequestHandler = async (req, res) => {
*/ */
export const GetPluginStoreDetailHandler: RequestHandler = async (req, res) => { export const GetPluginStoreDetailHandler: RequestHandler = async (req, res) => {
try { try {
const { id } = req.params; const id = validatePluginId(req.params['id']);
const data = await fetchPluginList(); const data = await fetchPluginList();
const plugin = data.plugins.find(p => p.id === id); const plugin = data.plugins.find(p => p.id === id);
@@ -307,12 +325,14 @@ export const GetPluginStoreDetailHandler: RequestHandler = async (req, res) => {
*/ */
export const InstallPluginFromStoreHandler: RequestHandler = async (req, res) => { export const InstallPluginFromStoreHandler: RequestHandler = async (req, res) => {
try { try {
const { id, mirror } = req.body; const { id: rawId, mirror } = req.body;
if (!id) { if (!rawId) {
return sendError(res, 'Plugin ID is required'); return sendError(res, 'Plugin ID is required');
} }
const id = validatePluginId(rawId);
// 获取插件信息 // 获取插件信息
const data = await fetchPluginList(); const data = await fetchPluginList();
const plugin = data.plugins.find(p => p.id === id); const plugin = data.plugins.find(p => p.id === id);
@@ -375,13 +395,21 @@ export const InstallPluginFromStoreHandler: RequestHandler = async (req, res) =>
* 安装插件(从商店)- SSE 版本,实时推送进度 * 安装插件(从商店)- SSE 版本,实时推送进度
*/ */
export const InstallPluginFromStoreSSEHandler: RequestHandler = async (req, res) => { export const InstallPluginFromStoreSSEHandler: RequestHandler = async (req, res) => {
const { id, mirror } = req.query; const { id: rawId, mirror } = req.query;
if (!id || typeof id !== 'string') { if (!rawId || typeof rawId !== 'string') {
res.status(400).json({ error: 'Plugin ID is required' }); res.status(400).json({ error: 'Plugin ID is required' });
return; return;
} }
let id: string;
try {
id = validatePluginId(rawId);
} catch (err: any) {
res.status(400).json({ error: err.message });
return;
}
// 设置 SSE 响应头 // 设置 SSE 响应头
res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Cache-Control', 'no-cache');

View File

@@ -4,6 +4,36 @@ import { WebUiDataRuntime } from '@/napcat-webui-backend/src/helper/Data';
import { WebUiConfig } from '@/napcat-webui-backend/index'; import { WebUiConfig } from '@/napcat-webui-backend/index';
import { isEmpty } from '@/napcat-webui-backend/src/utils/check'; import { isEmpty } from '@/napcat-webui-backend/src/utils/check';
import { sendError, sendSuccess } from '@/napcat-webui-backend/src/utils/response'; import { sendError, sendSuccess } from '@/napcat-webui-backend/src/utils/response';
import { Registry20Utils, MachineInfoUtils } from '@/napcat-webui-backend/src/utils/guid';
import os from 'node:os';
// 获取 Registry20 路径的辅助函数
const getRegistryPath = () => {
// 优先从 WebUiDataRuntime 获取早期设置的 dataPath
let dataPath = WebUiDataRuntime.getQQDataPath();
if (!dataPath) {
// 回退: 从 OneBotContext 获取
const oneBotContext = WebUiDataRuntime.getOneBotContext();
dataPath = oneBotContext?.core?.dataPath;
}
if (!dataPath) {
throw new Error('QQ data path not available yet');
}
return Registry20Utils.getRegistryPath(dataPath);
};
// 获取 machine-info 路径的辅助函数 (Linux)
const getMachineInfoPath = () => {
let dataPath = WebUiDataRuntime.getQQDataPath();
if (!dataPath) {
const oneBotContext = WebUiDataRuntime.getOneBotContext();
dataPath = oneBotContext?.core?.dataPath;
}
if (!dataPath) {
throw new Error('QQ data path not available yet');
}
return MachineInfoUtils.getMachineInfoPath(dataPath);
};
// 获取QQ登录二维码 // 获取QQ登录二维码
export const QQGetQRcodeHandler: RequestHandler = async (_, res) => { export const QQGetQRcodeHandler: RequestHandler = async (_, res) => {
@@ -147,3 +177,239 @@ export const QQPasswordLoginHandler: RequestHandler = async (req, res) => {
} }
return sendSuccess(res, null); return sendSuccess(res, null);
}; };
// 重置设备信息
export const QQResetDeviceIDHandler: RequestHandler = async (_, res) => {
try {
const registryPath = getRegistryPath();
// 自动备份
try {
await Registry20Utils.backup(registryPath);
} catch (e) {
// 忽略备份错误(例如文件不存在)
}
await Registry20Utils.delete(registryPath);
return sendSuccess(res, { message: 'Device ID reset successfully (Registry20 deleted)' });
} catch (e) {
return sendError(res, `Failed to reset Device ID: ${(e as Error).message}`);
}
};
// 获取设备 GUID
export const QQGetDeviceGUIDHandler: RequestHandler = async (_, res) => {
try {
const registryPath = getRegistryPath();
const guid = await Registry20Utils.readGuid(registryPath);
return sendSuccess(res, { guid });
} catch (e) {
// 可能是文件不存在,或者非 Windows 平台,或者解密失败
return sendError(res, `Failed to get GUID: ${(e as Error).message}`);
}
};
// 设置设备 GUID
export const QQSetDeviceGUIDHandler: RequestHandler = async (req, res) => {
const { guid } = req.body;
if (!guid || typeof guid !== 'string' || guid.length !== 32) {
return sendError(res, 'Invalid GUID format, must be 32 hex characters');
}
try {
const registryPath = getRegistryPath();
// 自动备份
try {
await Registry20Utils.backup(registryPath);
} catch { }
await Registry20Utils.writeGuid(registryPath, guid);
return sendSuccess(res, { message: 'GUID set successfully' });
} catch (e) {
return sendError(res, `Failed to set GUID: ${(e as Error).message}`);
}
};
// 获取备份列表
export const QQGetGUIDBackupsHandler: RequestHandler = async (_, res) => {
try {
const registryPath = getRegistryPath();
const backups = Registry20Utils.getBackups(registryPath);
return sendSuccess(res, backups);
} catch (e) {
return sendError(res, `Failed to get backups: ${(e as Error).message}`);
}
};
// 恢复备份
export const QQRestoreGUIDBackupHandler: RequestHandler = async (req, res) => {
const { backupName } = req.body;
if (!backupName) {
return sendError(res, 'Backup name is required');
}
try {
const registryPath = getRegistryPath();
await Registry20Utils.restore(registryPath, backupName);
return sendSuccess(res, { message: 'Restored successfully' });
} catch (e) {
return sendError(res, `Failed to restore: ${(e as Error).message}`);
}
};
// 创建备份
export const QQCreateGUIDBackupHandler: RequestHandler = async (_, res) => {
try {
const registryPath = getRegistryPath();
const backupPath = await Registry20Utils.backup(registryPath);
return sendSuccess(res, { message: 'Backup created', path: backupPath });
} catch (e) {
return sendError(res, `Failed to backup: ${(e as Error).message}`);
}
};
// 重启NapCat
export const QQRestartNapCatHandler: RequestHandler = async (_, res) => {
try {
const result = await WebUiDataRuntime.requestRestartProcess();
if (result.result) {
return sendSuccess(res, { message: result.message || 'Restart initiated' });
} else {
return sendError(res, result.message || 'Restart failed');
}
} catch (e) {
return sendError(res, `Restart error: ${(e as Error).message}`);
}
};
// ============================================================
// 平台信息 & Linux GUID 管理
// ============================================================
// 获取平台信息
export const QQGetPlatformInfoHandler: RequestHandler = async (_, res) => {
return sendSuccess(res, { platform: os.platform() });
};
// 获取 Linux MAC 地址 (从 machine-info 文件读取)
export const QQGetLinuxMACHandler: RequestHandler = async (_, res) => {
try {
const machineInfoPath = getMachineInfoPath();
const mac = MachineInfoUtils.readMac(machineInfoPath);
return sendSuccess(res, { mac });
} catch (e) {
return sendError(res, `Failed to get MAC: ${(e as Error).message}`);
}
};
// 设置 Linux MAC 地址 (写入 machine-info 文件)
export const QQSetLinuxMACHandler: RequestHandler = async (req, res) => {
const { mac } = req.body;
if (!mac || typeof mac !== 'string') {
return sendError(res, 'MAC address is required');
}
try {
const machineInfoPath = getMachineInfoPath();
// 自动备份
try {
MachineInfoUtils.backup(machineInfoPath);
} catch { }
MachineInfoUtils.writeMac(machineInfoPath, mac);
return sendSuccess(res, { message: 'MAC set successfully' });
} catch (e) {
return sendError(res, `Failed to set MAC: ${(e as Error).message}`);
}
};
// 获取 Linux machine-id
export const QQGetLinuxMachineIdHandler: RequestHandler = async (_, res) => {
try {
const machineId = MachineInfoUtils.readMachineId();
return sendSuccess(res, { machineId });
} catch (e) {
return sendError(res, `Failed to read machine-id: ${(e as Error).message}`);
}
};
// 计算 Linux GUID (用于前端实时预览)
export const QQComputeLinuxGUIDHandler: RequestHandler = async (req, res) => {
const { mac, machineId } = req.body;
try {
// 如果没传 machineId从 /etc/machine-id 读取
let mid = machineId;
if (!mid || typeof mid !== 'string') {
try {
mid = MachineInfoUtils.readMachineId();
} catch {
mid = '';
}
}
// 如果没传 mac从 machine-info 文件读取
let macStr = mac;
if (!macStr || typeof macStr !== 'string') {
try {
const machineInfoPath = getMachineInfoPath();
macStr = MachineInfoUtils.readMac(machineInfoPath);
} catch {
macStr = '';
}
}
const guid = MachineInfoUtils.computeGuid(mid, macStr);
return sendSuccess(res, { guid, machineId: mid, mac: macStr });
} catch (e) {
return sendError(res, `Failed to compute GUID: ${(e as Error).message}`);
}
};
// 获取 Linux machine-info 备份列表
export const QQGetLinuxMachineInfoBackupsHandler: RequestHandler = async (_, res) => {
try {
const machineInfoPath = getMachineInfoPath();
const backups = MachineInfoUtils.getBackups(machineInfoPath);
return sendSuccess(res, backups);
} catch (e) {
return sendError(res, `Failed to get backups: ${(e as Error).message}`);
}
};
// 创建 Linux machine-info 备份
export const QQCreateLinuxMachineInfoBackupHandler: RequestHandler = async (_, res) => {
try {
const machineInfoPath = getMachineInfoPath();
const backupPath = MachineInfoUtils.backup(machineInfoPath);
return sendSuccess(res, { message: 'Backup created', path: backupPath });
} catch (e) {
return sendError(res, `Failed to backup: ${(e as Error).message}`);
}
};
// 恢复 Linux machine-info 备份
export const QQRestoreLinuxMachineInfoBackupHandler: RequestHandler = async (req, res) => {
const { backupName } = req.body;
if (!backupName) {
return sendError(res, 'Backup name is required');
}
try {
const machineInfoPath = getMachineInfoPath();
MachineInfoUtils.restore(machineInfoPath, backupName);
return sendSuccess(res, { message: 'Restored successfully' });
} catch (e) {
return sendError(res, `Failed to restore: ${(e as Error).message}`);
}
};
// 重置 Linux 设备信息 (删除 machine-info)
export const QQResetLinuxDeviceIDHandler: RequestHandler = async (_, res) => {
try {
const machineInfoPath = getMachineInfoPath();
// 自动备份
try {
MachineInfoUtils.backup(machineInfoPath);
} catch { }
MachineInfoUtils.delete(machineInfoPath);
return sendSuccess(res, { message: 'Device ID reset successfully (machine-info deleted)' });
} catch (e) {
return sendError(res, `Failed to reset Device ID: ${(e as Error).message}`);
}
};

View File

@@ -16,6 +16,7 @@ const LoginRuntime: LoginRuntimeType = {
}, },
QQLoginError: '', QQLoginError: '',
QQVersion: 'unknown', QQVersion: 'unknown',
QQDataPath: '',
OneBotContext: null, OneBotContext: null,
onQQLoginStatusChange: async (status: boolean) => { onQQLoginStatusChange: async (status: boolean) => {
LoginRuntime.QQLoginStatus = status; LoginRuntime.QQLoginStatus = status;
@@ -167,6 +168,14 @@ export const WebUiDataRuntime = {
return LoginRuntime.QQVersion; return LoginRuntime.QQVersion;
}, },
setQQDataPath (dataPath: string) {
LoginRuntime.QQDataPath = dataPath;
},
getQQDataPath (): string {
return LoginRuntime.QQDataPath;
},
setWebUiConfigQuickFunction (func: LoginRuntimeType['WebUiConfigQuickFunction']): void { setWebUiConfigQuickFunction (func: LoginRuntimeType['WebUiConfigQuickFunction']): void {
LoginRuntime.WebUiConfigQuickFunction = func; LoginRuntime.WebUiConfigQuickFunction = func;
}, },

View File

@@ -11,6 +11,22 @@ import {
setAutoLoginAccountHandler, setAutoLoginAccountHandler,
QQRefreshQRcodeHandler, QQRefreshQRcodeHandler,
QQPasswordLoginHandler, QQPasswordLoginHandler,
QQResetDeviceIDHandler,
QQRestartNapCatHandler,
QQGetDeviceGUIDHandler,
QQSetDeviceGUIDHandler,
QQGetGUIDBackupsHandler,
QQRestoreGUIDBackupHandler,
QQCreateGUIDBackupHandler,
QQGetPlatformInfoHandler,
QQGetLinuxMACHandler,
QQSetLinuxMACHandler,
QQGetLinuxMachineIdHandler,
QQComputeLinuxGUIDHandler,
QQGetLinuxMachineInfoBackupsHandler,
QQCreateLinuxMachineInfoBackupHandler,
QQRestoreLinuxMachineInfoBackupHandler,
QQResetLinuxDeviceIDHandler,
} from '@/napcat-webui-backend/src/api/QQLogin'; } from '@/napcat-webui-backend/src/api/QQLogin';
const router: Router = Router(); const router: Router = Router();
@@ -34,5 +50,41 @@ router.post('/SetQuickLoginQQ', setAutoLoginAccountHandler);
router.post('/RefreshQRcode', QQRefreshQRcodeHandler); router.post('/RefreshQRcode', QQRefreshQRcodeHandler);
// router:密码登录 // router:密码登录
router.post('/PasswordLogin', QQPasswordLoginHandler); router.post('/PasswordLogin', QQPasswordLoginHandler);
// router:重置设备信息
router.post('/ResetDeviceID', QQResetDeviceIDHandler);
// router:重启NapCat
router.post('/RestartNapCat', QQRestartNapCatHandler);
// router:获取设备GUID
router.post('/GetDeviceGUID', QQGetDeviceGUIDHandler);
// router:设置设备GUID
router.post('/SetDeviceGUID', QQSetDeviceGUIDHandler);
// router:获取GUID备份列表
router.post('/GetGUIDBackups', QQGetGUIDBackupsHandler);
// router:恢复GUID备份
router.post('/RestoreGUIDBackup', QQRestoreGUIDBackupHandler);
// router:创建GUID备份
router.post('/CreateGUIDBackup', QQCreateGUIDBackupHandler);
// ============================================================
// 平台信息 & Linux GUID 管理
// ============================================================
// router:获取平台信息
router.post('/GetPlatformInfo', QQGetPlatformInfoHandler);
// router:获取Linux MAC地址
router.post('/GetLinuxMAC', QQGetLinuxMACHandler);
// router:设置Linux MAC地址
router.post('/SetLinuxMAC', QQSetLinuxMACHandler);
// router:获取Linux machine-id
router.post('/GetLinuxMachineId', QQGetLinuxMachineIdHandler);
// router:计算Linux GUID
router.post('/ComputeLinuxGUID', QQComputeLinuxGUIDHandler);
// router:获取Linux machine-info备份列表
router.post('/GetLinuxMachineInfoBackups', QQGetLinuxMachineInfoBackupsHandler);
// router:创建Linux machine-info备份
router.post('/CreateLinuxMachineInfoBackup', QQCreateLinuxMachineInfoBackupHandler);
// router:恢复Linux machine-info备份
router.post('/RestoreLinuxMachineInfoBackup', QQRestoreLinuxMachineInfoBackupHandler);
// router:重置Linux设备信息
router.post('/ResetLinuxDeviceID', QQResetLinuxDeviceIDHandler);
export { router as QQLoginRouter }; export { router as QQLoginRouter };

View File

@@ -49,6 +49,7 @@ export interface LoginRuntimeType {
QQLoginInfo: SelfInfo; QQLoginInfo: SelfInfo;
QQLoginError: string; QQLoginError: string;
QQVersion: string; QQVersion: string;
QQDataPath: string;
onQQLoginStatusChange: (status: boolean) => Promise<void>; onQQLoginStatusChange: (status: boolean) => Promise<void>;
onWebUiTokenChange: (token: string) => Promise<void>; onWebUiTokenChange: (token: string) => Promise<void>;
onRefreshQRCode: () => Promise<void>; onRefreshQRCode: () => Promise<void>;

View File

@@ -0,0 +1,275 @@
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';
import crypto from 'node:crypto';
import { protectData, unprotectData } from 'napcat-dpapi';
const GUID_HEADER = Buffer.from([0x00, 0x00, 0x00, 0x14]);
const XOR_KEY = 0x10;
/**
* Unprotects data using Windows DPAPI via napcat-dpapi.
*/
function dpapiUnprotect (filePath: string): Buffer {
const encrypted = fs.readFileSync(filePath);
return Buffer.from(unprotectData(encrypted, null, 'CurrentUser'));
}
/**
* Protects data using Windows DPAPI and writes to file.
*/
function dpapiProtectAndWrite (filePath: string, data: Buffer): void {
const encrypted = protectData(data, null, 'CurrentUser');
fs.writeFileSync(filePath, Buffer.from(encrypted));
}
export class Registry20Utils {
static getRegistryPath (dataPath: string): string {
return path.join(dataPath, 'nt_qq', 'global', 'nt_data', 'msf', 'Registry20');
}
static readGuid (registryPath: string): string {
if (!fs.existsSync(registryPath)) {
throw new Error('Registry20 file not found');
}
if (os.platform() !== 'win32') {
throw new Error('Registry20 decryption is only supported on Windows');
}
const decrypted = dpapiUnprotect(registryPath);
if (decrypted.length < 20) {
throw new Error(`Decrypted data too short (got ${decrypted.length} bytes, need 20)`);
}
// Decode payload: header(4) + obfuscated_guid(16)
const payload = decrypted.subarray(4, 20);
const guidBuf = Buffer.alloc(16);
for (let i = 0; i < 16; i++) {
const payloadByte = payload[i] ?? 0;
guidBuf[i] = (~(payloadByte ^ XOR_KEY)) & 0xFF;
}
return guidBuf.toString('hex');
}
static writeGuid (registryPath: string, guidHex: string): void {
if (guidHex.length !== 32) {
throw new Error('Invalid GUID length, must be 32 hex chars');
}
if (os.platform() !== 'win32') {
throw new Error('Registry20 encryption is only supported on Windows');
}
const guidBytes = Buffer.from(guidHex, 'hex');
const payload = Buffer.alloc(16);
for (let i = 0; i < 16; i++) {
const guidByte = guidBytes[i] ?? 0;
payload[i] = XOR_KEY ^ (~guidByte & 0xFF);
}
const data = Buffer.concat([GUID_HEADER, payload]);
// Create directory if not exists
const dir = path.dirname(registryPath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
dpapiProtectAndWrite(registryPath, data);
}
static getBackups (registryPath: string): string[] {
const dir = path.dirname(registryPath);
const baseName = path.basename(registryPath);
if (!fs.existsSync(dir)) return [];
return fs.readdirSync(dir)
.filter(f => f.startsWith(`${baseName}.bak.`))
.sort()
.reverse();
}
static backup (registryPath: string): string {
if (!fs.existsSync(registryPath)) {
throw new Error('Registry20 does not exist');
}
const timestamp = new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14);
const backupPath = `${registryPath}.bak.${timestamp}`;
fs.copyFileSync(registryPath, backupPath);
return backupPath;
}
static restore (registryPath: string, backupFileName: string): void {
const dir = path.dirname(registryPath);
const backupPath = path.join(dir, backupFileName);
if (!fs.existsSync(backupPath)) {
throw new Error('Backup file not found');
}
fs.copyFileSync(backupPath, registryPath);
}
static delete (registryPath: string): void {
if (fs.existsSync(registryPath)) {
fs.unlinkSync(registryPath);
}
}
}
// ============================================================
// Linux machine-info 工具类
// ============================================================
/**
* ROT13 编解码 (自逆运算)
* 字母偏移13位数字和符号不变
*/
function rot13 (s: string): string {
return s.replace(/[a-zA-Z]/g, (c) => {
const base = c <= 'Z' ? 65 : 97;
return String.fromCharCode(((c.charCodeAt(0) - base + 13) % 26) + base);
});
}
/**
* Linux 平台 machine-info 文件工具类
*
* 文件格式 (逆向自 machine_guid_util.cc):
* [4字节 BE uint32 长度 N] [N字节 ROT13 编码的 MAC 字符串]
* - MAC 格式: xx-xx-xx-xx-xx-xx (17 字符)
* - ROT13: 字母偏移13位, 数字和 '-' 不变
*
* GUID 生成算法:
* GUID = MD5( /etc/machine-id + MAC地址 )
*/
export class MachineInfoUtils {
/**
* 获取 machine-info 文件路径
*/
static getMachineInfoPath (dataPath: string): string {
return path.join(dataPath, 'nt_qq', 'global', 'nt_data', 'msf', 'machine-info');
}
/**
* 从 machine-info 文件读取 MAC 地址
*/
static readMac (machineInfoPath: string): string {
if (!fs.existsSync(machineInfoPath)) {
throw new Error('machine-info file not found');
}
const data = fs.readFileSync(machineInfoPath);
if (data.length < 4) {
throw new Error(`machine-info data too short: ${data.length} < 4 bytes`);
}
const length = data.readUInt32BE(0);
if (length >= 18) {
throw new Error(`MAC string length abnormal: ${length} >= 18`);
}
if (data.length < 4 + length) {
throw new Error(`machine-info data incomplete: need ${4 + length} bytes, got ${data.length}`);
}
const rot13Str = data.subarray(4, 4 + length).toString('ascii');
return rot13(rot13Str);
}
/**
* 将 MAC 地址写入 machine-info 文件
*/
static writeMac (machineInfoPath: string, mac: string): void {
mac = mac.trim().toLowerCase();
// 验证 MAC 格式: xx-xx-xx-xx-xx-xx
if (!/^[0-9a-f]{2}(-[0-9a-f]{2}){5}$/.test(mac)) {
throw new Error('Invalid MAC format, must be xx-xx-xx-xx-xx-xx');
}
const encoded = rot13(mac);
const length = encoded.length;
const buf = Buffer.alloc(4 + length);
buf.writeUInt32BE(length, 0);
buf.write(encoded, 4, 'ascii');
// 确保目录存在
const dir = path.dirname(machineInfoPath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(machineInfoPath, buf);
}
/**
* 读取 /etc/machine-id
*/
static readMachineId (): string {
const machineIdPath = '/etc/machine-id';
if (!fs.existsSync(machineIdPath)) {
throw new Error('/etc/machine-id not found');
}
return fs.readFileSync(machineIdPath, 'utf-8').trim();
}
/**
* 计算 Linux GUID = MD5(machine-id + MAC)
*/
static computeGuid (machineId: string, mac: string): string {
const md5 = crypto.createHash('md5');
md5.update(machineId, 'ascii');
md5.update(mac, 'ascii');
return md5.digest('hex');
}
/**
* 获取备份列表
*/
static getBackups (machineInfoPath: string): string[] {
const dir = path.dirname(machineInfoPath);
const baseName = path.basename(machineInfoPath);
if (!fs.existsSync(dir)) return [];
return fs.readdirSync(dir)
.filter(f => f.startsWith(`${baseName}.bak.`))
.sort()
.reverse();
}
/**
* 创建备份
*/
static backup (machineInfoPath: string): string {
if (!fs.existsSync(machineInfoPath)) {
throw new Error('machine-info file does not exist');
}
const timestamp = new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14);
const backupPath = `${machineInfoPath}.bak.${timestamp}`;
fs.copyFileSync(machineInfoPath, backupPath);
return backupPath;
}
/**
* 恢复备份
*/
static restore (machineInfoPath: string, backupFileName: string): void {
const dir = path.dirname(machineInfoPath);
const backupPath = path.join(dir, backupFileName);
if (!fs.existsSync(backupPath)) {
throw new Error('Backup file not found');
}
fs.copyFileSync(backupPath, machineInfoPath);
}
/**
* 删除 machine-info
*/
static delete (machineInfoPath: string): void {
if (fs.existsSync(machineInfoPath)) {
fs.unlinkSync(machineInfoPath);
}
}
}

View File

@@ -55,6 +55,7 @@ function getAuthorAvatar (homepage?: string, downloadUrl?: string): string | und
export interface PluginStoreCardProps { export interface PluginStoreCardProps {
data: PluginStoreItem; data: PluginStoreItem;
onInstall: () => void; onInstall: () => void;
onViewDetail?: () => void;
installStatus?: InstallStatus; installStatus?: InstallStatus;
installedVersion?: string; installedVersion?: string;
} }
@@ -62,6 +63,7 @@ export interface PluginStoreCardProps {
const PluginStoreCard: React.FC<PluginStoreCardProps> = ({ const PluginStoreCard: React.FC<PluginStoreCardProps> = ({
data, data,
onInstall, onInstall,
onViewDetail,
installStatus = 'not-installed', installStatus = 'not-installed',
installedVersion, installedVersion,
}) => { }) => {
@@ -91,7 +93,10 @@ const PluginStoreCard: React.FC<PluginStoreCardProps> = ({
)} )}
shadow='sm' shadow='sm'
> >
<CardBody className='p-4 flex flex-col gap-3'> <CardBody
className={clsx('p-4 flex flex-col gap-3', onViewDetail && 'cursor-pointer')}
onClick={onViewDetail}
>
{/* Header: Avatar + Name + Author */} {/* Header: Avatar + Name + Author */}
<div className='flex items-start gap-3'> <div className='flex items-start gap-3'>
<Avatar <Avatar
@@ -232,7 +237,10 @@ const PluginStoreCard: React.FC<PluginStoreCardProps> = ({
</div> </div>
</CardBody> </CardBody>
<CardFooter className='px-4 pb-4 pt-0'> <CardFooter
className='px-4 pb-4 pt-0'
onClick={(e) => e.stopPropagation()}
>
{installStatus === 'installed' {installStatus === 'installed'
? ( ? (
<Button <Button

View File

@@ -0,0 +1,714 @@
import { Button } from '@heroui/button';
import { Input } from '@heroui/input';
import { Divider } from '@heroui/divider';
import { Chip } from '@heroui/chip';
import { Listbox, ListboxItem } from '@heroui/listbox';
import { Spinner } from '@heroui/spinner';
import { useEffect, useState, useCallback, useMemo } from 'react';
import toast from 'react-hot-toast';
import { MdContentCopy, MdDelete, MdRefresh, MdSave, MdRestorePage, MdBackup } from 'react-icons/md';
import MD5 from 'crypto-js/md5';
import QQManager from '@/controllers/qq_manager';
import useDialog from '@/hooks/use-dialog';
interface GUIDManagerProps {
/** 是否显示重启按钮 */
showRestart?: boolean;
/** 紧凑模式(用于弹窗场景) */
compact?: boolean;
}
const GUIDManager: React.FC<GUIDManagerProps> = ({ showRestart = true, compact = false }) => {
const dialog = useDialog();
// 平台检测
const [platform, setPlatform] = useState<string>('');
const isWindows = platform === 'win32';
const isMac = platform === 'darwin';
const isLinux = platform !== '' && platform !== 'win32' && platform !== 'darwin';
const platformDetected = platform !== '';
// Windows 状态
const [currentGUID, setCurrentGUID] = useState<string>('');
const [inputGUID, setInputGUID] = useState<string>('');
const [backups, setBackups] = useState<string[]>([]);
// Linux 状态
const [currentMAC, setCurrentMAC] = useState<string>('');
const [inputMAC, setInputMAC] = useState<string>('');
const [machineId, setMachineId] = useState<string>('');
const [linuxBackups, setLinuxBackups] = useState<string[]>([]);
// 通用状态
const [loading, setLoading] = useState(false);
const [saving, setSaving] = useState(false);
const [restarting, setRestarting] = useState(false);
const isValidGUID = (guid: string) => /^[0-9a-fA-F]{32}$/.test(guid);
const isValidMAC = (mac: string) => /^[0-9a-fA-F]{2}(-[0-9a-fA-F]{2}){5}$/.test(mac.trim().toLowerCase());
// 前端实时计算 Linux GUID = MD5(machine-id + MAC)
const computedLinuxGUID = useMemo(() => {
if (!isLinux) return '';
const mac = inputMAC.trim().toLowerCase();
if (!machineId && !mac) return '';
return MD5(machineId + mac).toString();
}, [isLinux, machineId, inputMAC]);
// 当前生效的 GUID (基于已保存的 MAC)
const currentLinuxGUID = useMemo(() => {
if (!isLinux || !currentMAC) return '';
return MD5(machineId + currentMAC).toString();
}, [isLinux, machineId, currentMAC]);
// 检测平台
const fetchPlatform = useCallback(async () => {
try {
const data = await QQManager.getPlatformInfo();
setPlatform(data.platform);
} catch {
// 如果获取失败,默认 win32 向后兼容
setPlatform('win32');
}
}, []);
// Windows: 获取 GUID
const fetchGUID = useCallback(async () => {
setLoading(true);
try {
const data = await QQManager.getDeviceGUID();
setCurrentGUID(data.guid);
setInputGUID(data.guid);
} catch (error) {
const msg = (error as Error).message;
setCurrentGUID('');
setInputGUID('');
if (!msg.includes('not found')) {
toast.error(`获取 GUID 失败: ${msg}`);
}
} finally {
setLoading(false);
}
}, []);
// Windows: 获取备份
const fetchBackups = useCallback(async () => {
try {
const data = await QQManager.getGUIDBackups();
setBackups(data);
} catch {
// ignore
}
}, []);
// Linux: 获取 MAC + machine-id
const fetchLinuxInfo = useCallback(async () => {
setLoading(true);
try {
const [macData, midData] = await Promise.all([
QQManager.getLinuxMAC().catch(() => ({ mac: '' })),
QQManager.getLinuxMachineId().catch(() => ({ machineId: '' })),
]);
setCurrentMAC(macData.mac);
setInputMAC(macData.mac);
setMachineId(midData.machineId);
} catch (error) {
const msg = (error as Error).message;
toast.error(`获取设备信息失败: ${msg}`);
} finally {
setLoading(false);
}
}, []);
// Linux: 获取备份
const fetchLinuxBackups = useCallback(async () => {
try {
const data = await QQManager.getLinuxMachineInfoBackups();
setLinuxBackups(data);
} catch {
// ignore
}
}, []);
useEffect(() => {
fetchPlatform();
}, [fetchPlatform]);
useEffect(() => {
if (!platformDetected) return;
if (isWindows) {
fetchGUID();
fetchBackups();
} else {
fetchLinuxInfo();
fetchLinuxBackups();
}
}, [platformDetected, isWindows, fetchGUID, fetchBackups, fetchLinuxInfo, fetchLinuxBackups]);
// ========== Windows 操作 ==========
const handleCopy = () => {
const guid = isLinux ? currentLinuxGUID : currentGUID;
if (guid) {
navigator.clipboard.writeText(guid);
toast.success('已复制到剪贴板');
}
};
const handleSave = async () => {
if (!isValidGUID(inputGUID)) {
toast.error('GUID 格式无效,需要 32 位十六进制字符');
return;
}
setSaving(true);
try {
await QQManager.setDeviceGUID(inputGUID);
setCurrentGUID(inputGUID);
toast.success('GUID 已设置,重启后生效');
await fetchBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`设置 GUID 失败: ${msg}`);
} finally {
setSaving(false);
}
};
const handleDelete = () => {
dialog.confirm({
title: '确认删除',
content: '删除 Registry20 后QQ 将在下次启动时生成新的设备标识。确定要删除吗?',
confirmText: '删除',
cancelText: '取消',
onConfirm: async () => {
try {
await QQManager.resetDeviceID();
setCurrentGUID('');
setInputGUID('');
toast.success('已删除,重启后生效');
await fetchBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`删除失败: ${msg}`);
}
},
});
};
const handleBackup = async () => {
try {
await QQManager.createGUIDBackup();
toast.success('备份已创建');
await fetchBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`备份失败: ${msg}`);
}
};
const handleRestore = (backupName: string) => {
dialog.confirm({
title: '确认恢复',
content: `确定要从备份 "${backupName}" 恢复吗?当前的 Registry20 将被覆盖。`,
confirmText: '恢复',
cancelText: '取消',
onConfirm: async () => {
try {
await QQManager.restoreGUIDBackup(backupName);
toast.success('已恢复,重启后生效');
await fetchGUID();
await fetchBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`恢复失败: ${msg}`);
}
},
});
};
// ========== Linux 操作 ==========
const handleLinuxSaveMAC = async () => {
const mac = inputMAC.trim().toLowerCase();
if (!isValidMAC(mac)) {
toast.error('MAC 格式无效,需要 xx-xx-xx-xx-xx-xx 格式');
return;
}
setSaving(true);
try {
await QQManager.setLinuxMAC(mac);
setCurrentMAC(mac);
toast.success('MAC 已设置,重启后生效');
await fetchLinuxBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`设置 MAC 失败: ${msg}`);
} finally {
setSaving(false);
}
};
const handleLinuxCopyMAC = () => {
if (currentMAC) {
navigator.clipboard.writeText(currentMAC);
toast.success('MAC 已复制到剪贴板');
}
};
const handleLinuxDelete = () => {
dialog.confirm({
title: '确认删除',
content: '删除 machine-info 后QQ 将在下次启动时生成新的设备标识。确定要删除吗?',
confirmText: '删除',
cancelText: '取消',
onConfirm: async () => {
try {
await QQManager.resetLinuxDeviceID();
setCurrentMAC('');
setInputMAC('');
toast.success('已删除,重启后生效');
await fetchLinuxBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`删除失败: ${msg}`);
}
},
});
};
const handleLinuxBackup = async () => {
try {
await QQManager.createLinuxMachineInfoBackup();
toast.success('备份已创建');
await fetchLinuxBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`备份失败: ${msg}`);
}
};
const handleLinuxRestore = (backupName: string) => {
dialog.confirm({
title: '确认恢复',
content: `确定要从备份 "${backupName}" 恢复吗?当前的 machine-info 将被覆盖。`,
confirmText: '恢复',
cancelText: '取消',
onConfirm: async () => {
try {
await QQManager.restoreLinuxMachineInfoBackup(backupName);
toast.success('已恢复,重启后生效');
await fetchLinuxInfo();
await fetchLinuxBackups();
} catch (error) {
const msg = (error as Error).message;
toast.error(`恢复失败: ${msg}`);
}
},
});
};
// ========== 重启 ==========
const handleRestart = () => {
dialog.confirm({
title: '确认重启',
content: '确定要重启 NapCat 吗?这将导致当前连接断开。',
confirmText: '重启',
cancelText: '取消',
onConfirm: async () => {
setRestarting(true);
try {
await QQManager.restartNapCat();
toast.success('重启指令已发送');
} catch (error) {
const msg = (error as Error).message;
toast.error(`重启失败: ${msg}`);
} finally {
setRestarting(false);
}
},
});
};
if (loading || !platformDetected) {
return (
<div className='flex items-center justify-center py-8'>
<Spinner label='加载中...' />
</div>
);
}
// ========== macOS 不支持 ==========
if (isMac) {
return (
<div className={`flex flex-col gap-${compact ? '3' : '4'}`}>
<div className='flex flex-col items-center justify-center py-8 gap-2'>
<Chip variant='flat' color='warning' className='text-xs'>
macOS GUID
</Chip>
<div className='text-xs text-default-400'>
Windows Linux
</div>
</div>
</div>
);
}
// ========== Linux 渲染 ==========
if (isLinux) {
return (
<div className={`flex flex-col gap-${compact ? '3' : '4'}`}>
{/* 当前设备信息 */}
<div className='flex flex-col gap-2'>
<div className='text-sm font-medium text-default-700'> GUID</div>
<div className='flex items-center gap-2'>
{currentLinuxGUID ? (
<Chip variant='flat' color='primary' className='font-mono text-xs max-w-full'>
{currentLinuxGUID}
</Chip>
) : (
<Chip variant='flat' color='warning' className='text-xs'>
/
</Chip>
)}
{currentLinuxGUID && (
<Button
isIconOnly
size='sm'
variant='light'
onPress={handleCopy}
aria-label='复制GUID'
>
<MdContentCopy size={16} />
</Button>
)}
<Button
isIconOnly
size='sm'
variant='light'
onPress={fetchLinuxInfo}
aria-label='刷新'
>
<MdRefresh size={16} />
</Button>
</div>
<div className='text-xs text-default-400'>
GUID = MD5(machine-id + MAC) MAC GUID
</div>
</div>
<Divider />
{/* machine-id 显示 */}
<div className='flex flex-col gap-1'>
<div className='text-sm font-medium text-default-700'>Machine ID</div>
<Chip variant='flat' color='default' className='font-mono text-xs max-w-full'>
{machineId || '未知'}
</Chip>
<div className='text-xs text-default-400'>
/etc/machine-id
</div>
</div>
<Divider />
{/* 当前 MAC 显示 */}
<div className='flex flex-col gap-2'>
<div className='text-sm font-medium text-default-700'> MAC </div>
<div className='flex items-center gap-2'>
{currentMAC ? (
<Chip variant='flat' color='secondary' className='font-mono text-xs max-w-full'>
{currentMAC}
</Chip>
) : (
<Chip variant='flat' color='warning' className='text-xs'>
/
</Chip>
)}
{currentMAC && (
<Button
isIconOnly
size='sm'
variant='light'
onPress={handleLinuxCopyMAC}
aria-label='复制MAC'
>
<MdContentCopy size={16} />
</Button>
)}
</div>
</div>
<Divider />
{/* 编辑 MAC 地址 */}
<div className='flex flex-col gap-2'>
<div className='text-sm font-medium text-default-700'> MAC </div>
<div className='flex items-center gap-2'>
<Input
size='sm'
variant='bordered'
placeholder='xx-xx-xx-xx-xx-xx'
value={inputMAC}
onValueChange={setInputMAC}
isInvalid={inputMAC.length > 0 && !isValidMAC(inputMAC)}
errorMessage={inputMAC.length > 0 && !isValidMAC(inputMAC) ? '格式: xx-xx-xx-xx-xx-xx' : undefined}
classNames={{
input: 'font-mono text-sm',
}}
maxLength={17}
/>
</div>
{/* 实时 GUID 预览 */}
{inputMAC && isValidMAC(inputMAC) && (
<div className='flex flex-col gap-1 p-2 rounded-lg bg-default-100'>
<div className='text-xs font-medium text-default-500'> GUID</div>
<div className='font-mono text-xs text-primary break-all'>
{computedLinuxGUID}
</div>
{computedLinuxGUID !== currentLinuxGUID && (
<div className='text-xs text-warning-500'>
GUID
</div>
)}
</div>
)}
<div className='flex items-center gap-2'>
<Button
size='sm'
color='primary'
variant='flat'
isLoading={saving}
isDisabled={!isValidMAC(inputMAC) || inputMAC.trim().toLowerCase() === currentMAC}
onPress={handleLinuxSaveMAC}
startContent={<MdSave size={16} />}
>
MAC
</Button>
<Button
size='sm'
color='danger'
variant='flat'
isDisabled={!currentMAC}
onPress={handleLinuxDelete}
startContent={<MdDelete size={16} />}
>
</Button>
<Button
size='sm'
color='secondary'
variant='flat'
isDisabled={!currentMAC}
onPress={handleLinuxBackup}
startContent={<MdBackup size={16} />}
>
</Button>
</div>
<div className='text-xs text-default-400'>
MAC GUID NapCat
</div>
</div>
{/* 备份恢复 */}
{linuxBackups.length > 0 && (
<>
<Divider />
<div className='flex flex-col gap-2'>
<div className='text-sm font-medium text-default-700'>
<span className='text-xs text-default-400 ml-2'></span>
</div>
<div className='max-h-[160px] overflow-y-auto rounded-lg border border-default-200'>
<Listbox
aria-label='备份列表'
selectionMode='none'
onAction={(key) => handleLinuxRestore(key as string)}
>
{linuxBackups.map((name) => (
<ListboxItem
key={name}
startContent={<MdRestorePage size={16} className='text-default-400' />}
className='font-mono text-xs'
>
{name}
</ListboxItem>
))}
</Listbox>
</div>
</div>
</>
)}
{/* 重启 */}
{showRestart && (
<>
<Divider />
<Button
size='sm'
color='warning'
variant='flat'
isLoading={restarting}
onPress={handleRestart}
startContent={<MdRefresh size={16} />}
>
NapCat
</Button>
</>
)}
</div>
);
}
// ========== Windows 渲染 ==========
return (
<div className={`flex flex-col gap-${compact ? '3' : '4'}`}>
{/* 当前 GUID 显示 */}
<div className='flex flex-col gap-2'>
<div className='text-sm font-medium text-default-700'> GUID</div>
<div className='flex items-center gap-2'>
{currentGUID ? (
<Chip variant='flat' color='primary' className='font-mono text-xs max-w-full'>
{currentGUID}
</Chip>
) : (
<Chip variant='flat' color='warning' className='text-xs'>
/
</Chip>
)}
{currentGUID && (
<Button
isIconOnly
size='sm'
variant='light'
onPress={handleCopy}
aria-label='复制GUID'
>
<MdContentCopy size={16} />
</Button>
)}
<Button
isIconOnly
size='sm'
variant='light'
onPress={fetchGUID}
aria-label='刷新'
>
<MdRefresh size={16} />
</Button>
</div>
</div>
<Divider />
{/* 设置 GUID */}
<div className='flex flex-col gap-2'>
<div className='text-sm font-medium text-default-700'> GUID</div>
<div className='flex items-center gap-2'>
<Input
size='sm'
variant='bordered'
placeholder='输入32位十六进制 GUID'
value={inputGUID}
onValueChange={setInputGUID}
isInvalid={inputGUID.length > 0 && !isValidGUID(inputGUID)}
errorMessage={inputGUID.length > 0 && !isValidGUID(inputGUID) ? '需要32位十六进制字符' : undefined}
classNames={{
input: 'font-mono text-sm',
}}
maxLength={32}
/>
</div>
<div className='flex items-center gap-2'>
<Button
size='sm'
color='primary'
variant='flat'
isLoading={saving}
isDisabled={!isValidGUID(inputGUID) || inputGUID === currentGUID}
onPress={handleSave}
startContent={<MdSave size={16} />}
>
GUID
</Button>
<Button
size='sm'
color='danger'
variant='flat'
isDisabled={!currentGUID}
onPress={handleDelete}
startContent={<MdDelete size={16} />}
>
GUID
</Button>
<Button
size='sm'
color='secondary'
variant='flat'
isDisabled={!currentGUID}
onPress={handleBackup}
startContent={<MdBackup size={16} />}
>
</Button>
</div>
<div className='text-xs text-default-400'>
GUID NapCat
</div>
</div>
{/* 备份恢复 */}
{backups.length > 0 && (
<>
<Divider />
<div className='flex flex-col gap-2'>
<div className='text-sm font-medium text-default-700'>
<span className='text-xs text-default-400 ml-2'></span>
</div>
<div className='max-h-[160px] overflow-y-auto rounded-lg border border-default-200'>
<Listbox
aria-label='备份列表'
selectionMode='none'
onAction={(key) => handleRestore(key as string)}
>
{backups.map((name) => (
<ListboxItem
key={name}
startContent={<MdRestorePage size={16} className='text-default-400' />}
className='font-mono text-xs'
>
{name}
</ListboxItem>
))}
</Listbox>
</div>
</div>
</>
)}
{/* 重启 */}
{showRestart && (
<>
<Divider />
<Button
size='sm'
color='warning'
variant='flat'
isLoading={restarting}
onPress={handleRestart}
startContent={<MdRefresh size={16} />}
>
NapCat
</Button>
</>
)}
</div>
);
};
export default GUIDManager;

View File

@@ -1,43 +1,175 @@
import Markdown from 'react-markdown'; import Markdown from 'react-markdown';
import remarkGfm from 'remark-gfm'; import remarkGfm from 'remark-gfm';
const TailwindMarkdown: React.FC<{ content: string }> = ({ content }) => { const TailwindMarkdown: React.FC<{ content: string; }> = ({ content }) => {
return ( return (
<Markdown <Markdown
className='prose prose-sm sm:prose lg:prose-lg xl:prose-xl' className='prose prose-sm sm:prose lg:prose-lg xl:prose-xl max-w-none'
remarkPlugins={[remarkGfm]} remarkPlugins={[remarkGfm]}
components={{ components={{
h1: ({ node: _node, ...props }) => ( h1: ({ node: _node, ...props }) => (
<h1 className='text-2xl font-bold' {...props} /> <h1
className='text-3xl font-bold mt-6 mb-4 pb-2 border-b-2 border-primary/20 text-default-900 first:mt-0'
{...props}
/>
), ),
h2: ({ node: _node, ...props }) => ( h2: ({ node: _node, ...props }) => (
<h2 className='text-xl font-bold' {...props} /> <h2
className='text-2xl font-bold mt-6 mb-3 pb-2 border-b border-default-200 text-default-800'
{...props}
/>
), ),
h3: ({ node: _node, ...props }) => ( h3: ({ node: _node, ...props }) => (
<h3 className='text-lg font-bold' {...props} /> <h3
className='text-xl font-semibold mt-5 mb-2 text-default-800'
{...props}
/>
),
h4: ({ node: _node, ...props }) => (
<h4
className='text-lg font-semibold mt-4 mb-2 text-default-700'
{...props}
/>
),
h5: ({ node: _node, ...props }) => (
<h5
className='text-base font-semibold mt-3 mb-2 text-default-700'
{...props}
/>
),
h6: ({ node: _node, ...props }) => (
<h6
className='text-sm font-semibold mt-3 mb-2 text-default-600'
{...props}
/>
),
p: ({ node: _node, ...props }) => (
<p
className='my-3 leading-7 text-default-700 first:mt-0 last:mb-0'
{...props}
/>
), ),
p: ({ node: _node, ...props }) => <p className='m-0' {...props} />,
a: ({ node: _node, ...props }) => ( a: ({ node: _node, ...props }) => (
<a <a
className='text-primary-500 inline-block hover:underline' className='text-primary font-medium hover:text-primary-600 underline decoration-primary/30 hover:decoration-primary transition-colors'
target='_blank' target='_blank'
rel='noopener noreferrer'
{...props} {...props}
/> />
), ),
ul: ({ node: _node, ...props }) => ( ul: ({ node: _node, ...props }) => (
<ul className='list-disc list-inside' {...props} /> <ul
), className='my-3 ml-6 space-y-2 list-disc marker:text-primary'
ol: ({ node: _node, ...props }) => (
<ol className='list-decimal list-inside' {...props} />
),
blockquote: ({ node: _node, ...props }) => (
<blockquote
className='border-l-4 border-default-300 pl-4 italic'
{...props} {...props}
/> />
), ),
code: ({ node: _node, ...props }) => ( ol: ({ node: _node, ...props }) => (
<code className='bg-default-100 p-1 rounded text-xs' {...props} /> <ol
className='my-3 ml-6 space-y-2 list-decimal marker:text-primary marker:font-semibold'
{...props}
/>
),
li: ({ node: _node, ...props }) => (
<li
className='leading-7 text-default-700 pl-2'
{...props}
/>
),
blockquote: ({ node: _node, ...props }) => (
<blockquote
className='my-4 pl-4 pr-4 py-2 border-l-4 border-primary/50 bg-primary/5 rounded-r-lg italic text-default-600'
{...props}
/>
),
pre: ({ node: _node, ...props }) => (
<pre
className='my-4 p-4 bg-default-100 dark:bg-default-50 rounded-xl overflow-x-auto text-sm border border-default-200 shadow-sm'
{...props}
/>
),
code: ({ node: _node, inline, ...props }: any) => {
if (inline) {
return (
<code
className='px-1.5 py-0.5 mx-0.5 bg-primary/10 text-primary-700 dark:text-primary-600 rounded text-sm font-mono border border-primary/20'
{...props}
/>
);
}
return (
<code
className='text-sm font-mono text-default-800'
{...props}
/>
);
},
img: ({ node: _node, ...props }) => (
<img
className='max-w-full h-auto rounded-lg my-4 shadow-md hover:shadow-xl transition-shadow border border-default-200'
{...props}
/>
),
hr: ({ node: _node, ...props }) => (
<hr
className='my-8 border-0 h-px bg-gradient-to-r from-transparent via-default-300 to-transparent'
{...props}
/>
),
table: ({ node: _node, ...props }) => (
<div className='my-4 overflow-x-auto rounded-lg border border-default-200 shadow-sm'>
<table
className='min-w-full divide-y divide-default-200'
{...props}
/>
</div>
),
thead: ({ node: _node, ...props }) => (
<thead
className='bg-default-100'
{...props}
/>
),
tbody: ({ node: _node, ...props }) => (
<tbody
className='divide-y divide-default-200 bg-white dark:bg-default-50'
{...props}
/>
),
tr: ({ node: _node, ...props }) => (
<tr
className='hover:bg-default-50 transition-colors'
{...props}
/>
),
th: ({ node: _node, ...props }) => (
<th
className='px-4 py-3 text-left text-xs font-semibold text-default-700 uppercase tracking-wider'
{...props}
/>
),
td: ({ node: _node, ...props }) => (
<td
className='px-4 py-3 text-sm text-default-700'
{...props}
/>
),
strong: ({ node: _node, ...props }) => (
<strong
className='font-bold text-default-900'
{...props}
/>
),
em: ({ node: _node, ...props }) => (
<em
className='italic text-default-700'
{...props}
/>
),
del: ({ node: _node, ...props }) => (
<del
className='line-through text-default-500'
{...props}
/>
), ),
}} }}
> >

View File

@@ -101,4 +101,82 @@ export default class QQManager {
passwordMd5, passwordMd5,
}); });
} }
public static async resetDeviceID () {
await serverRequest.post<ServerResponse<null>>('/QQLogin/ResetDeviceID');
}
public static async restartNapCat () {
await serverRequest.post<ServerResponse<null>>('/QQLogin/RestartNapCat');
}
public static async getDeviceGUID () {
const data = await serverRequest.post<ServerResponse<{ guid: string; }>>('/QQLogin/GetDeviceGUID');
return data.data.data;
}
public static async setDeviceGUID (guid: string) {
await serverRequest.post<ServerResponse<null>>('/QQLogin/SetDeviceGUID', { guid });
}
public static async getGUIDBackups () {
const data = await serverRequest.post<ServerResponse<string[]>>('/QQLogin/GetGUIDBackups');
return data.data.data;
}
public static async restoreGUIDBackup (backupName: string) {
await serverRequest.post<ServerResponse<null>>('/QQLogin/RestoreGUIDBackup', { backupName });
}
public static async createGUIDBackup () {
const data = await serverRequest.post<ServerResponse<{ path: string; }>>('/QQLogin/CreateGUIDBackup');
return data.data.data;
}
// ============================================================
// 平台信息 & Linux GUID 管理
// ============================================================
public static async getPlatformInfo () {
const data = await serverRequest.post<ServerResponse<{ platform: string; }>>('/QQLogin/GetPlatformInfo');
return data.data.data;
}
public static async getLinuxMAC () {
const data = await serverRequest.post<ServerResponse<{ mac: string; }>>('/QQLogin/GetLinuxMAC');
return data.data.data;
}
public static async setLinuxMAC (mac: string) {
await serverRequest.post<ServerResponse<null>>('/QQLogin/SetLinuxMAC', { mac });
}
public static async getLinuxMachineId () {
const data = await serverRequest.post<ServerResponse<{ machineId: string; }>>('/QQLogin/GetLinuxMachineId');
return data.data.data;
}
public static async computeLinuxGUID (mac?: string, machineId?: string) {
const data = await serverRequest.post<ServerResponse<{ guid: string; machineId: string; mac: string; }>>('/QQLogin/ComputeLinuxGUID', { mac, machineId });
return data.data.data;
}
public static async getLinuxMachineInfoBackups () {
const data = await serverRequest.post<ServerResponse<string[]>>('/QQLogin/GetLinuxMachineInfoBackups');
return data.data.data;
}
public static async createLinuxMachineInfoBackup () {
const data = await serverRequest.post<ServerResponse<{ path: string; }>>('/QQLogin/CreateLinuxMachineInfoBackup');
return data.data.data;
}
public static async restoreLinuxMachineInfoBackup (backupName: string) {
await serverRequest.post<ServerResponse<null>>('/QQLogin/RestoreLinuxMachineInfoBackup', { backupName });
}
public static async resetLinuxDeviceID () {
await serverRequest.post<ServerResponse<null>>('/QQLogin/ResetLinuxDeviceID');
}
} }

View File

@@ -1,11 +1,13 @@
import { Input } from '@heroui/input'; import { Input } from '@heroui/input';
import { Button } from '@heroui/button'; import { Button } from '@heroui/button';
import { Divider } from '@heroui/divider';
import { useRequest } from 'ahooks'; import { useRequest } from 'ahooks';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form'; import { Controller, useForm } from 'react-hook-form';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import SaveButtons from '@/components/button/save_buttons'; import SaveButtons from '@/components/button/save_buttons';
import GUIDManager from '@/components/guid_manager';
import PageLoading from '@/components/page_loading'; import PageLoading from '@/components/page_loading';
import QQManager from '@/controllers/qq_manager'; import QQManager from '@/controllers/qq_manager';
@@ -131,6 +133,14 @@ const LoginConfigCard = () => {
Worker 3 Worker 3
</div> </div>
</div> </div>
<Divider className='mt-6' />
<div className='flex-shrink-0 w-full mt-4'>
<div className='mb-3 text-sm text-default-600'> GUID </div>
<div className='text-xs text-default-400 mb-3'>
GUID Registry20
</div>
<GUIDManager showRestart={false} />
</div>
</> </>
); );
}; };

Some files were not shown because too many files have changed in this diff Show More